2807 lines
416 KiB
JavaScript
2807 lines
416 KiB
JavaScript
/*
|
||
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||
if you want to view the source, please visit the github repository of this plugin
|
||
*/
|
||
|
||
var __defProp = Object.defineProperty;
|
||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
var __export = (target, all) => {
|
||
for (var name in all)
|
||
__defProp(target, name, { get: all[name], enumerable: true });
|
||
};
|
||
var __copyProps = (to, from, except, desc) => {
|
||
if (from && typeof from === "object" || typeof from === "function") {
|
||
for (let key of __getOwnPropNames(from))
|
||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||
}
|
||
return to;
|
||
};
|
||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||
|
||
// src/main.ts
|
||
var main_exports = {};
|
||
__export(main_exports, {
|
||
default: () => EasyTypingPlugin
|
||
});
|
||
module.exports = __toCommonJS(main_exports);
|
||
var import_obsidian3 = require("obsidian");
|
||
var import_state = require("@codemirror/state");
|
||
|
||
// src/core.ts
|
||
var import_obsidian = require("obsidian");
|
||
|
||
// src/utils.ts
|
||
var DEBUG = true;
|
||
var print = (message, ...optionalParams) => {
|
||
if (DEBUG) {
|
||
console.log(message, ...optionalParams);
|
||
}
|
||
};
|
||
function offsetToPos(doc, offset) {
|
||
let line = doc.lineAt(offset);
|
||
return { line: line.number - 1, ch: offset - line.from };
|
||
}
|
||
function getTypeStrOfTransac(tr) {
|
||
let TransacTypeArray = [
|
||
"EasyTyping.change",
|
||
"EasyTyping.paste",
|
||
"input.type.compose",
|
||
"input.type",
|
||
"input.paste",
|
||
"input.drop",
|
||
"input.complete",
|
||
"input",
|
||
"delete.selection",
|
||
"delete.forward",
|
||
"delete.backward",
|
||
"delete.cut",
|
||
"delete",
|
||
"move.drop",
|
||
"undo",
|
||
"redo",
|
||
"select.pointer"
|
||
];
|
||
for (let i = 0; i < TransacTypeArray.length; i++) {
|
||
if (tr.isUserEvent(TransacTypeArray[i]))
|
||
return TransacTypeArray[i];
|
||
}
|
||
return "none";
|
||
}
|
||
function string2pairstring(s) {
|
||
let cursorIdx = s.indexOf("|");
|
||
let left = s.substring(0, cursorIdx);
|
||
let right = s.substring(cursorIdx + 1);
|
||
return { left, right };
|
||
}
|
||
function ruleStringList2RuleList(list) {
|
||
let res = [];
|
||
for (let i in list) {
|
||
res[i] = { before: string2pairstring(list[i][0]), after: string2pairstring(list[i][1]) };
|
||
}
|
||
return res;
|
||
}
|
||
function stringDeleteAt(str, index) {
|
||
return str.substring(0, index) + str.substring(index + 1);
|
||
}
|
||
function stringInsertAt(str, index, s) {
|
||
return str.substring(0, index) + s + str.substring(index);
|
||
}
|
||
function isParamDefined(param) {
|
||
return typeof param !== "undefined";
|
||
}
|
||
function showString(s) {
|
||
return s.replace(/\n/g, "\\n");
|
||
}
|
||
|
||
// src/core.ts
|
||
var import_language = require("@codemirror/language");
|
||
var LineFormater = class {
|
||
constructor() {
|
||
}
|
||
syntaxTreeNodeNameType(name) {
|
||
if (name.contains("code") && !name.contains("link")) {
|
||
return "code" /* code */;
|
||
} else if (name.contains("math")) {
|
||
return "formula" /* formula */;
|
||
} else {
|
||
return "text" /* text */;
|
||
}
|
||
}
|
||
parseLineWithSyntaxTree(state, lineNum, regRegExp) {
|
||
let linePartsOfTxtCodeFormula = [];
|
||
let line = state.doc.line(lineNum);
|
||
const tree = (0, import_language.syntaxTree)(state);
|
||
let pos = line.from;
|
||
let prevNodeType = "none" /* none */;
|
||
let prevBeginIdx = 0;
|
||
while (pos < line.to) {
|
||
let node = tree.resolve(pos, 1);
|
||
let curNodeType = this.syntaxTreeNodeNameType(node.name);
|
||
if (prevNodeType == "none" /* none */) {
|
||
prevNodeType = curNodeType;
|
||
prevBeginIdx = 0;
|
||
} else if (prevNodeType == curNodeType) {
|
||
} else {
|
||
linePartsOfTxtCodeFormula.push({
|
||
content: line.text.substring(prevBeginIdx, pos - line.from),
|
||
type: prevNodeType,
|
||
begin: prevBeginIdx,
|
||
end: pos - line.from,
|
||
leftSpaceRequire: 0 /* none */,
|
||
rightSpaceRequire: 0 /* none */
|
||
});
|
||
prevNodeType = curNodeType;
|
||
prevBeginIdx = pos - line.from;
|
||
}
|
||
if (curNodeType == "text" /* text */) {
|
||
pos++;
|
||
} else {
|
||
pos = node.to;
|
||
}
|
||
if (pos == line.to) {
|
||
linePartsOfTxtCodeFormula.push({
|
||
content: line.text.substring(prevBeginIdx, pos - line.from),
|
||
type: prevNodeType,
|
||
begin: prevBeginIdx,
|
||
end: pos - line.from,
|
||
leftSpaceRequire: 0 /* none */,
|
||
rightSpaceRequire: 0 /* none */
|
||
});
|
||
}
|
||
}
|
||
let retArray = [];
|
||
for (let i = 0; i < linePartsOfTxtCodeFormula.length; i++) {
|
||
if (linePartsOfTxtCodeFormula[i].type != "text" /* text */) {
|
||
retArray.push(linePartsOfTxtCodeFormula[i]);
|
||
} else {
|
||
let tempArray;
|
||
if (isParamDefined(regRegExp))
|
||
tempArray = splitTextWithLinkAndUserDefined(linePartsOfTxtCodeFormula[i].content, regRegExp);
|
||
else
|
||
tempArray = splitTextWithLinkAndUserDefined(linePartsOfTxtCodeFormula[i].content);
|
||
tempArray.forEach((item) => {
|
||
item.begin += linePartsOfTxtCodeFormula[i].begin;
|
||
item.end += linePartsOfTxtCodeFormula[i].begin;
|
||
retArray.push(item);
|
||
});
|
||
}
|
||
}
|
||
return retArray;
|
||
}
|
||
formatLineOfDoc(state, settings, fromB, toB, insertedStr) {
|
||
let doc = state.doc;
|
||
let line = doc.lineAt(fromB).text;
|
||
let res = null;
|
||
if (insertedStr.contains("\n")) {
|
||
res = this.formatLine(state, doc.lineAt(fromB).number, settings, offsetToPos(doc, fromB).ch, offsetToPos(doc, fromB).ch);
|
||
} else {
|
||
res = this.formatLine(state, doc.lineAt(fromB).number, settings, offsetToPos(doc, toB).ch, offsetToPos(doc, fromB).ch);
|
||
}
|
||
if (res === null || res[2].length == 0)
|
||
return null;
|
||
let newline = stringInsertAt(res[0], res[1], "|");
|
||
let changes = [];
|
||
let offset = doc.lineAt(fromB).from;
|
||
for (let changeItem of res[2]) {
|
||
changes.push({
|
||
changes: { from: offset + changeItem.begin, to: offset + changeItem.end, insert: changeItem.text },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
}
|
||
if (insertedStr.contains("\n")) {
|
||
console.log("insertStr", insertedStr);
|
||
res[1] += insertedStr.length;
|
||
}
|
||
return [changes, { selection: { anchor: offset + res[1] }, userEvent: "EasyTyping.change" }];
|
||
}
|
||
formatLine(state, lineNum, settings, curCh, prevCh) {
|
||
let line = state.doc.line(lineNum).text;
|
||
let regNull = /^\s*$/g;
|
||
if (regNull.test(line))
|
||
return [line, curCh, []];
|
||
let lineParts = settings.UserDefinedRegSwitch ? this.parseLineWithSyntaxTree(state, lineNum, settings.UserDefinedRegExp) : this.parseLineWithSyntaxTree(state, lineNum);
|
||
if (settings.debug)
|
||
console.log("line parts\n", lineParts);
|
||
let linePartsOrigin = JSON.parse(JSON.stringify(lineParts));
|
||
let inlineChangeList = [];
|
||
let cursorLinePartIndex = -1;
|
||
let cursorRelativeIndex = -1;
|
||
let resultCursorCh = 0;
|
||
for (let i = 0; i < lineParts.length; i++) {
|
||
if (curCh > lineParts[i].begin && curCh <= lineParts[i].end) {
|
||
cursorLinePartIndex = i;
|
||
cursorRelativeIndex = curCh - lineParts[i].begin;
|
||
if (lineParts[i].type === "text" /* text */) {
|
||
lineParts[i].content = stringInsertAt(lineParts[i].content, cursorRelativeIndex, "\0");
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
let resultLine = "";
|
||
let offset = 0;
|
||
let prevPartType = "none" /* none */;
|
||
let prevTextEndSpaceState = 0 /* none */;
|
||
for (let i = 0; i < lineParts.length; i++) {
|
||
if (i === 0 && lineParts[i].type === "text" /* text */ && settings.AutoCapital) {
|
||
if (isParamDefined(prevCh) && cursorLinePartIndex != 0) {
|
||
} else {
|
||
let regFirstSentence = /^\s*(\- (\[[x ]\] )?)?“?[a-z\u0401\u0451\u0410-\u044f]/g;
|
||
let regHeaderSentence = /^(#+ |>+ ?|“)[a-z\u0401\u0451\u0410-\u044f]/g;
|
||
let textcopy = lineParts[0].content;
|
||
let match = regFirstSentence.exec(textcopy);
|
||
let matchHeader = regHeaderSentence.exec(textcopy);
|
||
let dstCharIndex = -1;
|
||
if (match) {
|
||
dstCharIndex = regFirstSentence.lastIndex - 1;
|
||
} else if (matchHeader) {
|
||
dstCharIndex = regHeaderSentence.lastIndex - 1;
|
||
}
|
||
if (settings.AutoCapitalMode == "global" /* Globally */ || isParamDefined(prevCh) && dstCharIndex >= prevCh && dstCharIndex < curCh) {
|
||
} else {
|
||
dstCharIndex = -1;
|
||
}
|
||
if (dstCharIndex != -1) {
|
||
lineParts[0].content = textcopy.substring(0, dstCharIndex) + textcopy.charAt(dstCharIndex).toUpperCase() + textcopy.substring(dstCharIndex + 1);
|
||
}
|
||
}
|
||
}
|
||
switch (lineParts[i].type) {
|
||
case "text" /* text */:
|
||
let insertSpace = function(content2, reg2, prevCh2, curCh2, offset2) {
|
||
while (true) {
|
||
let match = reg2.exec(content2);
|
||
if (!match)
|
||
break;
|
||
let tempIndex = reg2.lastIndex - 1;
|
||
if (isParamDefined(prevCh2) && tempIndex >= prevCh2 - offset2 && tempIndex < curCh2 - offset2) {
|
||
content2 = content2.substring(0, tempIndex) + " " + content2.substring(tempIndex);
|
||
curCh2 += 1;
|
||
}
|
||
}
|
||
return [content2, curCh2];
|
||
};
|
||
let content = lineParts[i].content;
|
||
if (settings.AutoCapital) {
|
||
var reg = /[\.\?\!。!?]([\s]*)[a-z\u0401\u0451\u0410-\u044f]/g;
|
||
while (true) {
|
||
let match = reg.exec(content);
|
||
if (!match)
|
||
break;
|
||
let tempIndex = reg.lastIndex - 1;
|
||
let isSpaceDot = tempIndex - 2 < 0 || content.substring(tempIndex - 2, tempIndex) == " .";
|
||
if (settings.AutoCapitalMode == "global" /* Globally */ && !isSpaceDot) {
|
||
lineParts[i].content = content.substring(0, tempIndex) + content.charAt(tempIndex).toUpperCase() + content.substring(reg.lastIndex);
|
||
content = lineParts[i].content;
|
||
} else if (isParamDefined(prevCh) && tempIndex >= prevCh - offset && tempIndex < curCh - offset && !isSpaceDot) {
|
||
lineParts[i].content = content.substring(0, tempIndex) + content.charAt(tempIndex).toUpperCase() + content.substring(reg.lastIndex);
|
||
content = lineParts[i].content;
|
||
}
|
||
}
|
||
}
|
||
if (settings.ChineseEnglishSpace) {
|
||
let reg1 = /([A-Za-z])([\u4e00-\u9fa5])/gi;
|
||
let reg2 = /([\u4e00-\u9fa5])([A-Za-z])/gi;
|
||
[content, curCh] = insertSpace(content, reg1, prevCh, curCh, offset);
|
||
[content, curCh] = insertSpace(content, reg2, prevCh, curCh, offset);
|
||
}
|
||
if (settings.ChineseNumberSpace) {
|
||
let reg2 = /([0-9])([\u4e00-\u9fa5])/g;
|
||
let reg1 = /([\u4e00-\u9fa5])([0-9])/g;
|
||
[content, curCh] = insertSpace(content, reg2, prevCh, curCh, offset);
|
||
[content, curCh] = insertSpace(content, reg1, prevCh, curCh, offset);
|
||
}
|
||
if (settings.EnglishNumberSpace) {
|
||
let reg2 = /([A-Za-z])(\d)/g;
|
||
let reg1 = /(\d)([A-Za-z])/g;
|
||
[content, curCh] = insertSpace(content, reg2, prevCh, curCh, offset);
|
||
[content, curCh] = insertSpace(content, reg1, prevCh, curCh, offset);
|
||
}
|
||
if (settings.ChineseNoSpace) {
|
||
let reg2 = /([\u4e00-\u9fa5,。、!;‘’《》]+)(\s+)([\u4e00-\u9fa5,。、!;‘’《》]+)/g;
|
||
while (reg2.exec(content)) {
|
||
lineParts[i].content = content.replace(reg2, "$1$3");
|
||
content = lineParts[i].content;
|
||
}
|
||
}
|
||
if (settings.PunctuationSpace) {
|
||
{
|
||
let reg2 = /([,\.;\?\!\)])([0-9A-Za-z\u0401\u0451\u0410-\u044f\u4e00-\u9fa5])|([A-Za-z0-9\u4e00-\u9fa5:,\.\?\!'"]+)(\()|[,\.;\?:!][\u4e00-\u9fa5]/gi;
|
||
while (true) {
|
||
let match = reg2.exec(content);
|
||
if (!match)
|
||
break;
|
||
let tempIndex = reg2.lastIndex - 1;
|
||
let isSpaceDot = "!.?;,".contains(content.charAt(tempIndex - 1)) && (tempIndex - 2 < 0 && i == 0 || content.charAt(tempIndex - 2) == " ");
|
||
let isNumPuncNum = /[,.]\d/.test(content.substring(tempIndex - 1, tempIndex + 1)) && (tempIndex - 2 < 0 || /\d/.test(content.charAt(tempIndex - 2)));
|
||
if (settings.PunctuationSpaceMode == "global" /* Globally */ && !isSpaceDot && !isNumPuncNum) {
|
||
content = content.substring(0, tempIndex) + " " + content.substring(tempIndex);
|
||
} else if (isParamDefined(prevCh) && tempIndex >= prevCh - offset && tempIndex < curCh - offset && !isSpaceDot && !isNumPuncNum) {
|
||
content = content.substring(0, tempIndex) + " " + content.substring(tempIndex);
|
||
curCh += 1;
|
||
}
|
||
}
|
||
let reg22 = /(:)([A-Za-z0-9_]+[ ,\.\?\\\/;'",。?;‘“”’、\[\]\-\{\}])/gi;
|
||
lineParts[i].content = content.replace(reg22, "$1 $2");
|
||
content = lineParts[i].content;
|
||
let reg3 = /(:)(["'])/g;
|
||
lineParts[i].content = content.replace(reg3, "$1 $2");
|
||
content = lineParts[i].content;
|
||
}
|
||
}
|
||
let regStrictSpaceStart = /^\0?\s/;
|
||
let regStrictSpaceEnd = /\s\0?$/;
|
||
let regStartWithSpace = /^\0?[\s,\.;\?\!,。;》?::!~\*、()"”\[\]\)\{\}]/;
|
||
let regEndWithSpace = /[\s,。、:;?!()~\*"《“\[\]\(\{\}]\0?$/;
|
||
let txtStartSpaceSate = 0 /* none */;
|
||
let txtEndSpaceState = 0 /* none */;
|
||
if (regStartWithSpace.test(content) || content.startsWith("<br>")) {
|
||
if (regStrictSpaceStart.test(content))
|
||
txtStartSpaceSate = 2 /* strict */;
|
||
else
|
||
txtStartSpaceSate = 1 /* soft */;
|
||
}
|
||
if (regEndWithSpace.test(content) || content.endsWith("<br>")) {
|
||
if (regStrictSpaceEnd.test(content))
|
||
txtEndSpaceState = 2 /* strict */;
|
||
else
|
||
txtEndSpaceState = 1 /* soft */;
|
||
}
|
||
switch (prevPartType) {
|
||
case "none" /* none */:
|
||
break;
|
||
case "code" /* code */:
|
||
if (settings.InlineCodeSpaceMode > txtStartSpaceSate) {
|
||
lineParts[i].content = " " + content;
|
||
content = lineParts[i].content;
|
||
}
|
||
break;
|
||
case "formula" /* formula */:
|
||
if (settings.InlineFormulaSpaceMode > txtStartSpaceSate) {
|
||
lineParts[i].content = " " + content;
|
||
content = lineParts[i].content;
|
||
}
|
||
break;
|
||
case "wikilink" /* wikilink */:
|
||
case "mdlink" /* mdlink */:
|
||
if (!settings.InlineLinkSmartSpace && settings.InlineLinkSpaceMode > txtStartSpaceSate) {
|
||
lineParts[i].content = " " + content;
|
||
content = lineParts[i].content;
|
||
} else if (settings.InlineLinkSmartSpace && txtStartSpaceSate == 0 /* none */) {
|
||
let charAtTextBegin = content.charAt(0);
|
||
let regMdLinkEnd = /\]/;
|
||
let charAtLinkEndIndex = lineParts[i - 1].content.search(regMdLinkEnd) - 1;
|
||
let charAtLinkEnd = lineParts[i - 1].content.charAt(charAtLinkEndIndex);
|
||
if (charAtLinkEnd === "[")
|
||
break;
|
||
let twoNeighborChars = charAtLinkEnd + charAtTextBegin;
|
||
let regNotNeedSpace = /[\u4e00-\u9fa5,。?:;”“’‘-)}][\u4e00-\u9fa5]/g;
|
||
if (!regNotNeedSpace.test(twoNeighborChars)) {
|
||
lineParts[i].content = " " + content;
|
||
content = lineParts[i].content;
|
||
}
|
||
}
|
||
break;
|
||
case "user-defined" /* user */:
|
||
if (lineParts[i - 1].rightSpaceRequire > txtStartSpaceSate) {
|
||
lineParts[i].content = " " + content;
|
||
content = lineParts[i].content;
|
||
}
|
||
break;
|
||
}
|
||
if (i === cursorLinePartIndex) {
|
||
let reg2 = "\0";
|
||
let n = content.search(reg2);
|
||
resultCursorCh = offset + n;
|
||
lineParts[i].content = stringDeleteAt(content, n);
|
||
}
|
||
resultLine += lineParts[i].content;
|
||
offset += lineParts[i].content.length;
|
||
prevPartType = "text" /* text */;
|
||
prevTextEndSpaceState = txtEndSpaceState;
|
||
break;
|
||
case "code" /* code */:
|
||
switch (prevPartType) {
|
||
case "none" /* none */:
|
||
break;
|
||
case "text" /* text */:
|
||
if (settings.InlineCodeSpaceMode > prevTextEndSpaceState) {
|
||
lineParts[i - 1].content += " ";
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "code" /* code */:
|
||
if (settings.InlineCodeSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "formula" /* formula */:
|
||
if (settings.InlineCodeSpaceMode > 0 /* none */ || settings.InlineFormulaSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "mdlink" /* mdlink */:
|
||
case "wikilink" /* wikilink */:
|
||
if (settings.InlineCodeSpaceMode > 0 /* none */ || settings.InlineLinkSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "user-defined" /* user */:
|
||
if (settings.InlineCodeSpaceMode > 0 /* none */ && lineParts[i - 1].rightSpaceRequire > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
}
|
||
if (i === cursorLinePartIndex) {
|
||
resultCursorCh = offset + cursorRelativeIndex;
|
||
}
|
||
resultLine += lineParts[i].content;
|
||
offset += lineParts[i].content.length;
|
||
prevPartType = "code" /* code */;
|
||
prevTextEndSpaceState = 0 /* none */;
|
||
break;
|
||
case "formula" /* formula */:
|
||
if (lineParts[i].content == "$\\qquad$") {
|
||
prevPartType = "text" /* text */;
|
||
prevTextEndSpaceState = 2 /* strict */;
|
||
break;
|
||
}
|
||
switch (prevPartType) {
|
||
case "none" /* none */:
|
||
break;
|
||
case "text" /* text */:
|
||
if (settings.InlineFormulaSpaceMode > prevTextEndSpaceState) {
|
||
lineParts[i - 1].content += " ";
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "code" /* code */:
|
||
if (settings.InlineFormulaSpaceMode > 0 /* none */ || settings.InlineCodeSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "formula" /* formula */:
|
||
if (settings.InlineCodeSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "mdlink" /* mdlink */:
|
||
case "wikilink" /* wikilink */:
|
||
if (settings.InlineFormulaSpaceMode > 0 /* none */ || settings.InlineLinkSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "user-defined" /* user */:
|
||
if (settings.InlineFormulaSpaceMode > 0 /* none */ && lineParts[i - 1].rightSpaceRequire > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
}
|
||
if (i === cursorLinePartIndex) {
|
||
resultCursorCh = offset + cursorRelativeIndex;
|
||
}
|
||
resultLine += lineParts[i].content;
|
||
offset += lineParts[i].content.length;
|
||
prevPartType = "formula" /* formula */;
|
||
prevTextEndSpaceState = 0 /* none */;
|
||
break;
|
||
case "mdlink" /* mdlink */:
|
||
case "wikilink" /* wikilink */:
|
||
switch (prevPartType) {
|
||
case "none" /* none */:
|
||
break;
|
||
case "text" /* text */:
|
||
if (prevTextEndSpaceState > settings.InlineLinkSpaceMode)
|
||
break;
|
||
if (settings.InlineLinkSpaceMode == 2 /* strict */ && prevTextEndSpaceState < 2 /* strict */) {
|
||
lineParts[i - 1].content += " ";
|
||
resultLine += " ";
|
||
offset += 1;
|
||
} else if (settings.InlineLinkSmartSpace && prevTextEndSpaceState == 0 /* none */) {
|
||
let regNoNeedSpace = /[\u4e00-\u9fa5][\u4e00-\u9fa5]/g;
|
||
let charAtTextEnd = lineParts[i - 1].content.charAt(lineParts[i - 1].content.length - 1);
|
||
let charAtLinkBegin = "";
|
||
if (lineParts[i].type == "wikilink" /* wikilink */) {
|
||
let regAlias = /\|/;
|
||
let charOfAliasBegin = lineParts[i].content.search(regAlias);
|
||
let beginIndex = 2;
|
||
if (lineParts[i].content.charAt(0) === "!")
|
||
beginIndex = 3;
|
||
if (charOfAliasBegin != -1) {
|
||
beginIndex = charOfAliasBegin + 1;
|
||
} else if (lineParts[i].content.charAt(beginIndex) == "#") {
|
||
beginIndex += 1;
|
||
}
|
||
charAtLinkBegin = lineParts[i].content.charAt(beginIndex);
|
||
if (charAtLinkBegin == "]")
|
||
break;
|
||
} else {
|
||
let regMdLinkBegin = /\[/;
|
||
let charAtLinkBeginIndex = lineParts[i].content.search(regMdLinkBegin) + 1;
|
||
charAtLinkBegin = lineParts[i].content.charAt(charAtLinkBeginIndex);
|
||
if (charAtLinkBegin === "]")
|
||
break;
|
||
}
|
||
let twoNeighborChars = charAtTextEnd + charAtLinkBegin;
|
||
if (!regNoNeedSpace.test(twoNeighborChars)) {
|
||
lineParts[i - 1].content += " ";
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
} else if (!settings.InlineLinkSmartSpace && settings.InlineLinkSpaceMode > prevTextEndSpaceState) {
|
||
lineParts[i - 1].content += " ";
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "code" /* code */:
|
||
if (settings.InlineLinkSpaceMode > 0 /* none */ || settings.InlineCodeSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "formula" /* formula */:
|
||
if (settings.InlineLinkSpaceMode > 0 /* none */ || settings.InlineFormulaSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "mdlink" /* mdlink */:
|
||
case "wikilink" /* wikilink */:
|
||
if (settings.InlineLinkSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "user-defined" /* user */:
|
||
if (lineParts[i - 1].rightSpaceRequire > 0 /* none */ && settings.InlineLinkSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
}
|
||
if (i === cursorLinePartIndex) {
|
||
resultCursorCh = offset + cursorRelativeIndex;
|
||
}
|
||
resultLine += lineParts[i].content;
|
||
offset += lineParts[i].content.length;
|
||
prevPartType = lineParts[i].type;
|
||
prevTextEndSpaceState = 0 /* none */;
|
||
break;
|
||
case "user-defined" /* user */:
|
||
switch (prevPartType) {
|
||
case "none" /* none */:
|
||
break;
|
||
case "text" /* text */:
|
||
if (lineParts[i].leftSpaceRequire > prevTextEndSpaceState) {
|
||
lineParts[i - 1].content += " ";
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "code" /* code */:
|
||
if (lineParts[i].leftSpaceRequire > 0 /* none */ && settings.InlineCodeSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "formula" /* formula */:
|
||
if (lineParts[i].leftSpaceRequire > 0 /* none */ && settings.InlineFormulaSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "mdlink" /* mdlink */:
|
||
case "wikilink" /* wikilink */:
|
||
if (lineParts[i].leftSpaceRequire > 0 /* none */ && settings.InlineLinkSpaceMode > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
case "user-defined" /* user */:
|
||
if (lineParts[i].leftSpaceRequire > 0 /* none */ && lineParts[i - 1].rightSpaceRequire > 0 /* none */) {
|
||
inlineChangeList.push({
|
||
text: " ",
|
||
begin: lineParts[i].begin,
|
||
end: lineParts[i].begin,
|
||
origin: ""
|
||
});
|
||
resultLine += " ";
|
||
offset += 1;
|
||
}
|
||
break;
|
||
}
|
||
if (i === cursorLinePartIndex) {
|
||
resultCursorCh = offset + cursorRelativeIndex;
|
||
}
|
||
resultLine += lineParts[i].content;
|
||
offset += lineParts[i].content.length;
|
||
prevPartType = "user-defined" /* user */;
|
||
prevTextEndSpaceState = 0 /* none */;
|
||
break;
|
||
}
|
||
}
|
||
for (let i = 0; i < lineParts.length; i++) {
|
||
if (lineParts[i].type === "text" /* text */ && lineParts[i].content != linePartsOrigin[i].content) {
|
||
inlineChangeList.push({
|
||
text: lineParts[i].content,
|
||
begin: linePartsOrigin[i].begin,
|
||
end: linePartsOrigin[i].end,
|
||
origin: linePartsOrigin[i].content
|
||
});
|
||
}
|
||
}
|
||
inlineChangeList = inlineChangeList.sort((a, b) => a.begin - b.begin);
|
||
return [resultLine, resultCursorCh, inlineChangeList];
|
||
}
|
||
};
|
||
function matchWithReg(text, regExp, type, inlineTypeArray, checkArray = false, leftSpaceRe = 0 /* none */, rightSpaceRe = 0 /* none */) {
|
||
let retArray = inlineTypeArray;
|
||
let matchArray = [];
|
||
retArray = retArray.sort((a, b) => a.begin - b.begin);
|
||
while (true) {
|
||
let match = regExp.exec(text);
|
||
if (!match)
|
||
break;
|
||
let valid = true;
|
||
if (checkArray) {
|
||
for (let i = 0; i < retArray.length; i++) {
|
||
if (regExp.lastIndex > retArray[i].begin && retArray[i].end > match.index) {
|
||
valid = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (!valid)
|
||
continue;
|
||
matchArray.push({
|
||
content: match[0],
|
||
type,
|
||
begin: match.index,
|
||
end: regExp.lastIndex,
|
||
leftSpaceRequire: leftSpaceRe,
|
||
rightSpaceRequire: rightSpaceRe
|
||
});
|
||
}
|
||
retArray = retArray.concat(matchArray);
|
||
return retArray;
|
||
}
|
||
function matchWithAbbr(text, type, inlineTypeArray, checkArray = false) {
|
||
let retArray = inlineTypeArray;
|
||
let matchArray = [];
|
||
retArray = retArray.sort((a, b) => a.begin - b.begin);
|
||
let regAbbr = /([a-zA-Z]\.)+/g;
|
||
while (true) {
|
||
let match = regAbbr.exec(text);
|
||
if (!match)
|
||
break;
|
||
let valid = true;
|
||
let isInBlockBegin = match.index == 0;
|
||
if (checkArray) {
|
||
for (let i = 0; i < retArray.length; i++) {
|
||
if (match.index == retArray[i].end) {
|
||
isInBlockBegin = true;
|
||
}
|
||
if (regAbbr.lastIndex > retArray[i].begin && retArray[i].end > match.index) {
|
||
valid = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (!isInBlockBegin && valid) {
|
||
let regChar = /[a-zA-Z0-9]/;
|
||
if (regChar.test(text.charAt(match.index - 1))) {
|
||
valid = false;
|
||
}
|
||
}
|
||
if (!valid)
|
||
continue;
|
||
matchArray.push({
|
||
content: match[0],
|
||
type,
|
||
begin: match.index,
|
||
end: regAbbr.lastIndex,
|
||
leftSpaceRequire: 0 /* none */,
|
||
rightSpaceRequire: 0 /* none */
|
||
});
|
||
}
|
||
retArray = retArray.concat(matchArray);
|
||
return retArray;
|
||
}
|
||
function splitTextWithLinkAndUserDefined(text, regExps) {
|
||
let retArray = [];
|
||
let regWikiLink = /\!{0,2}\[\[[^\[\]]*?\]\]/g;
|
||
let regMdLink = /\!{0,2}\[[^\[\]]*?\]\([^\s\)\(\[\]\{\}']*\)/g;
|
||
retArray = matchWithReg(text, regWikiLink, "wikilink" /* wikilink */, retArray);
|
||
retArray = matchWithReg(text, regMdLink, "mdlink" /* mdlink */, retArray);
|
||
let regExpList = [];
|
||
let leftSRequireList = [];
|
||
let rightSRequireList = [];
|
||
let regNull = /^\s*$/g;
|
||
let regSRequire = /\|[\-=\+][\-=\+]$/;
|
||
if (regExps) {
|
||
let regs = regExps.split("\n");
|
||
for (let i = 0; i < regs.length; i++) {
|
||
if (regNull.test(regs[i]))
|
||
continue;
|
||
if (!regSRequire.test(regs[i]) || regs[i].length <= 3) {
|
||
new import_obsidian.Notice("EasyTyping: \u7B2C" + String(i) + "\u884C\u81EA\u5B9A\u4E49\u6B63\u5219\u4E0D\u7B26\u5408\u89C4\u8303\n" + regs[i]);
|
||
continue;
|
||
}
|
||
let regItem = regs[i].substring(0, regs[i].length - 3);
|
||
let spaceReqString = regs[i].substring(regs[i].length - 3);
|
||
let isValidReg = true;
|
||
try {
|
||
let regTemp = new RegExp(regItem, "g");
|
||
} catch (error) {
|
||
isValidReg = false;
|
||
if (this.settings.debug) {
|
||
new import_obsidian.Notice("EasuTyping: Bad RegExp:\n" + regItem);
|
||
}
|
||
}
|
||
if (isValidReg) {
|
||
regExpList.push(new RegExp(regItem, "g"));
|
||
leftSRequireList.push(str2SpaceState(spaceReqString.charAt(1)));
|
||
rightSRequireList.push(str2SpaceState(spaceReqString.charAt(2)));
|
||
}
|
||
}
|
||
let regLen = regExpList.length;
|
||
for (let i = 0; i < regLen; i++) {
|
||
retArray = matchWithReg(text, regExpList[i], "user-defined" /* user */, retArray, true, leftSRequireList[i], rightSRequireList[i]);
|
||
}
|
||
}
|
||
retArray = matchWithReg(text, /\d{1,2}:\d{1,2}(:\d{0,2}){0,1}/g, "user-defined" /* user */, retArray, true, 0 /* none */, 0 /* none */);
|
||
retArray = matchWithAbbr(text, "user-defined" /* user */, retArray, true);
|
||
retArray = retArray.sort((a, b) => a.begin - b.begin);
|
||
let textArray = [];
|
||
let textBegin = 0;
|
||
let textEnd = 0;
|
||
for (let i = 0; i < retArray.length; i++) {
|
||
if (textBegin < retArray[i].begin) {
|
||
textEnd = retArray[i].begin;
|
||
textArray.push({
|
||
content: text.substring(textBegin, textEnd),
|
||
type: "text" /* text */,
|
||
begin: textBegin,
|
||
end: textEnd,
|
||
leftSpaceRequire: 0 /* none */,
|
||
rightSpaceRequire: 0 /* none */
|
||
});
|
||
}
|
||
textBegin = retArray[i].end;
|
||
}
|
||
if (textBegin != text.length) {
|
||
textArray.push({
|
||
content: text.substring(textBegin, text.length),
|
||
type: "text" /* text */,
|
||
begin: textBegin,
|
||
end: text.length,
|
||
leftSpaceRequire: 0 /* none */,
|
||
rightSpaceRequire: 0 /* none */
|
||
});
|
||
}
|
||
retArray = retArray.concat(textArray);
|
||
retArray = retArray.sort((a, b) => a.begin - b.begin);
|
||
return retArray;
|
||
}
|
||
function str2SpaceState(s) {
|
||
switch (s) {
|
||
case "+":
|
||
return 2 /* strict */;
|
||
case "=":
|
||
return 1 /* soft */;
|
||
case "-":
|
||
default:
|
||
return 0 /* none */;
|
||
}
|
||
}
|
||
function string2SpaceState(s) {
|
||
if (Number(s) == 0 /* none */)
|
||
return 0 /* none */;
|
||
if (Number(s) == 1 /* soft */)
|
||
return 1 /* soft */;
|
||
if (Number(s) == 2 /* strict */)
|
||
return 2 /* strict */;
|
||
return 0 /* none */;
|
||
}
|
||
function getPosLineType(state, pos) {
|
||
const line = state.doc.lineAt(pos);
|
||
let line_number = line.number;
|
||
const tree = (0, import_language.ensureSyntaxTree)(state, line.to);
|
||
const token = tree.resolve(line.from, 1).name;
|
||
if (token.contains("table")) {
|
||
return "table" /* table */;
|
||
}
|
||
if (token.contains("hmd-frontmatter")) {
|
||
return "frontmatter" /* frontmatter */;
|
||
}
|
||
if (token.contains("math")) {
|
||
for (let p = line.from + 1; p < line.to; p += 1) {
|
||
if (!tree.resolve(p, 1).name.contains("math")) {
|
||
return "text" /* text */;
|
||
}
|
||
}
|
||
return "formula" /* formula */;
|
||
} else if (token.contains("code") && token.contains("block")) {
|
||
for (let p = line.from + 1; p < line.to; p += 1) {
|
||
let t = tree.resolve(p, 1).name;
|
||
if (!(t.contains("code") && t.contains("block"))) {
|
||
return "text" /* text */;
|
||
}
|
||
}
|
||
return "codeblock" /* codeblock */;
|
||
} else if (token.contains("quote") && !token.contains("callout")) {
|
||
let callout_start_line = -1;
|
||
for (let l = line_number - 1; l >= 1; l -= 1) {
|
||
let l_line = state.doc.line(l);
|
||
let l_token = tree.resolve(l_line.from, 1).name;
|
||
if (!l_token.contains("quote")) {
|
||
break;
|
||
}
|
||
if (l_token.contains("callout")) {
|
||
callout_start_line = l;
|
||
break;
|
||
}
|
||
}
|
||
if (callout_start_line == -1)
|
||
return "text" /* text */;
|
||
let is_code_block = false;
|
||
let reset = false;
|
||
let reg_code_begin = /^>+ ```/;
|
||
let reg_code_end = /^>+ ```$/;
|
||
for (let l = callout_start_line + 1; l <= line_number; l += 1) {
|
||
let l_line = state.doc.line(l);
|
||
if (reset) {
|
||
is_code_block = false;
|
||
reset = false;
|
||
}
|
||
if (is_code_block && reg_code_end.test(l_line.text)) {
|
||
is_code_block = true;
|
||
reset = true;
|
||
} else if (!is_code_block && reg_code_begin.test(l_line.text)) {
|
||
is_code_block = true;
|
||
}
|
||
}
|
||
if (is_code_block) {
|
||
return "codeblock" /* codeblock */;
|
||
} else
|
||
return "text" /* text */;
|
||
} else if (token.contains("list")) {
|
||
for (let p = line.from + 1; p < line.to; p += 1) {
|
||
let t = tree.resolve(p, 1).name;
|
||
if (t.contains("code") && t.contains("block")) {
|
||
return "codeblock" /* codeblock */;
|
||
}
|
||
}
|
||
}
|
||
return "text" /* text */;
|
||
}
|
||
function getPosLineType2(state, pos) {
|
||
const line = state.doc.lineAt(pos);
|
||
const tree = (0, import_language.syntaxTree)(state);
|
||
const token = tree.resolve(line.from, 1).name;
|
||
if (token.contains("hmd-frontmatter")) {
|
||
return "frontmatter" /* frontmatter */;
|
||
}
|
||
if (token.contains("math")) {
|
||
for (let p = line.from + 1; p < line.to; p += 1) {
|
||
if (!tree.resolve(p, 1).name.contains("math")) {
|
||
return "text" /* text */;
|
||
}
|
||
}
|
||
return "formula" /* formula */;
|
||
} else if (token.contains("code") && token.contains("block")) {
|
||
for (let p = line.from + 1; p < line.to; p += 1) {
|
||
let t = tree.resolve(p, 1).name;
|
||
if (!(t.contains("code") && t.contains("block"))) {
|
||
return "text" /* text */;
|
||
}
|
||
}
|
||
return "codeblock" /* codeblock */;
|
||
}
|
||
for (let p = line.from; p < line.to; p += 1) {
|
||
if (tree.resolve(p, 1).name.contains("list")) {
|
||
return "list" /* list */;
|
||
} else if (tree.resolve(p, 1).name.contains("callout")) {
|
||
return "callout_title" /* callout_title */;
|
||
}
|
||
}
|
||
if (token.contains("quote")) {
|
||
return "quote" /* quote */;
|
||
}
|
||
return "text" /* text */;
|
||
}
|
||
|
||
// src/settings.ts
|
||
var import_obsidian2 = require("obsidian");
|
||
var DEFAULT_SETTINGS = {
|
||
Tabout: true,
|
||
SelectionEnhance: true,
|
||
IntrinsicSymbolPairs: true,
|
||
BaseObEditEnhance: true,
|
||
FW2HWEnhance: true,
|
||
BetterCodeEdit: true,
|
||
AutoFormat: true,
|
||
ExcludeFiles: "",
|
||
ChineseEnglishSpace: true,
|
||
ChineseNumberSpace: true,
|
||
EnglishNumberSpace: true,
|
||
ChineseNoSpace: true,
|
||
PunctuationSpace: true,
|
||
AutoCapital: true,
|
||
AutoCapitalMode: "typing" /* OnlyWhenTyping */,
|
||
PunctuationSpaceMode: "typing" /* OnlyWhenTyping */,
|
||
InlineCodeSpaceMode: 1 /* soft */,
|
||
InlineFormulaSpaceMode: 1 /* soft */,
|
||
InlineLinkSpaceMode: 1 /* soft */,
|
||
InlineLinkSmartSpace: true,
|
||
UserDefinedRegSwitch: true,
|
||
UserDefinedRegExp: "{{.*?}}|++\n<.*?>|--\n\\[\\!.*?\\][-+]{0,1}|-+\n(file:///|https?://|ftp://|obsidian://|zotero://|www.)[^\\s\uFF08\uFF09\u300A\u300B\u3002,\uFF0C\uFF01\uFF1F;\uFF1B\uFF1A\u201C\u201D\u2018\u2019\\)\\(\\[\\]\\{\\}']+|--\n\n[a-zA-Z0-9_\\-.]+@[a-zA-Z0-9_\\-.]+|++\n(?<!#)#[\\u4e00-\\u9fa5\\w-\\/]+|++",
|
||
debug: false,
|
||
userSelRepRuleTrigger: ["-", "#"],
|
||
userSelRepRuleValue: [{ left: "~~", right: "~~" }, { left: "#", right: " " }],
|
||
userDeleteRulesStrList: [["demo|", "|"]],
|
||
userConvertRulesStrList: [[":)|", "\u{1F600}|"]],
|
||
userSelRuleSettingsOpen: true,
|
||
userDelRuleSettingsOpen: true,
|
||
userCvtRuleSettingsOpen: true,
|
||
EnterTwice: false,
|
||
TryFixChineseIM: true,
|
||
PuncRectify: false,
|
||
FixMacOSContextMenu: false,
|
||
TryFixMSIME: false
|
||
};
|
||
var EasyTypingSettingTab = class extends import_obsidian2.PluginSettingTab {
|
||
constructor(app, plugin) {
|
||
super(app, plugin);
|
||
this.plugin = plugin;
|
||
}
|
||
display() {
|
||
const { containerEl } = this;
|
||
containerEl.empty();
|
||
containerEl.createEl("h1", { text: "Obsidian EasyTyping Plugin" });
|
||
containerEl.createEl("p", { text: "More detail is in Github: " }).createEl("a", {
|
||
text: "easy-typing-obsidian",
|
||
href: "https://github.com/Yaozhuwa/easy-typing-obsidian"
|
||
});
|
||
containerEl.createEl("h2", { text: "\u589E\u5F3A\u7F16\u8F91\u8BBE\u7F6E (Enhanced Editing Setting)" });
|
||
new import_obsidian2.Setting(containerEl).setName("Symbol auto pair and delete with pair").setDesc("\u589E\u52A0\u591A\u79CD\u7B26\u53F7\u914D\u5BF9\u8F93\u5165\uFF0C\u914D\u5BF9\u5220\u9664\uFF0C\u5982\u300A\u300B, \u201C\u201D, \u300C\u300D, \u300E\u300F,\u3010\u3011\u7B49").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.IntrinsicSymbolPairs).onChange(async (value) => {
|
||
this.plugin.settings.IntrinsicSymbolPairs = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Selection Replace Enhancement").setDesc("\u9009\u4E2D\u6587\u672C\u60C5\u51B5\u4E0B\u7684\u7F16\u8F91\u589E\u5F3A\uFF0C\u6309\uFFE5\u2192$\u9009\u4E2D\u7684\u6587\u672C$, \u6309\xB7\u2192`\u9009\u4E2D\u7684\u6587\u672C`\uFF0C\u300A \u2192 \u300A\u9009\u4E2D\u7684\u6587\u672C\u300B\u7B49\u7B49").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.SelectionEnhance).onChange(async (value) => {
|
||
this.plugin.settings.SelectionEnhance = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Convert successive full width symbol to half width symbol").setDesc("\u8FDE\u7EED\u8F93\u5165\u5168\u89D2\u7B26\u53F7\u8F6C\u534A\u89D2\uFF0C\u3002\u3002\u2192 .\uFF0C\uFF01\uFF01\u2192 !\uFF0C \u300B\u300B\u2192 >").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.FW2HWEnhance).onChange(async (value) => {
|
||
this.plugin.settings.FW2HWEnhance = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Basic symbol input enhance for obsidian").setDesc("Obsidian \u7684\u57FA\u7840\u8F93\u5165\u589E\u5F3A\uFF0C\u5982\u3010\u3010| \u2192 [[|]]\uFF0C\u53E5\u9996\u7684\u3001\u2192 /\uFF0C\u53E5\u9996\u7684\u300B\u2192 >\uFF0C\xB7\xB7| \u2192 `|`\uFF0C `\xB7|` \u53D8\u6210\u4EE3 \u7801\u5757\uFF0C\uFFE5\uFFE5| \u2192 $|$").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.BaseObEditEnhance).onChange(async (value) => {
|
||
this.plugin.settings.BaseObEditEnhance = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Enhance codeblock edit").setDesc("Improve editing in codeblock(Tab, delete, paste, cmd/ctrl+A select). \u589E\u5F3A\u4EE3\u7801\u5757\u5185\u7684\u7F16\u8F91\uFF08Cmd/Ctrl+A \u9009\u4E2D\u3001Tab\u3001\u5220\u9664\u3001\u7C98\u8D34\uFF09").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.BetterCodeEdit).onChange(async (value) => {
|
||
this.plugin.settings.BetterCodeEdit = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Tabout").setDesc("Tabout inline code or paired symbols(when selected). Tab \u8DF3\u51FA\u884C\u5185\u4EE3\u7801\u5757\u6216\u914D\u5BF9\u7B26\u53F7\u5757(\u9009\u4E2D\u65F6)").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.Tabout).onChange(async (value) => {
|
||
this.plugin.settings.Tabout = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
containerEl.createEl("h2", { text: "\u81EA\u5B9A\u4E49\u7F16\u8F91\u8F6C\u6362\u89C4\u5219 (Customize Edit Convertion Rule)" });
|
||
this.buildUserSelRepRuleSetting(this.containerEl.createEl("details", {
|
||
cls: "easytyping-nested-settings",
|
||
attr: {
|
||
...this.plugin.settings.userSelRuleSettingsOpen ? { open: true } : {}
|
||
}
|
||
}));
|
||
this.buildUserDeleteRuleSetting(this.containerEl.createEl("details", {
|
||
cls: "easytyping-nested-settings",
|
||
attr: {
|
||
...this.plugin.settings.userDelRuleSettingsOpen ? { open: true } : {}
|
||
}
|
||
}));
|
||
this.buildUserConvertRuleSetting(this.containerEl.createEl("details", {
|
||
cls: "easytyping-nested-settings",
|
||
attr: {
|
||
...this.plugin.settings.userCvtRuleSettingsOpen ? { open: true } : {}
|
||
}
|
||
}));
|
||
containerEl.createEl("h2", { text: "\u81EA\u52A8\u683C\u5F0F\u5316\u8BBE\u7F6E (Autoformat Setting)" });
|
||
new import_obsidian2.Setting(containerEl).setName("Auto formatting when typing").setDesc("\u662F\u5426\u5728\u7F16\u8F91\u6587\u6863\u65F6\u81EA\u52A8\u683C\u5F0F\u5316\u6587\u672C\uFF0C\u81EA\u52A8\u683C\u5F0F\u5316\u7684\u603B\u5F00\u5173").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.AutoFormat).onChange(async (value) => {
|
||
this.plugin.settings.AutoFormat = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
containerEl.createEl("p", { text: "Detailed Setting Below" });
|
||
new import_obsidian2.Setting(containerEl).setName("Space between Chinese and English").setDesc("\u5728\u4E2D\u6587\u548C\u82F1\u6587\u95F4\u7A7A\u683C").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.ChineseEnglishSpace).onChange(async (value) => {
|
||
this.plugin.settings.ChineseEnglishSpace = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Space between Chinese and Number").setDesc("\u5728\u4E2D\u6587\u548C\u6570\u5B57\u95F4\u7A7A\u683C").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.ChineseNumberSpace).onChange(async (value) => {
|
||
this.plugin.settings.ChineseNumberSpace = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Space between Engilsh and Number").setDesc("\u5728\u82F1\u6587\u548C\u6570\u5B57\u95F4\u7A7A\u683C").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.EnglishNumberSpace).onChange(async (value) => {
|
||
this.plugin.settings.EnglishNumberSpace = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Delete the Space between Chinese characters").setDesc("\u5728\u4E2D\u6587\u5B57\u7B26\u95F4\u53BB\u9664\u7A7A\u683C").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.ChineseNoSpace).onChange(async (value) => {
|
||
this.plugin.settings.ChineseNoSpace = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Capitalize the first letter of every sentence").setDesc("\u82F1\u6587\u6BCF\u4E2A\u53E5\u9996\u5B57\u6BCD\u5927\u5199").addDropdown((dropdown) => {
|
||
dropdown.addOption("typing" /* OnlyWhenTyping */, "\u8F93\u5165\u65F6\u751F\u6548(Only When Typing)");
|
||
dropdown.addOption("global" /* Globally */, "\u5168\u5C40\u751F\u6548(Work Globally)");
|
||
dropdown.setValue(this.plugin.settings.AutoCapitalMode);
|
||
dropdown.onChange(async (v) => {
|
||
this.plugin.settings.AutoCapitalMode = v;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
}).addToggle((toggle) => {
|
||
toggle.setTooltip("\u529F\u80FD\u5F00\u5173(Switch)");
|
||
toggle.setValue(this.plugin.settings.AutoCapital).onChange(async (value) => {
|
||
this.plugin.settings.AutoCapital = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Smartly insert space between text and punctuation").setDesc("\u5728\u6587\u672C\u548C\u6807\u70B9\u95F4\u6DFB\u52A0\u7A7A\u683C").addDropdown((dropdown) => {
|
||
dropdown.addOption("typing" /* OnlyWhenTyping */, "\u8F93\u5165\u65F6\u751F\u6548(Only When Typing)");
|
||
dropdown.addOption("global" /* Globally */, "\u5168\u5C40\u751F\u6548(Work Globally)");
|
||
dropdown.setValue(this.plugin.settings.PunctuationSpaceMode);
|
||
dropdown.onChange(async (v) => {
|
||
this.plugin.settings.PunctuationSpaceMode = v;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
}).addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.PunctuationSpace).onChange(async (value) => {
|
||
this.plugin.settings.PunctuationSpace = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Space stategy between inline code and text").setDesc("\u5728 `\u884C\u5185\u4EE3\u7801` \u548C\u6587\u672C\u95F4\u7684\u7A7A\u683C\u7B56\u7565\u3002\u65E0\u8981\u6C42\uFF1A\u5BF9\u672C\u7C7B\u522B\u5757\u4E0E\u5DE6\u53F3\u6587\u672C\u6CA1\u6709\u7A7A\u683C\u7684\u8981\u6C42\uFF0C\u8F6F\u7A7A\u683C\uFF1A\u5BF9\u672C\u7C7B\u522B\u5757\u4E0E\u5468\u56F4\u533A\u5757\u53EA\u8981\u6C42\u6709\u8F6F\u7A7A\u683C\uFF0C\u8F6F\u7A7A\u683C\u5982\u5F53\u524D\u5757\u5DE6\u8FB9\u7684\u4E34\u8FD1\u6587\u672C\u4E3A\u3002\uFF0C\uFF1B\uFF1F\u7B49\u5168\u89D2\u6807\u70B9\uFF0C\u5F53\u524D\u5757\u53F3\u8FB9\u7684\u4E34\u8FD1\u6587\u672C\u4E3A\u6240\u6709\u5168\u534A\u89D2\u6807\u70B9\uFF0C\u4E25\u683C\u7A7A\u683C\uFF1A\u5F53\u524D\u5757\u4E0E\u4E34\u8FD1\u6587\u672C\u4E4B\u95F4\u4E25\u683C\u6DFB\u52A0\u7A7A\u683C\u3002").addDropdown((dropdown) => {
|
||
dropdown.addOption(String(0 /* none */), "\u65E0\u8981\u6C42(No Require)");
|
||
dropdown.addOption(String(1 /* soft */), "\u8F6F\u7A7A\u683C(Soft Space)");
|
||
dropdown.addOption(String(2 /* strict */), "\u4E25\u683C\u7A7A\u683C(Strict Space)");
|
||
dropdown.setValue(String(this.plugin.settings.InlineCodeSpaceMode));
|
||
dropdown.onChange(async (v) => {
|
||
this.plugin.settings.InlineCodeSpaceMode = string2SpaceState(v);
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Space stategy between inline formula and text").setDesc("\u5728 $\u884C\u5185\u516C\u5F0F$ \u548C\u6587\u672C\u95F4\u7684\u7A7A\u683C\u7B56\u7565").addDropdown((dropdown) => {
|
||
dropdown.addOption(String(0 /* none */), "\u65E0\u8981\u6C42(No Require)");
|
||
dropdown.addOption(String(1 /* soft */), "\u8F6F\u7A7A\u683C(Soft Space)");
|
||
dropdown.addOption(String(2 /* strict */), "\u4E25\u683C\u7A7A\u683C(Strict Space)");
|
||
dropdown.setValue(String(this.plugin.settings.InlineFormulaSpaceMode));
|
||
dropdown.onChange(async (v) => {
|
||
this.plugin.settings.InlineFormulaSpaceMode = string2SpaceState(v);
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Space strategy between link and text").setDesc("\u5728 [[wikilink]] [mdlink](...) \u548C\u6587\u672C\u95F4\u7A7A\u683C\u7B56\u7565\u3002\u667A\u80FD\u7A7A\u683C\u6A21\u5F0F\u4E0B\u5219\u4F1A\u8003\u8651\u8BE5\u94FE\u63A5\u5757\u7684\u663E\u793A\u5185\u5BB9\uFF08\u5982wiki\u94FE\u63A5\u7684\u522B\u540D\uFF09\u6765\u4E0E\u4E34\u8FD1\u6587\u672C\u8FDB\u884C\u7A7A\u683C\u3002").addDropdown((dropdown) => {
|
||
dropdown.addOption("dummy", "\u5446\u7A7A\u683C(dummy)");
|
||
dropdown.addOption("smart", "\u667A\u80FD\u7A7A\u683C(Smart)");
|
||
dropdown.setValue(this.plugin.settings.InlineLinkSmartSpace ? "smart" : "dummy");
|
||
dropdown.onChange(async (v) => {
|
||
this.plugin.settings.InlineLinkSmartSpace = v == "smart" ? true : false;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
}).addDropdown((dropdown) => {
|
||
dropdown.addOption(String(0 /* none */), "\u65E0\u8981\u6C42(No Require)");
|
||
dropdown.addOption(String(1 /* soft */), "\u8F6F\u7A7A\u683C(Soft Space)");
|
||
dropdown.addOption(String(2 /* strict */), "\u4E25\u683C\u7A7A\u683C(Strict Space)");
|
||
dropdown.setValue(String(this.plugin.settings.InlineLinkSpaceMode));
|
||
dropdown.onChange(async (v) => {
|
||
this.plugin.settings.InlineLinkSpaceMode = string2SpaceState(v);
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
containerEl.createEl("h2", { text: "\u81EA\u5B9A\u4E49\u6B63\u5219\u533A\u5757 (Custom regular expressions block)" });
|
||
new import_obsidian2.Setting(containerEl).setName("User Defined RegExp Switch").setDesc("\u81EA\u5B9A\u4E49\u6B63\u5219\u8868\u8FBE\u5F0F\u5F00\u5173\uFF0C\u5339\u914D\u5230\u7684\u5185\u5BB9\u4E0D\u8FDB\u884C\u683C\u5F0F\u5316\uFF0C\u4E14\u53EF\u4EE5\u8BBE\u7F6E\u5339\u914D\u5230\u7684\u5185\u5BB9\u5757\u4E0E\u5176\u4ED6\u5185\u5BB9\u4E4B\u95F4\u7684\u7A7A\u683C\u7B56\u7565").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.UserDefinedRegSwitch).onChange(async (value) => {
|
||
this.plugin.settings.UserDefinedRegSwitch = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
containerEl.createEl("p", { text: "\u6B63\u5219\u8868\u8FBE\u5F0F\u76F8\u5173\u77E5\u8BC6\uFF0C\u89C1 " }).createEl("a", {
|
||
text: "\u300A\u962E\u4E00\u5CF0\uFF1A\u6B63\u5219\u8868\u8FBE\u5F0F\u7B80\u660E\u6559\u7A0B\u300B",
|
||
href: "https://javascript.ruanyifeng.com/stdlib/regexp.html#"
|
||
});
|
||
containerEl.createEl("p", { text: "\u6B63\u5219\u8868\u8FBE\u5F0F\u89C4\u5219\u4F7F\u7528\u8BF4\u660E\u4E0E\u793A\u4F8B\uFF1A" }).createEl("a", {
|
||
text: "\u81EA\u5B9A\u4E49\u6B63\u5219\u8868\u8FBE\u5F0F\u89C4\u5219",
|
||
href: "https://github.com/Yaozhuwa/easy-typing-obsidian/blob/master/UserDefinedRegExp.md"
|
||
});
|
||
const regContentAreaSetting = new import_obsidian2.Setting(containerEl);
|
||
regContentAreaSetting.settingEl.setAttribute("style", "display: grid; grid-template-columns: 1fr;");
|
||
regContentAreaSetting.setName("User-defined Regular Expression, one expression per line").setDesc("\u7528\u6237\u81EA\u5B9A\u4E49\u6B63\u5219\u8868\u8FBE\u5F0F\uFF0C\u5339\u914D\u5230\u7684\u5185\u5BB9\u4E0D\u8FDB\u884C\u683C\u5F0F\u5316\uFF0C\u6BCF\u884C\u4E00\u4E2A\u8868\u8FBE\u5F0F\uFF0C\u884C\u5C3E\u4E0D\u8981\u968F\u610F\u52A0\u7A7A\u683C\u3002\u6BCF\u884C\u672B\u5C3E3\u4E2A\u5B57\u7B26\u7684\u56FA\u5B9A\u4E3A|\u548C\u4E24\u4E2A\u7A7A\u683C\u7B56\u7565\u7B26\u53F7\uFF0C\u7A7A\u683C\u7B56\u7565\u7B26\u53F7\u4E3A-=+\uFF0C\u5206\u522B\u4EE3\u8868\u4E0D\u8981\u6C42\u7A7A\u683C(-)\uFF0C\u8F6F\u7A7A\u683C(=)\uFF0C\u4E25\u683C\u7A7A\u683C(+)\u3002\u8FD9\u4E24\u4E2A\u7A7A\u683C\u7B56\u7565\u7B26\u53F7\u5206\u522B\u4E3A\u5339\u914D\u533A\u5757\u7684\u5DE6\u53F3\u4E24\u8FB9\u7684\u7A7A\u683C\u7B56\u7565");
|
||
const regContentArea = new import_obsidian2.TextAreaComponent(regContentAreaSetting.controlEl);
|
||
setAttributes(regContentArea.inputEl, {
|
||
style: "margin-top: 12px; width: 100%; height: 30vh;"
|
||
});
|
||
regContentArea.setValue(this.plugin.settings.UserDefinedRegExp).onChange(async (value) => {
|
||
this.plugin.settings.UserDefinedRegExp = value;
|
||
this.plugin.saveSettings();
|
||
});
|
||
containerEl.createEl("h2", { text: "\u6307\u5B9A\u6587\u4EF6\u4E0D\u81EA\u52A8\u683C\u5F0F\u5316 (Exclude Folders/Files)" });
|
||
new import_obsidian2.Setting(containerEl).setName("Exclude Folders/Files").setDesc("This plugin will parse each line as a exlude folder or file. For example: DailyNote/, DailyNote/WeekNotes/, DailyNote/test.md").addTextArea((text) => text.setValue(this.plugin.settings.ExcludeFiles).onChange(async (value) => {
|
||
this.plugin.settings.ExcludeFiles = value;
|
||
this.plugin.saveSettings();
|
||
}));
|
||
containerEl.createEl("h2", { text: "Experimental Features" });
|
||
new import_obsidian2.Setting(containerEl).setName("Fix MacOS context-menu cursor position(Need to restart Obsidian)").setDesc("\u4FEE\u590D MacOS \u9F20\u6807\u53F3\u952E\u547C\u51FA\u83DC\u5355\u65F6\u5149\u6807\u8DF3\u5230\u4E0B\u4E00\u884C\u7684\u95EE\u9898(\u9700\u8981\u91CD\u542FObsidian\u751F\u6548)").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.FixMacOSContextMenu).onChange(async (value) => {
|
||
this.plugin.settings.FixMacOSContextMenu = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Fix MicroSoft Input Method Issue").setDesc("\u9002\u914D\u65E7\u7248\u5FAE\u8F6F\u8F93\u5165\u6CD5").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.TryFixMSIME).onChange(async (value) => {
|
||
this.plugin.settings.TryFixMSIME = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Strict Line breaks Mode Enter Twice").setDesc("\u4E25\u683C\u6362\u884C\u7684\u8BBE\u7F6E\u4E0B\uFF0C\u5728\u666E\u901A\u6587\u672C\u884C\u8FDB\u884C\u4E00\u6B21\u56DE\u8F66\u4F1A\u4EA7\u751F\u4E24\u4E2A\u6362\u884C\u7B26").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.EnterTwice).onChange(async (value) => {
|
||
this.plugin.settings.EnterTwice = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Punc rectify").setDesc("\u4EC5\u5728\u8F93\u5165\u8FC7\u7A0B\u4E2D\uFF0C\u4E2D\u6587\u95F4\u7684\u82F1\u6587\u6807\u70B9\uFF08,.?!\uFF09\u81EA\u52A8\u8F6C\u6362\u4E3A\u5168\u89D2\uFF08\u53EF\u64A4\u9500\uFF09").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.PuncRectify).onChange(async (value) => {
|
||
this.plugin.settings.PuncRectify = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(containerEl).setName("Print debug info in console").setDesc("\u5728\u63A7\u5236\u53F0\u8F93\u51FA\u8C03\u8BD5\u4FE1\u606F").addToggle((toggle) => {
|
||
toggle.setValue(this.plugin.settings.debug).onChange(async (value) => {
|
||
this.plugin.settings.debug = value;
|
||
await this.plugin.saveSettings();
|
||
});
|
||
});
|
||
}
|
||
buildUserSelRepRuleSetting(containerEl) {
|
||
containerEl.empty();
|
||
containerEl.ontoggle = async () => {
|
||
this.plugin.settings.userSelRuleSettingsOpen = containerEl.open;
|
||
await this.plugin.saveSettings();
|
||
};
|
||
const summary = containerEl.createEl("summary", { cls: "easytyping-nested-settings" });
|
||
summary.setText("\u81EA\u5B9A\u4E49\u9009\u4E2D\u6587\u672C\u7F16\u8F91\u589E\u5F3A\u89C4\u5219 (Customize Selection Replace Rule)");
|
||
const selectionRuleSetting = new import_obsidian2.Setting(containerEl);
|
||
selectionRuleSetting.setName("Selection Replece Rule");
|
||
const replaceRuleTrigger = new import_obsidian2.TextComponent(selectionRuleSetting.controlEl);
|
||
replaceRuleTrigger.setPlaceholder("Triggr Symbol");
|
||
const replaceLeftString = new import_obsidian2.TextAreaComponent(selectionRuleSetting.controlEl);
|
||
replaceLeftString.setPlaceholder("New Left Side String");
|
||
const replaceRightString = new import_obsidian2.TextAreaComponent(selectionRuleSetting.controlEl);
|
||
replaceRightString.setPlaceholder("New Right Side String");
|
||
selectionRuleSetting.addButton((button) => {
|
||
button.setButtonText("+").setTooltip("Add Rule").onClick(async (buttonEl) => {
|
||
let trigger = replaceRuleTrigger.inputEl.value;
|
||
let left = replaceLeftString.inputEl.value;
|
||
let right = replaceRightString.inputEl.value;
|
||
if (trigger && (left || right)) {
|
||
if (trigger.length != 1 && trigger != "\u2014\u2014" && trigger != "\u2026\u2026") {
|
||
new import_obsidian2.Notice("Inlvalid trigger, trigger must be a symbol of length 1 or symbol \u2014\u2014, \u2026\u2026");
|
||
return;
|
||
}
|
||
if (this.plugin.addUserSelectionRepRule(trigger, left, right)) {
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
} else {
|
||
new import_obsidian2.Notice("warning! Trigger " + trigger + " is already exist!");
|
||
}
|
||
} else {
|
||
new import_obsidian2.Notice("missing input");
|
||
}
|
||
});
|
||
});
|
||
for (let i = 0; i < this.plugin.settings.userSelRepRuleTrigger.length; i++) {
|
||
let trigger = this.plugin.settings.userSelRepRuleTrigger[i];
|
||
let left_s = this.plugin.settings.userSelRepRuleValue[i].left;
|
||
let right_s = this.plugin.settings.userSelRepRuleValue[i].right;
|
||
let showStr = "Trigger: " + trigger + " \u2192 " + showString(left_s) + "selected" + showString(right_s);
|
||
new import_obsidian2.Setting(containerEl).setName(showStr).addExtraButton((button) => {
|
||
button.setIcon("gear").setTooltip("Edit rule").onClick(() => {
|
||
new SelectRuleEditModal(this.app, trigger, left_s, right_s, async (new_left, new_right) => {
|
||
this.plugin.updateUserSelectionRepRule(i, new_left, new_right);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
}).open();
|
||
});
|
||
}).addExtraButton((button) => {
|
||
button.setIcon("trash").setTooltip("Remove rule").onClick(async () => {
|
||
this.plugin.deleteUserSelectionRepRule(i);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
});
|
||
});
|
||
}
|
||
}
|
||
buildUserDeleteRuleSetting(containerEl) {
|
||
containerEl.empty();
|
||
containerEl.ontoggle = async () => {
|
||
this.plugin.settings.userDelRuleSettingsOpen = containerEl.open;
|
||
await this.plugin.saveSettings();
|
||
};
|
||
const summary = containerEl.createEl("summary", { cls: "easytyping-nested-settings" });
|
||
summary.setText("\u81EA\u5B9A\u4E49\u5220\u9664\u7F16\u8F91\u589E\u5F3A\u89C4\u5219 (Customize Delete Rule)");
|
||
const deleteRuleSetting = new import_obsidian2.Setting(containerEl);
|
||
deleteRuleSetting.setName("Delete Rule").setDesc("\u89C4\u5219\uFF1A\u7528|\u4EE3\u8868\u5149\u6807\u4F4D\u7F6E\uFF0C\u5FC5\u987B\u5305\u542B\u5149\u6807\u3002 Tips: Using | to indicate the cursor position.");
|
||
const patternBefore = new import_obsidian2.TextAreaComponent(deleteRuleSetting.controlEl);
|
||
patternBefore.setPlaceholder("Before Delete");
|
||
const patternAfter = new import_obsidian2.TextAreaComponent(deleteRuleSetting.controlEl);
|
||
patternAfter.setPlaceholder("New Pattern");
|
||
deleteRuleSetting.addButton((button) => {
|
||
button.setButtonText("+").setTooltip("Add Rule").onClick(async (buttonEl) => {
|
||
let before = patternBefore.inputEl.value;
|
||
let after = patternAfter.inputEl.value;
|
||
if (before && after) {
|
||
let regRule = /\|/g;
|
||
if (before.search(regRule) == -1 || after.search(regRule) == -1) {
|
||
new import_obsidian2.Notice("Inlvalid trigger, pattern must contain symbol | which indicate cursor position");
|
||
return;
|
||
} else {
|
||
this.plugin.addUserDeleteRule(before, after);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
}
|
||
} else {
|
||
new import_obsidian2.Notice("missing input");
|
||
}
|
||
});
|
||
});
|
||
for (let i = 0; i < this.plugin.settings.userDeleteRulesStrList.length; i++) {
|
||
let before = this.plugin.settings.userDeleteRulesStrList[i][0];
|
||
let after = this.plugin.settings.userDeleteRulesStrList[i][1];
|
||
let showStr = '"' + showString(before) + '" delete.backwards \u2192 "' + showString(after) + '"';
|
||
new import_obsidian2.Setting(containerEl).setName(showStr).addExtraButton((button) => {
|
||
button.setIcon("gear").setTooltip("Edit rule").onClick(() => {
|
||
new EditConvertRuleModal(this.app, "Delete Rule" /* delete */, before, after, async (new_before, new_after) => {
|
||
this.plugin.updateUserDeleteRule(i, new_before, new_after);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
}).open();
|
||
});
|
||
}).addExtraButton((button) => {
|
||
button.setIcon("trash").setTooltip("Remove rule").onClick(async () => {
|
||
this.plugin.deleteUserDeleteRule(i);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
});
|
||
});
|
||
}
|
||
}
|
||
buildUserConvertRuleSetting(containerEl) {
|
||
containerEl.empty();
|
||
containerEl.ontoggle = async () => {
|
||
this.plugin.settings.userCvtRuleSettingsOpen = containerEl.open;
|
||
await this.plugin.saveSettings();
|
||
};
|
||
const summary = containerEl.createEl("summary", { cls: "easytyping-nested-settings" });
|
||
summary.setText("\u81EA\u5B9A\u4E49\u7F16\u8F91\u8F6C\u6362\u89C4\u5219 (Customize Convert Rule)");
|
||
const convertRuleSetting = new import_obsidian2.Setting(containerEl);
|
||
convertRuleSetting.setName("Convert Rule").setDesc("\u89C4\u5219\uFF1A\u7528|\u4EE3\u8868\u5149\u6807\u4F4D\u7F6E\uFF0C\u5FC5\u987B\u5305\u542B\u5149\u6807\u3002 Tips: Using | to indicate the cursor position.");
|
||
const patternBefore = new import_obsidian2.TextAreaComponent(convertRuleSetting.controlEl);
|
||
patternBefore.setPlaceholder("Before Convert");
|
||
const patternAfter = new import_obsidian2.TextAreaComponent(convertRuleSetting.controlEl);
|
||
patternAfter.setPlaceholder("New Pattern");
|
||
convertRuleSetting.addButton((button) => {
|
||
button.setButtonText("+").setTooltip("Add Rule").onClick(async (buttonEl) => {
|
||
let before = patternBefore.inputEl.value;
|
||
let after = patternAfter.inputEl.value;
|
||
if (before && after) {
|
||
let regRule = /\|/g;
|
||
if (before.search(regRule) == -1 || after.search(regRule) == -1) {
|
||
new import_obsidian2.Notice("Inlvalid trigger, pattern must contain symbol | which indicate cursor position");
|
||
return;
|
||
} else {
|
||
this.plugin.addUserConvertRule(before, after);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
}
|
||
} else {
|
||
new import_obsidian2.Notice("missing input");
|
||
}
|
||
});
|
||
});
|
||
for (let i = 0; i < this.plugin.settings.userConvertRulesStrList.length; i++) {
|
||
let before = this.plugin.settings.userConvertRulesStrList[i][0];
|
||
let after = this.plugin.settings.userConvertRulesStrList[i][1];
|
||
let showStr = '"' + showString(before) + '" auto convert to "' + showString(after) + '"';
|
||
new import_obsidian2.Setting(containerEl).setName(showStr).addExtraButton((button) => {
|
||
button.setIcon("gear").setTooltip("Edit rule").onClick(() => {
|
||
new EditConvertRuleModal(this.app, "Convert Rule" /* convert */, before, after, async (new_before, new_after) => {
|
||
this.plugin.updateUserConvertRule(i, new_before, new_after);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
}).open();
|
||
});
|
||
}).addExtraButton((button) => {
|
||
button.setIcon("trash").setTooltip("Remove rule").onClick(async () => {
|
||
this.plugin.deleteUserConvertRule(i);
|
||
await this.plugin.saveSettings();
|
||
this.display();
|
||
});
|
||
});
|
||
}
|
||
}
|
||
};
|
||
function setAttributes(element, attributes) {
|
||
for (let key in attributes) {
|
||
element.setAttribute(key, attributes[key]);
|
||
}
|
||
}
|
||
var SelectRuleEditModal = class extends import_obsidian2.Modal {
|
||
constructor(app, trigger, left, right, onSubmit) {
|
||
super(app);
|
||
this.trigger = trigger;
|
||
this.old_left = left;
|
||
this.old_right = right;
|
||
this.new_left = left;
|
||
this.new_right = right;
|
||
this.onSubmit = onSubmit;
|
||
}
|
||
onOpen() {
|
||
const { contentEl } = this;
|
||
contentEl.createEl("h1", { text: "Edit Selection Replace Rule" });
|
||
new import_obsidian2.Setting(contentEl).setName("Trigger").addText((text) => {
|
||
text.setValue(this.trigger);
|
||
text.setDisabled(true);
|
||
});
|
||
new import_obsidian2.Setting(contentEl).setName("Left").addTextArea((text) => {
|
||
text.setValue(this.old_left);
|
||
text.onChange((value) => {
|
||
this.new_left = value;
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(contentEl).setName("Right").addTextArea((text) => {
|
||
text.setValue(this.old_right);
|
||
text.onChange((value) => {
|
||
this.new_right = value;
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(contentEl).addButton((btn) => btn.setButtonText("Update").setCta().onClick(() => {
|
||
this.close();
|
||
this.onSubmit(this.new_left, this.new_right);
|
||
}));
|
||
}
|
||
onClose() {
|
||
let { contentEl } = this;
|
||
contentEl.empty();
|
||
}
|
||
};
|
||
var EditConvertRuleModal = class extends import_obsidian2.Modal {
|
||
constructor(app, type, before, after, onSubmit) {
|
||
super(app);
|
||
this.type = type;
|
||
this.old_before = before;
|
||
this.old_after = after;
|
||
this.new_before = before;
|
||
this.new_after = after;
|
||
this.onSubmit = onSubmit;
|
||
}
|
||
onOpen() {
|
||
const { contentEl } = this;
|
||
contentEl.createEl("h1", { text: "Edit " + this.type });
|
||
new import_obsidian2.Setting(contentEl).setName("Old Pattern").addTextArea((text) => {
|
||
text.setValue(this.old_before);
|
||
text.onChange((value) => {
|
||
this.new_before = value;
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(contentEl).setName("New Pattern").addTextArea((text) => {
|
||
text.setValue(this.old_after);
|
||
text.onChange((value) => {
|
||
this.new_after = value;
|
||
});
|
||
});
|
||
new import_obsidian2.Setting(contentEl).addButton((btn) => btn.setButtonText("Update").setCta().onClick(() => {
|
||
if (this.checkConvertPatternString(this.new_before, this.new_after)) {
|
||
this.close();
|
||
this.onSubmit(this.new_before, this.new_after);
|
||
} else {
|
||
new import_obsidian2.Notice("Invalid pattern string!");
|
||
}
|
||
}));
|
||
}
|
||
checkConvertPatternString(before, after) {
|
||
let regRule = /\|/g;
|
||
if (before.search(regRule) == -1 || after.search(regRule) == -1)
|
||
return false;
|
||
return true;
|
||
}
|
||
onClose() {
|
||
let { contentEl } = this;
|
||
contentEl.empty();
|
||
}
|
||
};
|
||
|
||
// src/main.ts
|
||
var import_view = require("@codemirror/view");
|
||
var import_language3 = require("@codemirror/language");
|
||
|
||
// src/syntax.ts
|
||
var import_language2 = require("@codemirror/language");
|
||
function isCodeBlockInPos(state, pos) {
|
||
let codeBlockInfos = getCodeBlocksInfos(state);
|
||
for (let i = 0; i < codeBlockInfos.length; i++) {
|
||
if (pos >= codeBlockInfos[i].start_pos && pos <= codeBlockInfos[i].end_pos) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
function selectCodeBlockInPos(view, pos) {
|
||
let codeBlockInfos = getCodeBlocksInfos(view.state);
|
||
for (let i = 0; i < codeBlockInfos.length; i++) {
|
||
if (pos >= codeBlockInfos[i].start_pos && pos <= codeBlockInfos[i].end_pos) {
|
||
view.dispatch({
|
||
selection: {
|
||
anchor: codeBlockInfos[i].code_start_pos,
|
||
head: codeBlockInfos[i].code_end_pos
|
||
}
|
||
});
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
function getCodeBlocksInfos(state) {
|
||
let isCodeBlockBegin = false;
|
||
let codeBlockInfos = [];
|
||
let curCodeBlockInfo = null;
|
||
const doc = state.doc;
|
||
(0, import_language2.syntaxTree)(state).iterate({
|
||
enter(node) {
|
||
const nodeName = node.name;
|
||
const nodeFrom = node.from;
|
||
const nodeTo = node.to;
|
||
const nodeText = state.sliceDoc(nodeFrom, nodeTo);
|
||
if (nodeName.includes("codeblock-begin")) {
|
||
isCodeBlockBegin = true;
|
||
let start_pos = nodeFrom + nodeText.indexOf("`");
|
||
let indent = start_pos - state.doc.lineAt(start_pos).from;
|
||
let language = nodeText.trim().substring(3);
|
||
curCodeBlockInfo = {
|
||
start_pos,
|
||
end_pos: -1,
|
||
code_start_pos: -1,
|
||
code_end_pos: -1,
|
||
language,
|
||
indent
|
||
};
|
||
} else if (nodeName.includes("codeblock-end")) {
|
||
isCodeBlockBegin = false;
|
||
if (curCodeBlockInfo != null) {
|
||
curCodeBlockInfo.end_pos = nodeTo;
|
||
if (doc.lineAt(curCodeBlockInfo.start_pos).number == doc.lineAt(curCodeBlockInfo.end_pos).number - 1) {
|
||
curCodeBlockInfo.code_start_pos = doc.lineAt(curCodeBlockInfo.start_pos).to;
|
||
curCodeBlockInfo.code_end_pos = doc.lineAt(curCodeBlockInfo.start_pos).to;
|
||
} else {
|
||
let code_start_line = doc.lineAt(curCodeBlockInfo.start_pos).number + 1;
|
||
let code_end_line = doc.lineAt(curCodeBlockInfo.end_pos).number - 1;
|
||
curCodeBlockInfo.code_start_pos = doc.line(code_start_line).from + curCodeBlockInfo.indent;
|
||
curCodeBlockInfo.code_end_pos = doc.line(code_end_line).to;
|
||
}
|
||
codeBlockInfos.push(curCodeBlockInfo);
|
||
curCodeBlockInfo = null;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
if (isCodeBlockBegin && curCodeBlockInfo) {
|
||
curCodeBlockInfo.end_pos = doc.length;
|
||
curCodeBlockInfo.code_end_pos = doc.length;
|
||
if (doc.lines > doc.lineAt(curCodeBlockInfo.start_pos).number) {
|
||
let start_line = doc.lineAt(curCodeBlockInfo.start_pos).number + 1;
|
||
let code_start_pos = doc.line(start_line).from + curCodeBlockInfo.indent;
|
||
curCodeBlockInfo.code_start_pos = code_start_pos < doc.length ? code_start_pos : doc.lineAt(curCodeBlockInfo.start_pos + 1).from;
|
||
} else {
|
||
curCodeBlockInfo.code_start_pos = doc.lineAt(curCodeBlockInfo.start_pos).to;
|
||
}
|
||
codeBlockInfos.push(curCodeBlockInfo);
|
||
curCodeBlockInfo = null;
|
||
}
|
||
return codeBlockInfos;
|
||
}
|
||
|
||
// src/main.ts
|
||
var EasyTypingPlugin = class extends import_obsidian3.Plugin {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.getDefaultIndentChar = () => {
|
||
let default_indent = this.app.vault.config.useTab ? " " : " ".repeat(this.app.vault.config.tabSize);
|
||
return default_indent;
|
||
};
|
||
this.transactionFilterPlugin = (tr) => {
|
||
const changes = [];
|
||
if (!tr.docChanged)
|
||
return tr;
|
||
let selected = tr.startState.selection.asSingle().main.anchor != tr.startState.selection.asSingle().main.head;
|
||
let changeTypeStr = getTypeStrOfTransac(tr);
|
||
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
||
var _a, _b;
|
||
let changedStr = tr.startState.sliceDoc(fromA, toA);
|
||
let changestr_ = changedStr.replace(/\s/g, "0");
|
||
let insertedStr = inserted.sliceString(0);
|
||
if (this.settings.debug) {
|
||
console.log("[TransactionFilter] type, fromA, toA, changed, fromB, toB, inserted");
|
||
console.log(changeTypeStr, fromA, toA, changedStr, fromB, toB, insertedStr);
|
||
}
|
||
if (getPosLineType(tr.startState, fromA) == "table" /* table */)
|
||
return tr;
|
||
if (this.settings.SelectionEnhance) {
|
||
if ((changeTypeStr == "input.type" || changeTypeStr == "input.type.compose") && fromA != toA && (fromB + 1 === toB || insertedStr == "\u2014\u2014" || insertedStr == "\u2026\u2026")) {
|
||
if (this.SelectionReplaceMap.has(insertedStr)) {
|
||
changes.push({ changes: { from: fromA, insert: (_a = this.SelectionReplaceMap.get(insertedStr)) == null ? void 0 : _a.left }, userEvent: "EasyTyping.change" });
|
||
changes.push({ changes: { from: toA, insert: (_b = this.SelectionReplaceMap.get(insertedStr)) == null ? void 0 : _b.right }, userEvent: "EasyTyping.change" });
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
if (this.settings.BetterCodeEdit && changeTypeStr.contains("paste") && fromA == fromB && isCodeBlockInPos(tr.startState, fromA)) {
|
||
print("\u68C0\u6D4B\u5230\u5728\u4EE3\u7801\u5757\u4E2D\u7C98\u8D34");
|
||
let line = tr.startState.doc.lineAt(fromB).text;
|
||
let indent_space = line.match(/^\s*/)[0].length;
|
||
let inserted_lines = insertedStr.split("\n");
|
||
let extra_indent = "";
|
||
if (inserted_lines.length > 1) {
|
||
let first_line = inserted_lines[0].trimStart();
|
||
if (first_line.endsWith("{") || first_line.endsWith("(") || first_line.endsWith("[")) {
|
||
extra_indent = this.getDefaultIndentChar();
|
||
}
|
||
let rest_lines = inserted_lines.slice(1);
|
||
let min_indent_space = Infinity;
|
||
for (let line2 of rest_lines) {
|
||
let indent = line2.match(/^\s*/)[0].length;
|
||
if (!/^\s*$/.test(line2) && indent < min_indent_space)
|
||
min_indent_space = indent;
|
||
}
|
||
let new_rest_lines = rest_lines.map((line2) => line2.substring(min_indent_space));
|
||
new_rest_lines = new_rest_lines.map((line2) => line2.replace(/[\t]/g, this.getDefaultIndentChar()));
|
||
let final_rest_lines = new_rest_lines.map((line2) => " ".repeat(indent_space) + extra_indent + line2);
|
||
let new_insertedStr = first_line + "\n" + final_rest_lines.join("\n");
|
||
changes.push({
|
||
changes: { from: fromA, to: toA, insert: new_insertedStr },
|
||
selection: { anchor: fromA + new_insertedStr.length },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
if (selected)
|
||
return tr;
|
||
if (this.settings.TryFixMSIME && changeTypeStr == "input.type.compose" && changedStr == "" && /^[\u4e00-\u9fa5]+$/.test(insertedStr)) {
|
||
print("MS-IME Compose detected:", insertedStr);
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
if (this.settings.BetterCodeEdit && changeTypeStr == "delete.backward" && !selected && getPosLineType(tr.startState, toA) == "codeblock" /* codeblock */ && (tr.startState.sliceDoc(fromA, toA) != "`" || getPosLineType(tr.state, fromA) == "codeblock" /* codeblock */)) {
|
||
let line_number = tr.startState.doc.lineAt(toA).number;
|
||
let cur_line = tr.startState.doc.lineAt(toA);
|
||
let list_code = false;
|
||
let list_code_indent = 0;
|
||
for (let i = line_number - 1; i >= 1; i--) {
|
||
let line = tr.startState.doc.line(i);
|
||
if (/^\s+```/.test(line.text)) {
|
||
list_code = true;
|
||
list_code_indent = line.text.match(/^\s*/)[0].length;
|
||
break;
|
||
} else if (/^```/.test(line.text))
|
||
break;
|
||
else
|
||
continue;
|
||
}
|
||
if (list_code) {
|
||
print("list_code, indent: ", list_code_indent);
|
||
if (toA == cur_line.from + list_code_indent) {
|
||
changes.push({ changes: { from: tr.startState.doc.line(line_number - 1).to, to: toA, insert: "" }, userEvent: "EasyTyping.change" });
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
if (fromA >= cur_line.from && fromA < cur_line.from + list_code_indent && toA > cur_line.from + list_code_indent) {
|
||
changes.push({ changes: { from: cur_line.from + list_code_indent, to: toA, insert: "" }, userEvent: "EasyTyping.change" });
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
if (changeTypeStr == "delete.backward") {
|
||
for (let rule of this.UserDeleteRules) {
|
||
let left = tr.startState.doc.sliceString(toA - rule.before.left.length, toA);
|
||
let right = tr.startState.doc.sliceString(toA, toA + rule.before.right.length);
|
||
if (left === rule.before.left && right === rule.before.right) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - rule.before.left.length,
|
||
to: toA + rule.before.right.length,
|
||
insert: rule.after.left + rule.after.right
|
||
},
|
||
selection: { anchor: toA - rule.before.left.length + rule.after.left.length },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
if (changeTypeStr === "delete.backward" && this.settings.IntrinsicSymbolPairs) {
|
||
if (this.SymbolPairsMap.has(changedStr) && this.SymbolPairsMap.get(changedStr) === tr.startState.sliceDoc(toA, toA + 1)) {
|
||
changes.push({ changes: { from: fromA, to: toA + 1 }, userEvent: "EasyTyping.change" });
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
let line_content = tr.startState.doc.lineAt(toA).text;
|
||
let next_line_content = tr.startState.doc.sliceString(toA, toA + line_content.length + 1);
|
||
if (/^\s*```$/.test(line_content) && "\n" + line_content == next_line_content) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - 3,
|
||
to: toA + line_content.length + 1,
|
||
insert: ""
|
||
},
|
||
selection: { anchor: toA - 3 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
for (let rule of this.IntrinsicDeleteRules) {
|
||
let left = tr.startState.doc.sliceString(toA - rule.before.left.length, toA);
|
||
let right = tr.startState.doc.sliceString(toA, toA + rule.before.right.length);
|
||
if (left === rule.before.left && right === rule.before.right) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - rule.before.left.length,
|
||
to: toA + rule.before.right.length,
|
||
insert: rule.after.left + rule.after.right
|
||
},
|
||
selection: { anchor: toA - rule.before.left.length + rule.after.left.length },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
if (changeTypeStr == "input.type" && insertedStr == "`\n```" && this.settings.BaseObEditEnhance) {
|
||
const line_content = tr.startState.doc.lineAt(fromA).text;
|
||
if (/^\s*``$/.test(line_content)) {
|
||
changes.push({
|
||
changes: { from: fromA, to: toA, insert: "`\n" + line_content + "`" },
|
||
selection: { anchor: fromA + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
if ((changeTypeStr == "input.type" || changeTypeStr == "input.type.compose") && fromA === toA && fromB + 1 === toB) {
|
||
if (this.settings.BaseObEditEnhance) {
|
||
if (insertedStr === "`" && toA - tr.startState.doc.lineAt(toA).from > 2 && tr.startState.sliceDoc(toA - 1, toA) === "`" && tr.startState.sliceDoc(toA - 2, toA - 1) != "`") {
|
||
changes.push({
|
||
changes: { from: toA, insert: "`" },
|
||
selection: { anchor: toA },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
if (insertedStr == "\xB7") {
|
||
let line_content = tr.startState.doc.lineAt(fromA).text;
|
||
let ch_pos = fromA - tr.startState.doc.lineAt(fromA).from;
|
||
if (/^\s*``$/.test(line_content) && ch_pos == line_content.length - 1) {
|
||
changes.push({
|
||
changes: { from: fromA + 1, to: toA + 1, insert: "`\n" + line_content + "`" },
|
||
selection: { anchor: fromA + 2 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
for (let rule of this.BasicConvRules) {
|
||
if (insertedStr != rule.before.left.charAt(rule.before.left.length - 1))
|
||
continue;
|
||
if (rule.before.left.charAt(0) === "\n" && offsetToPos(tr.state.doc, fromA).line === 0 && toB - rule.before.left.length + 1 === 0) {
|
||
let left = tr.state.doc.sliceString(toB - rule.before.left.length + 1, toB);
|
||
let right = tr.state.doc.sliceString(toB, toB + rule.before.right.length);
|
||
if (left === rule.before.left.substring(1) && right === rule.before.right) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - rule.before.left.length + 2,
|
||
to: toA + rule.before.right.length,
|
||
insert: rule.after.left.substring(1) + rule.after.right
|
||
},
|
||
selection: { anchor: toA - rule.before.left.length + rule.after.left.length + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
} else {
|
||
let left = tr.state.doc.sliceString(toB - rule.before.left.length, toB);
|
||
let right = tr.state.doc.sliceString(toB, toB + rule.before.right.length);
|
||
if (left === rule.before.left && right === rule.before.right) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - rule.before.left.length + 1,
|
||
to: toA + rule.before.right.length,
|
||
insert: rule.after.left + rule.after.right
|
||
},
|
||
selection: { anchor: toA - rule.before.left.length + rule.after.left.length + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (this.settings.FW2HWEnhance) {
|
||
for (let rule of this.FW2HWSymbolRules) {
|
||
if (insertedStr != rule.before.left.charAt(rule.before.left.length - 1))
|
||
continue;
|
||
let left = tr.state.doc.sliceString(toB - rule.before.left.length, toB);
|
||
let right = tr.state.doc.sliceString(toB, toB + rule.before.right.length);
|
||
if (left === rule.before.left && right === rule.before.right) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - rule.before.left.length + 1,
|
||
to: toA + rule.before.right.length,
|
||
insert: rule.after.left + rule.after.right
|
||
},
|
||
selection: { anchor: toA - rule.before.left.length + rule.after.left.length + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
if (this.settings.IntrinsicSymbolPairs) {
|
||
for (let rule of this.IntrinsicAutoPairRulesPatch) {
|
||
if (insertedStr != rule.before.left.charAt(rule.before.left.length - 1))
|
||
continue;
|
||
let left = tr.state.doc.sliceString(toB - rule.before.left.length, toB);
|
||
let right = tr.state.doc.sliceString(toB, toB + rule.before.right.length);
|
||
if (left === rule.before.left && right === rule.before.right) {
|
||
changes.push({
|
||
changes: {
|
||
from: toA - rule.before.left.length + 1,
|
||
to: toA + rule.before.right.length,
|
||
insert: rule.after.left + rule.after.right
|
||
},
|
||
selection: { anchor: toA - rule.before.left.length + rule.after.left.length + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
if (this.SymbolPairsMap.has(insertedStr) && insertedStr != "'") {
|
||
changes.push({
|
||
changes: { from: fromA, to: toA, insert: insertedStr + this.SymbolPairsMap.get(insertedStr) },
|
||
selection: { anchor: fromA + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
} else if (insertedStr === "'") {
|
||
let charBeforeCursor = tr.startState.sliceDoc(fromA - 1, fromA);
|
||
if (["", " ", "\n"].includes(charBeforeCursor)) {
|
||
changes.push({
|
||
changes: { from: fromA, to: toA, insert: "''" },
|
||
selection: { anchor: fromA + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
if (insertedStr === "\u201D" || insertedStr === "\u2019") {
|
||
let tempStr = insertedStr === "\u201D" ? "\u201C\u201D" : "\u2018\u2019";
|
||
changes.push({
|
||
changes: { from: fromA, to: toA, insert: tempStr },
|
||
selection: { anchor: fromA + 1 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
tr = tr.startState.update(...changes);
|
||
return tr;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
return tr;
|
||
};
|
||
this.viewUpdatePlugin = (update) => {
|
||
if (this.onFormatArticle === true)
|
||
return;
|
||
let notSelected = true;
|
||
let mainSelection = update.view.state.selection.asSingle().main;
|
||
if (mainSelection.anchor != mainSelection.head)
|
||
notSelected = false;
|
||
if (!update.docChanged)
|
||
return;
|
||
let isExcludeFile = this.isCurrentFileExclude();
|
||
let tr = update.transactions[0];
|
||
let changeType = getTypeStrOfTransac(tr);
|
||
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
||
let insertedStr = inserted.sliceString(0);
|
||
let changedStr = tr.startState.doc.sliceString(fromA, toA);
|
||
if (this.settings.debug) {
|
||
console.log("[ViewUpdate] type, fromA, toA, changed, fromB, toB, inserted");
|
||
console.log(changeType, fromA, toA, changedStr, fromB, toB, insertedStr);
|
||
console.log("==>[Composing]", update.view.composing);
|
||
}
|
||
if (getPosLineType(update.view.state, fromB) == "table" /* table */) {
|
||
return;
|
||
}
|
||
let cursor = update.view.state.selection.asSingle().main;
|
||
if (update.view.composing) {
|
||
if (this.compose_need_handle) {
|
||
this.compose_end_pos = cursor.anchor;
|
||
} else {
|
||
this.compose_need_handle = true;
|
||
this.compose_begin_pos = fromA;
|
||
this.compose_end_pos = cursor.anchor;
|
||
}
|
||
return;
|
||
}
|
||
let change_from = fromB;
|
||
let change_to = toB;
|
||
let composeEnd = false;
|
||
if (this.compose_need_handle) {
|
||
composeEnd = true;
|
||
this.compose_need_handle = false;
|
||
change_from = this.compose_begin_pos;
|
||
change_to = this.compose_end_pos;
|
||
}
|
||
if (changeType.contains("EasyTyping") || changeType == "undo" || changeType == "redo")
|
||
return;
|
||
if (changeType != "none" && notSelected && !changeType.includes("delete")) {
|
||
if (this.triggerUserCvtRule(update.view, mainSelection.anchor))
|
||
return;
|
||
if (composeEnd && this.triggerPuncRectify(update.view, change_from))
|
||
return;
|
||
if (this.settings.AutoFormat && notSelected && !isExcludeFile && (changeType != "none" || insertedStr == "\n")) {
|
||
if (getPosLineType(update.view.state, change_from) == "text" /* text */ || getPosLineType(update.view.state, change_from) == "table" /* table */) {
|
||
let changes = this.Formater.formatLineOfDoc(update.state, this.settings, change_from, cursor.anchor, insertedStr);
|
||
if (changes != null) {
|
||
update.view.dispatch(...changes[0]);
|
||
update.view.dispatch(changes[1]);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (this.settings.AutoFormat && !isExcludeFile && changeType == "input.paste" && !import_obsidian3.Platform.isIosApp) {
|
||
let updateLineStart = update.state.doc.lineAt(fromB).number;
|
||
let updateLineEnd = update.state.doc.lineAt(toB).number;
|
||
if (updateLineStart == updateLineEnd && getPosLineType(update.view.state, toB) == "text" /* text */) {
|
||
let changes = this.Formater.formatLineOfDoc(update.state, this.settings, fromB, toB, insertedStr);
|
||
if (changes != null) {
|
||
update.view.dispatch(...changes[0]);
|
||
return;
|
||
}
|
||
} else {
|
||
let all_changes = [];
|
||
let inserted_array = insertedStr.split("\n");
|
||
let update_start = fromB;
|
||
for (let i = updateLineStart; i <= updateLineEnd; i++) {
|
||
let real_inserted = inserted_array[i - updateLineStart];
|
||
let changes = this.Formater.formatLineOfDoc(update.state, this.settings, update_start, update_start + real_inserted.length, real_inserted);
|
||
if (changes != null) {
|
||
all_changes.push(...changes[0]);
|
||
}
|
||
update_start += real_inserted.length + 1;
|
||
}
|
||
if (all_changes.length > 0) {
|
||
update.view.dispatch(...all_changes);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
};
|
||
this.handleTabDown = (view) => {
|
||
if (!this.settings.Tabout)
|
||
return false;
|
||
let state = view.state;
|
||
let doc = state.doc;
|
||
const tree = (0, import_language3.syntaxTree)(state);
|
||
const s = view.state.selection;
|
||
if (s.ranges.length > 1)
|
||
return false;
|
||
const pos = s.main.to;
|
||
let line = doc.lineAt(pos);
|
||
if (s.main.from == s.main.to && getPosLineType(view.state, s.main.from) == "codeblock" /* codeblock */) {
|
||
view.dispatch({
|
||
changes: {
|
||
from: s.main.from,
|
||
insert: this.getDefaultIndentChar()
|
||
},
|
||
selection: {
|
||
anchor: s.main.from + this.getDefaultIndentChar().length
|
||
}
|
||
});
|
||
return true;
|
||
}
|
||
if (this.settings.BetterCodeEdit && pos - line.from != 0 && tree.resolve(pos - 1, 1).name.contains("inline-code")) {
|
||
if (tree.resolve(pos, 1).name.contains("formatting-code_inline-code")) {
|
||
view.dispatch({
|
||
selection: { anchor: pos + 1, head: pos + 1 }
|
||
});
|
||
return true;
|
||
}
|
||
for (let p = pos + 1; p < line.to && tree.resolve(p, 1).name.contains("inline-code"); p += 1) {
|
||
if (tree.resolve(p, 1).name.contains("formatting-code_inline-code")) {
|
||
view.dispatch({
|
||
selection: { anchor: p, head: p }
|
||
});
|
||
return true;
|
||
}
|
||
if (p == line.to - 1 && tree.resolve(p, 1).name.contains("inline-code")) {
|
||
view.dispatch({
|
||
selection: { anchor: p + 1, head: p + 1 }
|
||
});
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
let selection = view.state.selection.asSingle().main;
|
||
let selected = selection.anchor != selection.head;
|
||
if (selected) {
|
||
let new_anchor = selection.anchor < selection.head ? selection.anchor : selection.head;
|
||
let new_head = selection.anchor > selection.head ? selection.anchor : selection.head;
|
||
for (let pstr of this.TaboutPairStrs) {
|
||
if (doc.sliceString(new_anchor - pstr.left.length, new_anchor) == pstr.left && doc.sliceString(new_head, new_head + pstr.right.length) == pstr.right) {
|
||
view.dispatch({
|
||
selection: { anchor: new_head + pstr.right.length, head: new_head + pstr.right.length }
|
||
});
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
this.handleEnter = (view) => {
|
||
if (!this.settings.EnterTwice)
|
||
return false;
|
||
let strictLineBreaks = this.app.vault.config.strictLineBreaks || false;
|
||
if (!strictLineBreaks)
|
||
return false;
|
||
let state = view.state;
|
||
let doc = state.doc;
|
||
const tree = (0, import_language3.syntaxTree)(state);
|
||
const s = view.state.selection;
|
||
if (s.ranges.length > 1)
|
||
return false;
|
||
const pos = s.main.to;
|
||
let line = doc.lineAt(pos);
|
||
if (/^\s*$/.test(line.text))
|
||
return false;
|
||
else if (getPosLineType2(state, pos) == "text" /* text */) {
|
||
view.dispatch({
|
||
changes: {
|
||
from: pos,
|
||
to: pos,
|
||
insert: "\n\n"
|
||
},
|
||
selection: { anchor: pos + 2 },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
this.handleModAInCodeBlock = (view) => {
|
||
if (!this.settings.BetterCodeEdit)
|
||
return false;
|
||
let selected = false;
|
||
let mainSelection = view.state.selection.asSingle().main;
|
||
if (mainSelection.anchor != mainSelection.head)
|
||
selected = true;
|
||
if (selected)
|
||
return false;
|
||
let cursor_pos = mainSelection.anchor;
|
||
return selectCodeBlockInPos(view, cursor_pos);
|
||
};
|
||
this.onKeyup = (event, view) => {
|
||
if (this.settings.debug) {
|
||
console.log("Keyup:", event.key);
|
||
}
|
||
this.handleEndComposeTypeKey(event, view);
|
||
};
|
||
this.triggerUserCvtRule = (view, cursor_pos) => {
|
||
for (let rule of this.UserConvertRules) {
|
||
let left = view.state.doc.sliceString(cursor_pos - rule.before.left.length, cursor_pos);
|
||
let right = view.state.doc.sliceString(cursor_pos, cursor_pos + rule.before.right.length);
|
||
let inserted = rule.after.left + rule.after.right;
|
||
let anchor = cursor_pos - rule.before.left.length + rule.after.left.length;
|
||
let from = cursor_pos - rule.before.left.length;
|
||
let to = cursor_pos + rule.before.right.length;
|
||
if (rule.before.left.charAt(0) === "\n" && rule.after.left.charAt(0) === "\n" && cursor_pos - rule.before.left.length + 1 == 0) {
|
||
left = "\n" + left;
|
||
inserted = inserted.substring(1);
|
||
from = 0;
|
||
}
|
||
if (left === rule.before.left && right === rule.before.right) {
|
||
view.dispatch({
|
||
changes: {
|
||
from,
|
||
to,
|
||
insert: inserted
|
||
},
|
||
selection: { anchor },
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
this.triggerPuncRectify = (view, change_from_pos) => {
|
||
if (this.settings.PuncRectify && /[,.?!]/.test(view.state.doc.sliceString(change_from_pos - 1, change_from_pos))) {
|
||
let punc = view.state.doc.sliceString(change_from_pos - 1, change_from_pos);
|
||
if (change_from_pos > 2 && /[^\u4e00-\u9fa5]/.test(view.state.doc.sliceString(change_from_pos - 2, change_from_pos - 1))) {
|
||
} else {
|
||
view.dispatch({
|
||
changes: {
|
||
from: change_from_pos - 1,
|
||
to: change_from_pos,
|
||
insert: this.halfToFullSymbolMap.get(punc)
|
||
},
|
||
userEvent: "EasyTyping.change"
|
||
});
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
this.handleEndComposeTypeKey = (event, view) => {
|
||
if ((["Enter", "Process", " ", "Shift"].contains(event.key) || /\d/.test(event.key)) && this.compose_need_handle) {
|
||
let cursor = view.state.selection.asSingle().main;
|
||
if (cursor.head != cursor.anchor)
|
||
return;
|
||
let insertedStr = view.state.doc.sliceString(this.compose_begin_pos, cursor.anchor);
|
||
this.compose_need_handle = false;
|
||
if (this.triggerUserCvtRule(view, cursor.anchor))
|
||
return;
|
||
if (this.triggerPuncRectify(view, this.compose_begin_pos))
|
||
return;
|
||
if (this.settings.AutoFormat && !this.isCurrentFileExclude()) {
|
||
if (getPosLineType(view.state, cursor.anchor) != "text" /* text */)
|
||
return;
|
||
let changes = this.Formater.formatLineOfDoc(view.state, this.settings, this.compose_begin_pos, cursor.anchor, insertedStr);
|
||
if (changes != null) {
|
||
view.dispatch(...changes[0]);
|
||
view.dispatch(changes[1]);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
this.formatArticle = (editor, view) => {
|
||
const editorView = editor.cm;
|
||
const tree = (0, import_language3.ensureSyntaxTree)(editorView.state, editorView.state.doc.length);
|
||
if (!tree) {
|
||
new import_obsidian3.Notice("EasyTyping: Syntax tree is not ready yet, please wait a moment and try again later!", 5e3);
|
||
return;
|
||
}
|
||
this.onFormatArticle = true;
|
||
let lineCount = editor.lineCount();
|
||
let new_article = "";
|
||
let cs = editor.getCursor();
|
||
let ch = 0;
|
||
for (let i = 0; i < lineCount; i++) {
|
||
if (i != 0)
|
||
new_article += "\n";
|
||
if (i != cs.line) {
|
||
new_article += this.preFormatOneLine(editor, i + 1)[0];
|
||
} else {
|
||
let newData = this.preFormatOneLine(editor, i + 1, cs.ch);
|
||
new_article += newData[0];
|
||
ch = newData[1];
|
||
}
|
||
}
|
||
editor.setValue(new_article);
|
||
editor.setCursor({ line: cs.line, ch });
|
||
this.onFormatArticle = false;
|
||
new import_obsidian3.Notice("EasyTyping: Format Article Done!");
|
||
};
|
||
this.formatSelectionOrCurLine = (editor, view) => {
|
||
if (!editor.somethingSelected() || editor.getSelection() === "") {
|
||
let lineNumber = editor.getCursor().line;
|
||
let newLineData = this.preFormatOneLine(editor, lineNumber + 1, editor.getCursor().ch);
|
||
editor.replaceRange(newLineData[0], { line: lineNumber, ch: 0 }, { line: lineNumber, ch: editor.getLine(lineNumber).length });
|
||
editor.setSelection({ line: lineNumber, ch: newLineData[1] });
|
||
return;
|
||
}
|
||
let selection = editor.listSelections()[0];
|
||
let begin = selection.anchor.line;
|
||
let end = selection.head.line;
|
||
if (begin > end) {
|
||
let temp = begin;
|
||
begin = end;
|
||
end = temp;
|
||
}
|
||
let new_lines = "";
|
||
for (let i = begin; i <= end; i++) {
|
||
if (i != begin)
|
||
new_lines += "\n";
|
||
new_lines += this.preFormatOneLine(editor, i + 1)[0];
|
||
}
|
||
editor.replaceRange(new_lines, { line: begin, ch: 0 }, { line: end, ch: editor.getLine(end).length });
|
||
if (selection.anchor.line < selection.head.line) {
|
||
editor.setSelection({ line: selection.anchor.line, ch: 0 }, { line: selection.head.line, ch: editor.getLine(selection.head.line).length });
|
||
} else {
|
||
editor.setSelection({ line: selection.anchor.line, ch: editor.getLine(selection.anchor.line).length }, { line: selection.head.line, ch: 0 });
|
||
}
|
||
};
|
||
this.formatOneLine = (editor, lineNumber) => {
|
||
const editorView = editor.cm;
|
||
let state = editorView.state;
|
||
let line = state.doc.line(lineNumber);
|
||
if (getPosLineType(state, line.from) == "text" /* text */ || getPosLineType(state, line.from) == "table" /* table */) {
|
||
let oldLine = line.text;
|
||
let newLine = this.Formater.formatLine(state, lineNumber, this.settings, oldLine.length, 0)[0];
|
||
if (oldLine != newLine) {
|
||
editor.replaceRange(newLine, { line: lineNumber - 1, ch: 0 }, { line: lineNumber - 1, ch: oldLine.length });
|
||
editor.setCursor({ line: lineNumber - 1, ch: editor.getLine(lineNumber - 1).length });
|
||
}
|
||
}
|
||
return;
|
||
};
|
||
this.preFormatOneLine = (editor, lineNumber, ch = -1) => {
|
||
const editorView = editor.cm;
|
||
let state = editorView.state;
|
||
let line = state.doc.line(lineNumber);
|
||
let newLine = line.text;
|
||
let newCh = 0;
|
||
let curCh = line.text.length;
|
||
if (ch != -1) {
|
||
curCh = ch;
|
||
}
|
||
if (getPosLineType(state, line.from) == "text" /* text */ || getPosLineType(state, line.from) == "table" /* table */) {
|
||
let newLineData = this.Formater.formatLine(state, lineNumber, this.settings, curCh, 0);
|
||
newLine = newLineData[0];
|
||
newCh = newLineData[1];
|
||
}
|
||
return [newLine, newCh];
|
||
};
|
||
this.deleteBlankLines = (editor) => {
|
||
if (this.settings.debug) {
|
||
console.log(this.app.vault.getConfig("strictLineBreaks"));
|
||
}
|
||
let strictLineBreaks = this.app.vault.getConfig("strictLineBreaks");
|
||
const editorView = editor.cm;
|
||
let state = editorView.state;
|
||
let doc = state.doc;
|
||
const tree = (0, import_language3.ensureSyntaxTree)(state, doc.length);
|
||
if (!tree) {
|
||
new import_obsidian3.Notice("EasyTyping: Syntax tree is not ready yet, please wait a moment and try again later!", 5e3);
|
||
return;
|
||
}
|
||
let start_line = 1;
|
||
let end_line = doc.lines;
|
||
let line_num = doc.lines;
|
||
const selected = editor.somethingSelected() && editor.getSelection() != "";
|
||
if (selected) {
|
||
let selection = editor.listSelections()[0];
|
||
let begin = selection.anchor.line + 1;
|
||
let end = selection.head.line + 1;
|
||
if (begin > end) {
|
||
let temp = begin;
|
||
begin = end;
|
||
end = temp;
|
||
}
|
||
start_line = begin;
|
||
end_line = end;
|
||
}
|
||
let delete_index = [];
|
||
let blank_reg = /^\s*$/;
|
||
let remain_next_blank = false;
|
||
if (start_line != 1) {
|
||
let node = tree.resolve(doc.line(start_line - 1).from, 1);
|
||
if (node.name.contains("list") || node.name.contains("quote") || node.name.contains("blockid")) {
|
||
remain_next_blank = true;
|
||
}
|
||
}
|
||
if (end_line != line_num && !blank_reg.test(doc.line(end_line + 1).text)) {
|
||
end_line += 1;
|
||
}
|
||
for (let i = start_line; i <= end_line; i++) {
|
||
let line = doc.line(i);
|
||
let pos = line.from;
|
||
let node = tree.resolve(pos, 1);
|
||
if (blank_reg.test(line.text) && !remain_next_blank) {
|
||
delete_index.push(i);
|
||
continue;
|
||
} else if (blank_reg.test(line.text) && remain_next_blank) {
|
||
remain_next_blank = false;
|
||
continue;
|
||
}
|
||
if (node.name.contains("hr") && delete_index[delete_index.length - 1] == i - 1) {
|
||
delete_index.pop();
|
||
} else if (node.name.contains("list") || node.name.contains("quote") || node.name.contains("blockid")) {
|
||
remain_next_blank = true;
|
||
} else {
|
||
remain_next_blank = false;
|
||
}
|
||
}
|
||
let newContent = "";
|
||
for (let i = 1; i < line_num; i++) {
|
||
if (!delete_index.contains(i)) {
|
||
newContent += doc.line(i).text + "\n";
|
||
}
|
||
}
|
||
if (!delete_index.contains(line_num)) {
|
||
newContent += doc.line(line_num).text;
|
||
}
|
||
editor.setValue(newContent);
|
||
};
|
||
this.getEditor = () => {
|
||
let editor = null;
|
||
let markdownView = this.app.workspace.getActiveViewOfType(import_obsidian3.MarkdownView);
|
||
if (markdownView) {
|
||
editor = markdownView.editor;
|
||
}
|
||
if (editor === null)
|
||
console.log("can't get editor");
|
||
return editor;
|
||
};
|
||
}
|
||
async onload() {
|
||
await this.loadSettings();
|
||
this.selectionReplaceMapInitalData = [
|
||
["\u3010", { left: "[", right: "]" }],
|
||
["\uFFE5", { left: "$", right: "$" }],
|
||
["\xB7", { left: "`", right: "`" }],
|
||
["\xA5", { left: "$", right: "$" }],
|
||
["\u300A", { left: "\u300A", right: "\u300B" }],
|
||
["\u201C", { left: "\u201C", right: "\u201D" }],
|
||
["\u201D", { left: "\u201C", right: "\u201D" }],
|
||
["\uFF08", { left: "\uFF08", right: "\uFF09" }],
|
||
["<", { left: "<", right: ">" }]
|
||
];
|
||
this.refreshSelectionReplaceRule();
|
||
this.SymbolPairsMap = /* @__PURE__ */ new Map();
|
||
let SymbolPairs = ["\u3010\u3011", "\uFF08\uFF09", "\u300A\u300B", "\u201C\u201D", "\u2018\u2019", "\u300C\u300D", "\u300E\u300F", "[]", "()", "{}", '""', "''"];
|
||
for (let pairStr of SymbolPairs)
|
||
this.SymbolPairsMap.set(pairStr.charAt(0), pairStr.charAt(1));
|
||
this.halfToFullSymbolMap = /* @__PURE__ */ new Map([
|
||
[".", "\u3002"],
|
||
[",", "\uFF0C"],
|
||
["?", "\uFF1F"],
|
||
["!", "\uFF01"]
|
||
]);
|
||
let BasicConvRuleStringList = [
|
||
["\xB7\xB7|", "`|`"],
|
||
["\uFF01\u3010\u3010|\u3011", "![[|]]"],
|
||
["\uFF01\u3010\u3010|", "![[|]]"],
|
||
["\u3010\u3010|\u3011", "[[|]]"],
|
||
["\u3010\u3010|", "[[|]]"],
|
||
["\uFFE5\uFFE5|", "$|$"],
|
||
["$\uFFE5|$", "$$\n|\n$$"],
|
||
["\xA5\xA5|", "$|$"],
|
||
["$\xA5|$", "$$\n|\n$$"],
|
||
["$$|$", "$$\n|\n$$"],
|
||
["$$|", "$|$"],
|
||
[">\u300B|", ">>|"],
|
||
["\n\u300B|", "\n>|"],
|
||
[" \u300B|", " >|"],
|
||
["\n\u3001|", "\n/|"]
|
||
];
|
||
this.BasicConvRules = ruleStringList2RuleList(BasicConvRuleStringList);
|
||
let FW2HWSymbolRulesStrList = [
|
||
["\u3002\u3002|", ".|"],
|
||
["\uFF01\uFF01|", "!|"],
|
||
["\uFF1B\uFF1B|", ";|"],
|
||
["\uFF0C\uFF0C|", ",|"],
|
||
["\uFF1A\uFF1A|", ":|"],
|
||
["\uFF1F\uFF1F|", "?|"],
|
||
["\uFF08\uFF08|\uFF09", "(|)"],
|
||
["\uFF08\uFF08|", "(|)"],
|
||
["\u201C\u201C|\u201D", '"|"'],
|
||
["\u201C\u201D|\u201D", '"|"'],
|
||
["\u2018\u2018|\u2019", "'|'"],
|
||
["\u2018\u2019|\u2019", "'|'"],
|
||
["\u300B\u300B|", ">|"],
|
||
["\u300A\u300A|\u300B", "<|"],
|
||
["\u300A\u300A|", "<|"]
|
||
];
|
||
this.FW2HWSymbolRules = ruleStringList2RuleList(FW2HWSymbolRulesStrList);
|
||
let fw2hw_rule_0 = { before: { left: "\uFF5C\uFF5C", right: "" }, after: { left: "|", right: "" } };
|
||
this.FW2HWSymbolRules.push(fw2hw_rule_0);
|
||
let DeleteRulesStrList = [["$|$", "|"], ["==|==", "|"], ["$$\n|\n$$", "|"]];
|
||
this.IntrinsicDeleteRules = ruleStringList2RuleList(DeleteRulesStrList);
|
||
let autoPairRulesPatchStrList = [
|
||
["\u3010\u3011|\u3011", "\u3010\u3011|"],
|
||
["\uFF08\uFF09|\uFF09", "\uFF08\uFF09|"],
|
||
["<>|>", "<>|"],
|
||
["\u300A\u300B|\u300B", "\u300A\u300B|"],
|
||
["\u300C\u300D|\u300D", "\u300C\u300D|"],
|
||
["\u300E\u300F|\u300F", "\u300E\u300F|"],
|
||
["()|)", "()|"],
|
||
["[]|]", "[]|"],
|
||
["{}|}", "{}|"],
|
||
["''|'", "''|"],
|
||
['""|"', '""|']
|
||
];
|
||
this.IntrinsicAutoPairRulesPatch = ruleStringList2RuleList(autoPairRulesPatchStrList);
|
||
let TaboutPairStrs = [
|
||
"\u3010|\u3011",
|
||
"\uFF08|\uFF09",
|
||
"\u300A|\u300B",
|
||
"\u201C|\u201D",
|
||
"\u2018|\u2019",
|
||
"\u300C|\u300D",
|
||
"\u300E|\u300F",
|
||
"'|'",
|
||
'"|"',
|
||
"$$|$$",
|
||
"$|$",
|
||
"__|__",
|
||
"_|_",
|
||
"==|==",
|
||
"~~|~~",
|
||
"**|**",
|
||
"*|*",
|
||
"[[|]]",
|
||
"[|]",
|
||
"{|}",
|
||
"(|)",
|
||
"<|>"
|
||
];
|
||
this.TaboutPairStrs = TaboutPairStrs.map((s) => string2pairstring(s));
|
||
this.refreshUserDeleteRule();
|
||
this.refreshUserConvertRule();
|
||
this.CurActiveMarkdown = "";
|
||
this.compose_need_handle = false;
|
||
this.Formater = new LineFormater();
|
||
this.onFormatArticle = false;
|
||
this.registerEditorExtension([
|
||
import_state.EditorState.transactionFilter.of(this.transactionFilterPlugin),
|
||
import_view.EditorView.updateListener.of(this.viewUpdatePlugin),
|
||
import_state.Prec.highest(import_view.EditorView.domEventHandlers({
|
||
"keyup": this.onKeyup
|
||
}))
|
||
]);
|
||
this.registerEditorExtension(import_state.Prec.highest(import_view.keymap.of([
|
||
{
|
||
key: "Tab",
|
||
run: (view) => {
|
||
const success = this.handleTabDown(view);
|
||
return success;
|
||
}
|
||
},
|
||
{
|
||
key: "Enter",
|
||
run: (view) => {
|
||
const success = this.handleEnter(view);
|
||
return success;
|
||
}
|
||
},
|
||
{
|
||
key: "Mod-a",
|
||
run: (view) => {
|
||
const success = this.handleModAInCodeBlock(view);
|
||
return success;
|
||
}
|
||
}
|
||
])));
|
||
this.lang = window.localStorage.getItem("language");
|
||
let command_name_map = this.getCommandNameMap();
|
||
this.addCommand({
|
||
id: "easy-typing-format-article",
|
||
name: command_name_map.get("format_article"),
|
||
editorCallback: (editor, view) => {
|
||
this.formatArticle(editor, view);
|
||
},
|
||
hotkeys: [{
|
||
modifiers: ["Ctrl", "Shift"],
|
||
key: "s"
|
||
}]
|
||
});
|
||
this.addCommand({
|
||
id: "easy-typing-format-selection",
|
||
name: command_name_map.get("format_selection"),
|
||
editorCallback: (editor, view) => {
|
||
this.formatSelectionOrCurLine(editor, view);
|
||
},
|
||
hotkeys: [{
|
||
modifiers: ["Ctrl", "Shift"],
|
||
key: "l"
|
||
}]
|
||
});
|
||
this.addCommand({
|
||
id: "easy-typing-delete-blank-line",
|
||
name: command_name_map.get("delete_blank_line"),
|
||
editorCallback: (editor, view) => {
|
||
this.deleteBlankLines(editor);
|
||
},
|
||
hotkeys: [{
|
||
modifiers: ["Ctrl", "Shift"],
|
||
key: "k"
|
||
}]
|
||
});
|
||
this.addCommand({
|
||
id: "easy-typing-insert-codeblock",
|
||
name: command_name_map.get("insert_codeblock"),
|
||
editorCallback: (editor, view) => {
|
||
this.convert2CodeBlock(editor);
|
||
},
|
||
hotkeys: [{
|
||
modifiers: ["Ctrl", "Shift"],
|
||
key: "n"
|
||
}]
|
||
});
|
||
this.addCommand({
|
||
id: "easy-typing-format-switch",
|
||
name: command_name_map.get("switch_autoformat"),
|
||
callback: () => this.switchAutoFormatting(),
|
||
hotkeys: [{
|
||
modifiers: ["Ctrl"],
|
||
key: "tab"
|
||
}]
|
||
});
|
||
this.addCommand({
|
||
id: "easy-typing-paste-without-format",
|
||
name: command_name_map.get("paste_wo_format"),
|
||
editorCallback: (editor) => this.normalPaste(editor),
|
||
hotkeys: [
|
||
{
|
||
modifiers: ["Mod", "Shift"],
|
||
key: "v"
|
||
}
|
||
]
|
||
});
|
||
this.addSettingTab(new EasyTypingSettingTab(this.app, this));
|
||
this.registerEvent(this.app.workspace.on("active-leaf-change", (leaf) => {
|
||
if (leaf.view.getViewType() == "markdown") {
|
||
let file = this.app.workspace.getActiveFile();
|
||
if (file != null && this.CurActiveMarkdown != file.path) {
|
||
this.CurActiveMarkdown = file.path;
|
||
if (this.settings.debug)
|
||
new import_obsidian3.Notice("new md-file open: " + file.path);
|
||
}
|
||
}
|
||
}));
|
||
if (import_obsidian3.Platform.isMacOS && this.settings.FixMacOSContextMenu) {
|
||
this.registerEvent(this.app.workspace.on("editor-menu", (menu, editor, view) => {
|
||
if (editor.listSelections().length != 1)
|
||
return;
|
||
let selection = editor.listSelections()[0];
|
||
let selected = editor.getSelection();
|
||
if (selected == "\n") {
|
||
editor.setSelection(selection.anchor, selection.anchor);
|
||
}
|
||
}));
|
||
}
|
||
console.log("Easy Typing Plugin loaded.");
|
||
}
|
||
onunload() {
|
||
console.log("Easy Typing Plugin unloaded.");
|
||
}
|
||
async normalPaste(editor) {
|
||
let clipboardText = await navigator.clipboard.readText();
|
||
if (clipboardText === null || clipboardText === "")
|
||
return;
|
||
if (this.settings.debug)
|
||
console.log("Normal Paste!!");
|
||
const editorView = editor.cm;
|
||
let mainSelection = editorView.state.selection.asSingle().main;
|
||
editorView.dispatch({
|
||
changes: { from: mainSelection.from, to: mainSelection.to, insert: clipboardText },
|
||
selection: { anchor: mainSelection.from + clipboardText.length },
|
||
userEvent: "EasyTyping.paste"
|
||
});
|
||
}
|
||
isCurrentFileExclude() {
|
||
if (this.CurActiveMarkdown == "") {
|
||
let file = this.app.workspace.getActiveFile();
|
||
if (file != null && this.CurActiveMarkdown != file.path) {
|
||
this.CurActiveMarkdown = file.path;
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
let excludePaths = this.settings.ExcludeFiles.split("\n");
|
||
for (let epath of excludePaths) {
|
||
if (epath.charAt(0) == "/")
|
||
epath = epath.substring(1);
|
||
if (this.CurActiveMarkdown == epath)
|
||
return true;
|
||
let len = epath.length;
|
||
if (this.CurActiveMarkdown.substring(0, len) == epath && (this.CurActiveMarkdown.charAt(len) == "/" || this.CurActiveMarkdown.charAt(len) == "\\" || epath.charAt(len - 1) == "/" || epath.charAt(len - 1) == "\\")) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
switchAutoFormatting() {
|
||
this.settings.AutoFormat = !this.settings.AutoFormat;
|
||
let status = this.settings.AutoFormat ? "on" : "off";
|
||
new import_obsidian3.Notice("EasyTyping: Autoformat is " + status + "!");
|
||
}
|
||
convert2CodeBlock(editor) {
|
||
if (this.settings.debug)
|
||
console.log("----- EasyTyping: insert code block-----");
|
||
if (editor.somethingSelected && editor.getSelection() != "") {
|
||
let selected = editor.getSelection();
|
||
let selectedRange = editor.listSelections()[0];
|
||
let anchor = selectedRange.anchor;
|
||
let head = selectedRange.head;
|
||
let replacement = "```\n" + selected + "\n```";
|
||
if (anchor.line > head.line || anchor.line == head.line && anchor.ch > head.ch) {
|
||
let temp = anchor;
|
||
anchor = head;
|
||
head = temp;
|
||
}
|
||
let dstLine = anchor.line;
|
||
if (anchor.ch != 0) {
|
||
replacement = "\n" + replacement;
|
||
dstLine += 1;
|
||
}
|
||
if (head.ch != editor.getLine(head.line).length) {
|
||
replacement = replacement + "\n";
|
||
}
|
||
editor.replaceSelection(replacement);
|
||
editor.setCursor({ line: dstLine, ch: 3 });
|
||
} else {
|
||
let cs = editor.getCursor();
|
||
let replace = "```\n```";
|
||
let dstLine = cs.line;
|
||
if (cs.ch != 0) {
|
||
replace = "\n" + replace;
|
||
dstLine += 1;
|
||
}
|
||
if (cs.ch != editor.getLine(cs.line).length) {
|
||
replace = replace + "\n";
|
||
}
|
||
editor.replaceRange(replace, cs);
|
||
editor.setCursor({ line: dstLine, ch: 3 });
|
||
}
|
||
}
|
||
refreshSelectionReplaceRule() {
|
||
this.SelectionReplaceMap = new Map(this.selectionReplaceMapInitalData);
|
||
for (let i = 0; i < this.settings.userSelRepRuleTrigger.length; i++) {
|
||
let trigger = this.settings.userSelRepRuleTrigger[i];
|
||
let lefts = this.settings.userSelRepRuleValue[i].left;
|
||
let rights = this.settings.userSelRepRuleValue[i].right;
|
||
this.SelectionReplaceMap.set(trigger, { left: lefts, right: rights });
|
||
}
|
||
}
|
||
addUserSelectionRepRule(trigger, left, right) {
|
||
if (this.settings.userSelRepRuleTrigger.includes(trigger))
|
||
return false;
|
||
this.settings.userSelRepRuleTrigger.push(trigger);
|
||
this.settings.userSelRepRuleValue.push({ left, right });
|
||
this.refreshSelectionReplaceRule();
|
||
return true;
|
||
}
|
||
deleteUserSelectionRepRule(idx) {
|
||
if (idx < 0 || idx >= this.settings.userSelRepRuleTrigger.length)
|
||
return;
|
||
this.settings.userSelRepRuleTrigger.splice(idx, 1);
|
||
this.settings.userSelRepRuleValue.splice(idx, 1);
|
||
this.refreshSelectionReplaceRule();
|
||
}
|
||
updateUserSelectionRepRule(idx, left, right) {
|
||
if (idx < 0 || idx >= this.settings.userSelRepRuleTrigger.length)
|
||
return;
|
||
this.settings.userSelRepRuleValue[idx].left = left;
|
||
this.settings.userSelRepRuleValue[idx].right = right;
|
||
this.refreshSelectionReplaceRule();
|
||
}
|
||
refreshUserDeleteRule() {
|
||
this.UserDeleteRules = ruleStringList2RuleList(this.settings.userDeleteRulesStrList);
|
||
}
|
||
addUserDeleteRule(before, after) {
|
||
this.settings.userDeleteRulesStrList.push([before, after]);
|
||
this.refreshUserDeleteRule();
|
||
}
|
||
deleteUserDeleteRule(idx) {
|
||
if (idx >= this.settings.userDeleteRulesStrList.length || idx < 0)
|
||
return;
|
||
this.settings.userDeleteRulesStrList.splice(idx, 1);
|
||
this.refreshUserDeleteRule();
|
||
}
|
||
updateUserDeleteRule(idx, before, after) {
|
||
if (idx >= this.settings.userDeleteRulesStrList.length || idx < 0)
|
||
return;
|
||
this.settings.userDeleteRulesStrList[idx][0] = before;
|
||
this.settings.userDeleteRulesStrList[idx][1] = after;
|
||
this.refreshUserDeleteRule();
|
||
}
|
||
refreshUserConvertRule() {
|
||
this.UserConvertRules = ruleStringList2RuleList(this.settings.userConvertRulesStrList);
|
||
}
|
||
addUserConvertRule(before, after) {
|
||
this.settings.userConvertRulesStrList.push([before, after]);
|
||
this.refreshUserConvertRule();
|
||
}
|
||
deleteUserConvertRule(idx) {
|
||
if (idx >= this.settings.userConvertRulesStrList.length || idx < 0)
|
||
return;
|
||
this.settings.userConvertRulesStrList.splice(idx, 1);
|
||
this.refreshUserConvertRule();
|
||
}
|
||
getCommandNameMap() {
|
||
const lang = window.localStorage.getItem("language");
|
||
let command_name_map_en = /* @__PURE__ */ new Map([
|
||
["format_article", "Format current article"],
|
||
["format_selection", "Format selected text or current line"],
|
||
["delete_blank_line", "Delete blank lines of the selected or whole article"],
|
||
["insert_codeblock", "Insert code block w/wo selection"],
|
||
["switch_autoformat", "Switch autoformat"],
|
||
["paste_wo_format", "Paste without format"]
|
||
]);
|
||
let command_name_map_zh_TW = /* @__PURE__ */ new Map([
|
||
["format_article", "\u683C\u5F0F\u5316\u5168\u6587"],
|
||
["format_selection", "\u683C\u5F0F\u5316\u9078\u4E2D\u90E8\u5206/\u7576\u524D\u884C"],
|
||
["delete_blank_line", "\u522A\u9664\u9078\u4E2D\u90E8\u5206/\u5168\u6587\u7684\u591A\u9918\u7A7A\u767D\u884C"],
|
||
["insert_codeblock", "\u63D2\u5165\u4EE3\u78BC\u584A"],
|
||
["switch_autoformat", "\u5207\u63DB\u81EA\u52D5\u683C\u5F0F\u5316\u958B\u95DC"],
|
||
["paste_wo_format", "\u7121\u683C\u5F0F\u5316\u7C98\u8CBC"]
|
||
]);
|
||
let command_name_map_zh = /* @__PURE__ */ new Map([
|
||
["format_article", "\u683C\u5F0F\u5316\u5168\u6587"],
|
||
["format_selection", "\u683C\u5F0F\u5316\u9009\u4E2D\u90E8\u5206/\u5F53\u524D\u884C"],
|
||
["delete_blank_line", "\u522A\u9664\u9009\u4E2D\u90E8\u5206/\u5168\u6587\u7684\u591A\u4F59\u7A7A\u767D\u884C"],
|
||
["insert_codeblock", "\u63D2\u5165\u4EE3\u7801\u5757"],
|
||
["switch_autoformat", "\u5207\u6362\u81EA\u52A8\u683C\u5F0F\u5316\u5F00\u5173"],
|
||
["paste_wo_format", "\u65E0\u683C\u5F0F\u5316\u7C98\u8D34"]
|
||
]);
|
||
let command_name_map = command_name_map_en;
|
||
if (lang == "zh") {
|
||
command_name_map = command_name_map_zh;
|
||
} else if (lang == "zh-TW") {
|
||
command_name_map = command_name_map_zh_TW;
|
||
}
|
||
return command_name_map;
|
||
}
|
||
updateUserConvertRule(idx, before, after) {
|
||
if (idx >= this.settings.userConvertRulesStrList.length || idx < 0)
|
||
return;
|
||
this.settings.userConvertRulesStrList[idx][0] = before;
|
||
this.settings.userConvertRulesStrList[idx][1] = after;
|
||
this.refreshUserConvertRule();
|
||
}
|
||
async loadSettings() {
|
||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||
}
|
||
async saveSettings() {
|
||
await this.saveData(this.settings);
|
||
}
|
||
};
|
||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL2NvcmUudHMiLCAic3JjL3V0aWxzLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvc3ludGF4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge0VkaXRvciwgTWFya2Rvd25WaWV3LCBNZW51LCBOb3RpY2UsIFBsYXRmb3JtLCBQbHVnaW4sIFdvcmtzcGFjZUxlYWZ9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB7RWRpdG9yU2VsZWN0aW9uLCBFZGl0b3JTdGF0ZSwgUHJlYywgVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uU3BlY30gZnJvbSAnQGNvZGVtaXJyb3Ivc3RhdGUnO1xuaW1wb3J0IHtDb252ZXJ0UnVsZSwgREVGQVVMVF9TRVRUSU5HUywgRWFzeVR5cGluZ1NldHRpbmdzLCBFYXN5VHlwaW5nU2V0dGluZ1RhYiwgUGFpclN0cmluZ30gZnJvbSBcIi4vc2V0dGluZ3NcIlxuaW1wb3J0IHtFZGl0b3JWaWV3LCBrZXltYXAsIFZpZXdVcGRhdGV9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHtcblx0Z2V0VHlwZVN0ck9mVHJhbnNhYyxcblx0b2Zmc2V0VG9Qb3MsXG5cdHByaW50LFxuXHRydWxlU3RyaW5nTGlzdDJSdWxlTGlzdCxcblx0c3RyaW5nMnBhaXJzdHJpbmdcbn0gZnJvbSAnLi91dGlscydcbmltcG9ydCB7Z2V0UG9zTGluZVR5cGUsIGdldFBvc0xpbmVUeXBlMiwgTGluZUZvcm1hdGVyLCBMaW5lVHlwZX0gZnJvbSAnLi9jb3JlJ1xuaW1wb3J0IHtlbnN1cmVTeW50YXhUcmVlLCBzeW50YXhUcmVlfSBmcm9tIFwiQGNvZGVtaXJyb3IvbGFuZ3VhZ2VcIjtcbmltcG9ydCB7IHNlbGVjdENvZGVCbG9ja0luUG9zLCBpc0NvZGVCbG9ja0luUG9zIH0gZnJvbSAnLi9zeW50YXgnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVhc3lUeXBpbmdQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogRWFzeVR5cGluZ1NldHRpbmdzO1xuXHRzZWxlY3Rpb25SZXBsYWNlTWFwSW5pdGFsRGF0YTogW3N0cmluZywgUGFpclN0cmluZ11bXTtcblx0U2VsZWN0aW9uUmVwbGFjZU1hcDogTWFwPHN0cmluZywgUGFpclN0cmluZz47XG5cdFN5bWJvbFBhaXJzTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuXHRoYWxmVG9GdWxsU3ltYm9sTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuXHRCYXNpY0NvbnZSdWxlczogQ29udmVydFJ1bGVbXTtcblx0RlcySFdTeW1ib2xSdWxlczogQ29udmVydFJ1bGVbXTtcblx0Rm9ybWF0ZXI6IExpbmVGb3JtYXRlcjtcblx0SW50cmluc2ljRGVsZXRlUnVsZXM6IENvbnZlcnRSdWxlW107XG5cdEludHJpbnNpY0F1dG9QYWlyUnVsZXNQYXRjaDogQ29udmVydFJ1bGVbXTtcblx0Q3VyQWN0aXZlTWFya2Rvd246IHN0cmluZztcblxuXHRVc2VyRGVsZXRlUnVsZXM6IENvbnZlcnRSdWxlW107XG5cdFVzZXJDb252ZXJ0UnVsZXM6IENvbnZlcnRSdWxlW107XG5cdGxhbmc6IHN0cmluZztcblxuXHRjb21wb3NlX2JlZ2luX3BvczogbnVtYmVyO1xuXHRjb21wb3NlX2VuZF9wb3M6IG51bWJlcjtcblx0Y29tcG9zZV9uZWVkX2hhbmRsZTogYm9vbGVhbjtcblxuXHRvbkZvcm1hdEFydGljbGU6IGJvb2xlYW47XG5cdFRhYm91dFBhaXJTdHJzOiBQYWlyU3RyaW5nW107XG5cblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblx0XHR0aGlzLnNlbGVjdGlvblJlcGxhY2VNYXBJbml0YWxEYXRhID0gW1xuXHRcdFx0W1wiXHUzMDEwXCIsIHsgbGVmdDogXCJbXCIsIHJpZ2h0OiBcIl1cIiB9XSwgW1wiXHVGRkU1XCIsIHsgbGVmdDogXCIkXCIsIHJpZ2h0OiBcIiRcIiB9XSwgW1wiXHUwMEI3XCIsIHsgbGVmdDogXCJgXCIsIHJpZ2h0OiBcImBcIiB9XSwgWydcdTAwQTUnLCB7IGxlZnQ6IFwiJFwiLCByaWdodDogXCIkXCIgfV0sXG5cdFx0XHRbXCJcdTMwMEFcIiwgeyBsZWZ0OiBcIlx1MzAwQVwiLCByaWdodDogXCJcdTMwMEJcIiB9XSwgW1wiXHUyMDFDXCIsIHsgbGVmdDogXCJcdTIwMUNcIiwgcmlnaHQ6IFwiXHUyMDFEXCIgfV0sIFtcIlx1MjAxRFwiLCB7IGxlZnQ6IFwiXHUyMDFDXCIsIHJpZ2h0OiBcIlx1MjAxRFwiIH1dLCBbXCJcdUZGMDhcIiwgeyBsZWZ0OiBcIlx1RkYwOFwiLCByaWdodDogXCJcdUZGMDlcIiB9XSxcblx0XHRcdFtcIjxcIiwgeyBsZWZ0OiBcIjxcIiwgcmlnaHQ6IFwiPlwiIH1dXG5cdFx0XTtcblx0XHR0aGlzLnJlZnJlc2hTZWxlY3Rpb25SZXBsYWNlUnVsZSgpO1xuXHRcdHRoaXMuU3ltYm9sUGFpcnNNYXAgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXHRcdGxldCBTeW1ib2xQYWlycyA9IFtcIlx1MzAxMFx1MzAxMVwiLCBcIlx1RkYwOFx1RkYwOVwiLCBcIlx1MzAwQVx1MzAwQlwiLCBcIlx1MjAxQ1x1MjAxRFwiLCBcIlx1MjAxOFx1MjAxOVwiLCBcIlx1MzAwQ1x1MzAwRFwiLCBcIlx1MzAwRVx1MzAwRlwiLCAnW10nLCAnKCknLCAne30nLCAnXCJcIicsIFwiJydcIl1cblx0XHRmb3IgKGxldCBwYWlyU3RyIG9mIFN5bWJvbFBhaXJzKSB0aGlzLlN5bWJvbFBhaXJzTWFwLnNldChwYWlyU3RyLmNoYXJBdCgwKSwgcGFpclN0ci5jaGFyQXQoMSkpO1xuXG5cdFx0dGhpcy5oYWxmVG9GdWxsU3ltYm9sTWFwID0gbmV3IE1hcChbXG5cdFx0XHRbXCIuXCIsIFwiXHUzMDAyXCJdLFxuXHRcdFx0W1wiLFwiLCBcIlx1RkYwQ1wiXSxcblx0XHRcdFsnPycsICdcdUZGMUYnXSxcblx0XHRcdFsnIScsICdcdUZGMDEnXVxuXHRcdF0pO1xuXG5cdFx0bGV0IEJhc2ljQ29udlJ1bGVTdHJpbmdMaXN0OiBBcnJheTxbc3RyaW5nLCBzdHJpbmddPiA9IFtbJ1x1MDBCN1x1MDBCN3wnLCAnYHxgJ10sIFtcIlx1RkYwMVx1MzAxMFx1MzAxMHxcdTMwMTFcIiwnIVtbfF1dJ10sWydcdUZGMDFcdTMwMTBcdTMwMTB8JywgJyFbW3xdXSddLFxuXHRcdFtcIlx1MzAxMFx1MzAxMHxcdTMwMTFcIiwgXCJbW3xdXVwiXSwgWydcdTMwMTBcdTMwMTB8JywgXCJbW3xdXVwiXSwgWydcdUZGRTVcdUZGRTV8JywgJyR8JCddLCBbJyRcdUZGRTV8JCcsIFwiJCRcXG58XFxuJCRcIl0sWydcdTAwQTVcdTAwQTV8JywnJHwkJ10sIFsnJFx1MDBBNXwkJywgXCIkJFxcbnxcXG4kJFwiXSxbXCIkJHwkXCIsIFwiJCRcXG58XFxuJCRcIl0sIFsnJCR8JywgXCIkfCRcIl0sXG5cdFx0W1wiPlx1MzAwQnxcIiwgXCI+PnxcIl0sIFsnXFxuXHUzMDBCfCcsIFwiXFxuPnxcIl0sIFtcIiBcdTMwMEJ8XCIsIFwiID58XCJdLCBbXCJcXG5cdTMwMDF8XCIsIFwiXFxuL3xcIl1dO1xuXHRcdHRoaXMuQmFzaWNDb252UnVsZXMgPSBydWxlU3RyaW5nTGlzdDJSdWxlTGlzdChCYXNpY0NvbnZSdWxlU3RyaW5nTGlzdCk7XG5cdFx0bGV0IEZXMkhXU3ltYm9sUnVsZXNTdHJMaXN0OiBBcnJheTxbc3RyaW5nLCBzdHJpbmddPiA9IFtbXCJcdTMwMDJcdTMwMDJ8XCIsIFwiLnxcIl0sIFtcIlx1RkYwMVx1RkYwMXxcIiwgXCIhfFwiXSwgW1wiXHVGRjFCXHVGRjFCfFwiLCBcIjt8XCJdLCBbXCJcdUZGMENcdUZGMEN8XCIsIFwiLHxcIl0sXG5cdFx0W1wiXHVGRjFBXHVGRjFBfFwiLCBcIjp8XCJdLCBbJ1x1RkYxRlx1RkYxRnwnLCAnP3wnXSwgWydcdUZGMDhcdUZGMDh8XHVGRjA5JywgXCIofClcIl0sIFsnXHVGRjA4XHVGRjA4fCcsICcofCknXSwgW1wiXHUyMDFDXHUyMDFDfFx1MjAxRFwiLCBcIlxcXCJ8XFxcIlwiXSwgW1wiXHUyMDFDXHUyMDFEfFx1MjAxRFwiLCBcIlxcXCJ8XFxcIlwiXSwgW1wiXHUyMDE4XHUyMDE4fFx1MjAxOVwiLCBcIid8J1wiXSwgW1wiXHUyMDE4XHUyMDE5fFx1MjAxOVwiLCBcIid8J1wiXSxcblx0XHRbXCJcdTMwMEJcdTMwMEJ8XCIsIFwiPnxcIl0sIFtcIlx1MzAwQVx1MzAwQXxcdTMwMEJcIiwgXCI8fFwiXSwgWydcdTMwMEFcdTMwMEF8JywgXCI8fFwiXV07XG5cdFx0dGhpcy5GVzJIV1N5bWJvbFJ1bGVzID0gcnVsZVN0cmluZ0xpc3QyUnVsZUxpc3QoRlcySFdTeW1ib2xSdWxlc1N0ckxpc3QpO1xuXHRcdGxldCBmdzJod19ydWxlXzA6IENvbnZlcnRSdWxlID0ge2JlZm9yZTp7bGVmdDonXHVGRjVDXHVGRjVDJywgcmlnaHQ6Jyd9LCBhZnRlcjp7bGVmdDonfCcsIHJpZ2h0OicnfX07XG5cdFx0dGhpcy5GVzJIV1N5bWJvbFJ1bGVzLnB1c2goZncyaHdfcnVsZV8wKVxuXG5cdFx0bGV0IERlbGV0ZVJ1bGVzU3RyTGlzdDogQXJyYXk8W3N0cmluZywgc3RyaW5nXT4gPSBbW1wiJHwkXCIsIFwifFwiXSwgWyc9PXw9PScsICd8J10sIFsnJCRcXG58XFxuJCQnLCBcInxcIl1dO1xuXHRcdHRoaXMuSW50cmluc2ljRGVsZXRlUnVsZXMgPSBydWxlU3RyaW5nTGlzdDJSdWxlTGlzdChEZWxldGVSdWxlc1N0ckxpc3QpO1xuXG5cdFx0bGV0IGF1dG9QYWlyUnVsZXNQYXRjaFN0ckxpc3Q6IEFycmF5PFtzdHJpbmcsIHN0cmluZ10+ID0gW1tcIlx1MzAxMFx1MzAxMXxcdTMwMTFcIiwgXCJcdTMwMTBcdTMwMTF8XCJdLCBbXCJcdUZGMDhcdUZGMDl8XHVGRjA5XCIsIFwiXHVGRjA4XHVGRjA5fFwiXSxcblx0XHRbXCI8Pnw+XCIsIFwiPD58XCJdLCBbXCJcdTMwMEFcdTMwMEJ8XHUzMDBCXCIsIFwiXHUzMDBBXHUzMDBCfFwiXSwgW1wiXHUzMDBDXHUzMDBEfFx1MzAwRFwiLCBcIlx1MzAwQ1x1MzAwRHxcIl0sIFtcIlx1MzAwRVx1MzAwRnxcdTMwMEZcIiwgXCJcdTMwMEVcdTMwMEZ8XCJdLCBbXCIoKXwpXCIsIFwiKCl8XCJdLCBbJ1tdfF0nLCAnW118J10sXG5cdFx0W1wie318fVwiLCBcInt9fFwiXSwgW1wiJyd8J1wiLCBcIicnfFwiXSwgWydcIlwifFwiJywgJ1wiXCJ8J10sXG5cdFx0XTtcblx0XHR0aGlzLkludHJpbnNpY0F1dG9QYWlyUnVsZXNQYXRjaCA9IHJ1bGVTdHJpbmdMaXN0MlJ1bGVMaXN0KGF1dG9QYWlyUnVsZXNQYXRjaFN0ckxpc3QpO1xuXG5cdFx0bGV0IFRhYm91dFBhaXJTdHJzID0gW1wiXHUzMDEwfFx1MzAxMVwiLCBcIlx1RkYwOHxcdUZGMDlcIiwgXCJcdTMwMEF8XHUzMDBCXCIsIFwiXHUyMDFDfFx1MjAxRFwiLCBcIlx1MjAxOHxcdTIwMTlcIiwgXG5cdFx0XHRcdFx0XHQgICBcIlx1MzAwQ3xcdTMwMERcIiwgXCJcdTMwMEV8XHUzMDBGXCIsIFwiJ3wnXCIsIFwiXFxcInxcXFwiXCIsIFwiJCR8JCRcIiwgJyR8JCcsICdfX3xfXycsICdffF8nLFxuXHRcdFx0XHRcdFx0XHRcIj09fD09XCIsIFwifn58fn5cIiwgXCIqKnwqKlwiLCAnKnwqJywgXCJbW3xdXVwiLCAnW3xdJyxcInt8fVwiLCBcIih8KVwiLCBcIjx8PlwiXTtcblx0XHR0aGlzLlRhYm91dFBhaXJTdHJzID0gVGFib3V0UGFpclN0cnMubWFwKChzOnN0cmluZyk9PnN0cmluZzJwYWlyc3RyaW5nKHMpKTtcblxuXHRcdHRoaXMucmVmcmVzaFVzZXJEZWxldGVSdWxlKCk7XG5cdFx0dGhpcy5yZWZyZXNoVXNlckNvbnZlcnRSdWxlKCk7XG5cblx0XHR0aGlzLkN1ckFjdGl2ZU1hcmtkb3duID0gXCJcIjtcblxuXHRcdHRoaXMuY29tcG9zZV9uZWVkX2hhbmRsZSA9IGZhbHNlO1xuXG5cdFx0dGhpcy5Gb3JtYXRlciA9IG5ldyBMaW5lRm9ybWF0ZXIoKTtcblxuXHRcdHRoaXMub25Gb3JtYXRBcnRpY2xlID0gZmFsc2U7XG5cblx0XHR0aGlzLnJlZ2lzdGVyRWRpdG9yRXh0ZW5zaW9uKFtcblx0XHRcdEVkaXRvclN0YXRlLnRyYW5zYWN0aW9uRmlsdGVyLm9mKHRoaXMudHJhbnNhY3Rpb25GaWx0ZXJQbHVnaW4pLFxuXHRcdFx0RWRpdG9yVmlldy51cGRhdGVMaXN0ZW5lci5vZih0aGlzLnZpZXdVcGRhdGVQbHVnaW4pLFxuXHRcdFx0UHJlYy5oaWdoZXN0KEVkaXRvclZpZXcuZG9tRXZlbnRIYW5kbGVycyh7XG5cdFx0XHRcdFwia2V5dXBcIjogdGhpcy5vbktleXVwXG5cdFx0XHR9KSlcblx0XHRdKTtcblxuXG5cdFx0dGhpcy5yZWdpc3RlckVkaXRvckV4dGVuc2lvbihQcmVjLmhpZ2hlc3Qoa2V5bWFwLm9mKFtcblx0XHRcdHtcblx0XHRcdFx0a2V5OiBcIlRhYlwiLFxuXHRcdFx0XHRydW46ICh2aWV3OiBFZGl0b3JWaWV3KTogYm9vbGVhbiA9PiB7XG5cdFx0XHRcdFx0Y29uc3Qgc3VjY2VzcyA9IHRoaXMuaGFuZGxlVGFiRG93bih2aWV3KTtcblx0XHRcdFx0XHRyZXR1cm4gc3VjY2Vzcztcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0a2V5OiBcIkVudGVyXCIsXG5cdFx0XHRcdHJ1bjogKHZpZXc6IEVkaXRvclZpZXcpOiBib29sZWFuID0+IHtcblx0XHRcdFx0XHRjb25zdCBzdWNjZXNzID0gdGhpcy5oYW5kbGVFbnRlcih2aWV3KTtcblx0XHRcdFx0XHRyZXR1cm4gc3VjY2Vzcztcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0a2V5OiBcIk1vZC1hXCIsIFxuXHRcdFx0XHRydW46ICh2aWV3OiBFZGl0b3JWaWV3KTogYm9vbGVhbiA9PiB7XG5cdFx0XHRcdFx0Y29uc3Qgc3VjY2VzcyA9IHRoaXMuaGFuZGxlTW9kQUluQ29kZUJsb2NrKHZpZXcpO1xuXHRcdFx0XHRcdHJldHVybiBzdWNjZXNzO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XSkpKTtcblxuXHRcdHRoaXMubGFuZyA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbGFuZ3VhZ2UnKTtcblx0XHRsZXQgY29tbWFuZF9uYW1lX21hcCA9IHRoaXMuZ2V0Q29tbWFuZE5hbWVNYXAoKTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJlYXN5LXR5cGluZy1mb3JtYXQtYXJ0aWNsZVwiLFxuXHRcdFx0bmFtZTogY29tbWFuZF9uYW1lX21hcC5nZXQoXCJmb3JtYXRfYXJ0aWNsZVwiKSxcblx0XHRcdGVkaXRvckNhbGxiYWNrOiAoZWRpdG9yOiBFZGl0b3IsIHZpZXc6IE1hcmtkb3duVmlldykgPT4ge1xuXHRcdFx0XHR0aGlzLmZvcm1hdEFydGljbGUoZWRpdG9yLCB2aWV3KTtcblx0XHRcdH0sXG5cdFx0XHRob3RrZXlzOiBbe1xuXHRcdFx0XHRtb2RpZmllcnM6IFsnQ3RybCcsICdTaGlmdCddLFxuXHRcdFx0XHRrZXk6IFwic1wiXG5cdFx0XHR9XSxcblx0XHR9KTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJlYXN5LXR5cGluZy1mb3JtYXQtc2VsZWN0aW9uXCIsXG5cdFx0XHRuYW1lOiBjb21tYW5kX25hbWVfbWFwLmdldChcImZvcm1hdF9zZWxlY3Rpb25cIiksXG5cdFx0XHRlZGl0b3JDYWxsYmFjazogKGVkaXRvcjogRWRpdG9yLCB2aWV3OiBNYXJrZG93blZpZXcpID0+IHtcblx0XHRcdFx0dGhpcy5mb3JtYXRTZWxlY3Rpb25PckN1ckxpbmUoZWRpdG9yLCB2aWV3KTtcblx0XHRcdH0sXG5cdFx0XHRob3RrZXlzOiBbe1xuXHRcdFx0XHRtb2RpZmllcnM6IFsnQ3RybCcsICdTaGlmdCddLFxuXHRcdFx0XHRrZXk6IFwibFwiXG5cdFx0XHR9XSxcblx0XHR9KTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJlYXN5LXR5cGluZy1kZWxldGUtYmxhbmstbGluZVwiLFxuXHRcdFx0bmFtZTogY29tbWFuZF9uYW1lX21hcC5nZXQoXCJkZWxldGVfYmxhbmtfbGluZVwiKSxcblx0XHRcdGVkaXRvckNhbGxiYWNrOiAoZWRpdG9yOiBFZGl0b3IsIHZpZXc6IE1hcmtkb3duVmlldykgPT4ge1xuXHRcdFx0XHR0aGlzLmRlbGV0ZUJsYW5rTGluZXMoZWRpdG9yKTtcblx0XHRcdH0sXG5cdFx0XHRob3RrZXlzOiBbe1xuXHRcdFx0XHRtb2RpZmllcnM6IFsnQ3RybCcsICdTaGlmdCddLFxuXHRcdFx0XHRrZXk6IFwia1wiXG5cdFx0XHR9XSxcblx0XHR9KTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJlYXN5LXR5cGluZy1pbnNlcnQtY29kZWJsb2NrXCIsXG5cdFx0XHRuYW1lOiBjb21tYW5kX25hbWVfbWFwLmdldChcImluc2VydF9jb2RlYmxvY2tcIiksXG5cdFx0XHRlZGl0b3JDYWxsYmFjazogKGVkaXRvcjogRWRpdG9yLCB2aWV3OiBNYXJrZG93blZpZXcpID0+IHtcblx0XHRcdFx0dGhpcy5jb252ZXJ0MkNvZGVCbG9jayhlZGl0b3IpO1xuXHRcdFx0fSxcblx0XHRcdGhvdGtleXM6IFt7XG5cdFx0XHRcdG1vZGlmaWVyczogWydDdHJsJywgJ1NoaWZ0J10sXG5cdFx0XHRcdGtleTogXCJuXCJcblx0XHRcdH1dLFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiBcImVhc3ktdHlwaW5nLWZvcm1hdC1zd2l0Y2hcIixcblx0XHRcdG5hbWU6IGNvbW1hbmRfbmFtZV9tYXAuZ2V0KFwic3dpdGNoX2F1dG9mb3JtYXRcIiksXG5cdFx0XHRjYWxsYmFjazogKCkgPT4gdGhpcy5zd2l0Y2hBdXRvRm9ybWF0dGluZygpLFxuXHRcdFx0aG90a2V5czogW3tcblx0XHRcdFx0bW9kaWZpZXJzOiBbJ0N0cmwnXSxcblx0XHRcdFx0a2V5OiBcInRhYlwiXG5cdFx0XHR9XSxcblx0XHR9KTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJlYXN5LXR5cGluZy1wYXN0ZS13aXRob3V0LWZvcm1hdFwiLFxuXHRcdFx0bmFtZTogY29tbWFuZF9uYW1lX21hcC5nZXQoXCJwYXN0ZV93b19mb3JtYXRcIiksXG5cdFx0XHRlZGl0b3JDYWxsYmFjazogKGVkaXRvcikgPT4gdGhpcy5ub3JtYWxQYXN0ZShlZGl0b3IpLFxuXHRcdFx0aG90a2V5czogW1xuXHRcdFx0ICB7XG5cdFx0XHRcdG1vZGlmaWVyczogW1wiTW9kXCIsIFwiU2hpZnRcIl0sXG5cdFx0XHRcdGtleTogXCJ2XCIsXG5cdFx0XHQgIH0sXG5cdFx0XHRdLFxuXHRcdCAgfSk7XG5cblx0XHQvLyBUaGlzIGFkZHMgYSBzZXR0aW5ncyB0YWIgc28gdGhlIHVzZXIgY2FuIGNvbmZpZ3VyZSB2YXJpb3VzIGFzcGVjdHMgb2YgdGhlIHBsdWdpblxuXHRcdHRoaXMuYWRkU2V0dGluZ1RhYihuZXcgRWFzeVR5cGluZ1NldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2FjdGl2ZS1sZWFmLWNoYW5nZScsIChsZWFmOiBXb3Jrc3BhY2VMZWFmKSA9PiB7XG5cdFx0XHRpZiAobGVhZi52aWV3LmdldFZpZXdUeXBlKCkgPT0gJ21hcmtkb3duJykge1xuXHRcdFx0XHRsZXQgZmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XG5cdFx0XHRcdGlmIChmaWxlICE9IG51bGwgJiYgdGhpcy5DdXJBY3RpdmVNYXJrZG93biAhPSBmaWxlLnBhdGgpIHtcblx0XHRcdFx0XHR0aGlzLkN1ckFjdGl2ZU1hcmtkb3duID0gZmlsZS5wYXRoO1xuXHRcdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLmRlYnVnKVxuXHRcdFx0XHRcdFx0bmV3IE5vdGljZSgnbmV3IG1kLWZpbGUgb3BlbjogJyArIGZpbGUucGF0aClcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pKTtcblxuXHRcdC8vXHU1MjI0XHU2NUFEXHU1RjUzXHU1MjREXHU2NjJGXHU1NDI2XHU0RTNBTUFDXHU3Q0ZCXHU3RURGXG5cdFx0aWYgKFBsYXRmb3JtLmlzTWFjT1MgJiYgdGhpcy5zZXR0aW5ncy5GaXhNYWNPU0NvbnRleHRNZW51KSB7XG5cdFx0XHQvLyBcdTY4QzBcdTZENEJcdTlGMjBcdTY4MDdcdTUzRjNcdTk1MkVcdTU0N0NcdTUxRkFcdTgzRENcdTUzNTVcdTc2ODRcdTRFOEJcdTRFRjZcblx0XHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2VkaXRvci1tZW51JywgKG1lbnU6IE1lbnUsIGVkaXRvcjogRWRpdG9yLCB2aWV3OiBNYXJrZG93blZpZXcpID0+IHtcblx0XHRcdFx0Ly8gY29uc29sZS5sb2coJ2VkaXRvci1tZW51JywgbWVudSwgZWRpdG9yLCB2aWV3KTtcblx0XHRcdFx0aWYgKGVkaXRvci5saXN0U2VsZWN0aW9ucygpLmxlbmd0aCAhPSAxKSByZXR1cm47XG5cdFx0XHRcdGxldCBzZWxlY3Rpb24gPSBlZGl0b3IubGlzdFNlbGVjdGlvbnMoKVswXTtcblx0XHRcdFx0bGV0IHNlbGVjdGVkID0gZWRpdG9yLmdldFNlbGVjdGlvbigpO1xuXHRcdFx0XHQvLyBjb25zb2xlLmxvZygnc2VsZWN0ZWQnLCBzZWxlY3RlZCwgc2VsZWN0ZWQ9PSdcXG4nKTtcblx0XHRcdFx0Ly8gY29uc29sZS5sb2coJ3NlbGVjdGlvbicsIHNlbGVjdGlvbik7XG5cdFx0XHRcdGlmIChzZWxlY3RlZD09J1xcbicpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRlZGl0b3Iuc2V0U2VsZWN0aW9uKHNlbGVjdGlvbi5hbmNob3IsIHNlbGVjdGlvbi5hbmNob3IpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KSk7XG5cdFx0fVxuXG5cdFx0Ly8gdGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLndvcmtzcGFjZS5vbignZmlsZS1vcGVuJywgKGZpbGU6IFRGaWxlIHwgbnVsbCkgPT4ge1xuXHRcdC8vIFx0aWYgKGZpbGUgIT0gbnVsbCkge1xuXHRcdC8vIFx0XHRsZXQgZWRpdG9yID0gdGhpcy5nZXRFZGl0b3IoKTtcblx0XHQvLyBcdFx0aWYgKGVkaXRvciA9PT0gbnVsbCkgcmV0dXJuO1xuXHRcdC8vIFx0XHR0aGlzLkNvbnRlbnRQYXJzZXIucGFyc2VOZXdBcnRpY2xlKGVkaXRvci5nZXRWYWx1ZSgpKTtcblx0XHQvLyBcdFx0aWYgKHRoaXMuc2V0dGluZ3MuZGVidWcpIHtcblx0XHQvLyBcdFx0XHRuZXcgTm90aWNlKFwiRWFzeVR5cGluZzogUGFyc2UgTmV3IEFydGljbGU6IFwiICsgZmlsZS52YXVsdC5nZXROYW1lKCkgKyAnLycgKyBmaWxlLnBhdGgpO1xuXHRcdC8vIFx0XHRcdC8vIGlmICh0aGlzLnNldHRpbmdzLmRlYnVnKSB0aGlzLkNvbnRlbnRQYXJzZXIucHJpbnQoKTtcblx0XHQvLyBcdFx0fVxuXHRcdC8vIFx0fVxuXHRcdC8vIH0pKTtcblx0XHRjb25zb2xlLmxvZyhcIkVhc3kgVHlwaW5nIFBsdWdpbiBsb2FkZWQuXCIpXG5cdH1cblxuXHRvbnVubG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZyhcIkVhc3kgVHlwaW5nIFBsdWdpbiB1bmxvYWRlZC5cIilcblx0fVxuXG5cdGdldERlZmF1bHRJbmRlbnRDaGFyID0gKCkgPT4ge1xuXHRcdGxldCBkZWZhdWx0X2luZGVudCA9IHRoaXMuYXBwLnZhdWx0LmNvbmZpZy51c2VUYWIgPyAnXFx0JyA6ICcgJy5yZXBlYXQodGhpcy5hcHAudmF1bHQuY29uZmlnLnRhYlNpemUpO1xuXHRcdHJldHVybiBkZWZhdWx0X2luZGVudDtcblx0fVxuXG5cdHRyYW5zYWN0aW9uRmlsdGVyUGx1Z2luID0gKHRyOiBUcmFuc2FjdGlvbik6IFRyYW5zYWN0aW9uU3BlYyB8IHJlYWRvbmx5IFRyYW5zYWN0aW9uU3BlY1tdID0+IHtcblx0XHRjb25zdCBjaGFuZ2VzOiBUcmFuc2FjdGlvblNwZWNbXSA9IFtdO1xuXHRcdGlmICghdHIuZG9jQ2hhbmdlZCkgcmV0dXJuIHRyO1xuXHRcdGxldCBzZWxlY3RlZCA9IHRyLnN0YXJ0U3RhdGUuc2VsZWN0aW9uLmFzU2luZ2xlKCkubWFpbi5hbmNob3IgIT0gdHIuc3RhcnRTdGF0ZS5zZWxlY3Rpb24uYXNTaW5nbGUoKS5tYWluLmhlYWQ7XG5cblx0XHRsZXQgY2hhbmdlVHlwZVN0ciA9IGdldFR5cGVTdHJPZlRyYW5zYWModHIpO1xuXG5cdFx0dHIuY2hhbmdlcy5pdGVyQ2hhbmdlcygoZnJvbUEsIHRvQSwgZnJvbUIsIHRvQiwgaW5zZXJ0ZWQpID0+IHtcblx0XHRcdGxldCBjaGFuZ2VkU3RyID0gdHIuc3RhcnRTdGF0ZS5zbGljZURvYyhmcm9tQSwgdG9BKTtcblx0XHRcdGxldCBjaGFuZ2VzdHJfID0gY2hhbmdlZFN0ci5yZXBsYWNlKC9cXHMvZywgJzAnKVxuXHRcdFx0bGV0IGluc2VydGVkU3RyID0gaW5zZXJ0ZWQuc2xpY2VTdHJpbmcoMCk7XG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5kZWJ1Zylcblx0XHRcdHtcblx0XHRcdFx0Y29uc29sZS5sb2coXCJbVHJhbnNhY3Rpb25GaWx0ZXJdIHR5cGUsIGZyb21BLCB0b0EsIGNoYW5nZWQsIGZyb21CLCB0b0IsIGluc2VydGVkXCIpO1xuXHRcdFx0XHRjb25zb2xlLmxvZyhjaGFuZ2VUeXBlU3RyLCBmcm9tQSwgdG9BLCBjaGFuZ2VkU3RyLGZyb21CLCB0b0IsIGluc2VydGVkU3RyKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gXHU4ODY4XHU2ODNDXHU3RjE2XHU4RjkxXHU2NUY2XHU3NkY0XHU2M0E1XHU4RkQ0XHU1NkRFXHVGRjBDXHU4OUUzXHU1MUIzXHU4ODY4XHU2ODNDXHU1MTg1XHU1QkI5XHU3RjE2XHU4RjkxXHU2NzA5XHU2NUY2XHU1MDE5XHU0RjFBXHU4REYzXHU1MUZBXHU4MDVBXHU3MTI2XHU3MkI2XHU2MDAxXHU3Njg0IEJ1Z1xuXHRcdFx0aWYgKGdldFBvc0xpbmVUeXBlKHRyLnN0YXJ0U3RhdGUsIGZyb21BKT09TGluZVR5cGUudGFibGUpIHJldHVybiB0cjtcblxuXHRcdFx0Ly8gPT09PT09PT09PSBTZWxlY3Rpb24gUmVwbGFjZSA9PT09PT09PT09PT1cblx0XHRcdGlmICh0aGlzLnNldHRpbmdzLlNlbGVjdGlvbkVuaGFuY2UpIHtcblx0XHRcdFx0aWYgKChjaGFuZ2VUeXBlU3RyID09ICdpbnB1dC50eXBlJyB8fCBjaGFuZ2VUeXBlU3RyID09IFwiaW5wdXQudHlwZS5jb21wb3NlXCIpICYmIGZyb21BICE9IHRvQSAmJiAoKGZyb21CICsgMSA9PT0gdG9CKXx8aW5zZXJ0ZWRTdHI9PSdcdTIwMTRcdTIwMTQnfHxpbnNlcnRlZFN0cj09J1x1MjAyNlx1MjAyNicpKSB7XG5cdFx0XHRcdFx0aWYgKHRoaXMuU2VsZWN0aW9uUmVwbGFjZU1hcC5oYXMoaW5zZXJ0ZWRTdHIpKSB7XG5cdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goeyBjaGFuZ2VzOiB7IGZyb206IGZyb21BLCBpbnNlcnQ6IHRoaXMuU2VsZWN0aW9uUmVwbGFjZU1hcC5nZXQoaW5zZXJ0ZWRTdHIpPy5sZWZ0IH0sIHVzZXJFdmVudDogXCJFYXN5VHlwaW5nLmNoYW5nZVwiIH0pXG5cdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goeyBjaGFuZ2VzOiB7IGZyb206IHRvQSwgaW5zZXJ0OiB0aGlzLlNlbGVjdGlvblJlcGxhY2VNYXAuZ2V0KGluc2VydGVkU3RyKT8ucmlnaHQgfSwgdXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCIgfSlcblx0XHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFx1NTcyOFx1NEVFM1x1NzgwMVx1NTc1N1x1NEUyRFx1N0M5OFx1OEQzNFx1NjVGNlx1NjY3QVx1ODBGRFx1NkRGQlx1NTJBMFx1N0YyOVx1OEZEQlxuXHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQmV0dGVyQ29kZUVkaXQgJiYgY2hhbmdlVHlwZVN0ci5jb250YWlucygncGFzdGUnKSAmJiBmcm9tQT09ZnJvbUIgJiYgXG5cdFx0XHRcdFx0aXNDb2RlQmxvY2tJblBvcyh0ci5zdGFydFN0YXRlLCBmcm9tQSkpe1xuXHRcdFx0XHRwcmludChcIlx1NjhDMFx1NkQ0Qlx1NTIzMFx1NTcyOFx1NEVFM1x1NzgwMVx1NTc1N1x1NEUyRFx1N0M5OFx1OEQzNFwiKVxuXHRcdFx0XHRsZXQgbGluZSA9IHRyLnN0YXJ0U3RhdGUuZG9jLmxpbmVBdChmcm9tQikudGV4dDtcblx0XHRcdFx0bGV0IGluZGVudF9zcGFjZSA9IGxpbmUubWF0Y2goL15cXHMqLylbMF0ubGVuZ3RoO1xuXHRcdFx0XHRsZXQgaW5zZXJ0ZWRfbGluZXMgPSBpbnNlcnRlZFN0ci5zcGxpdCgnXFxuJyk7XG5cdFx0XHRcdGxldCBleHRyYV9pbmRlbnQgPSAnJztcblx0XHRcdFx0aWYoaW5zZXJ0ZWRfbGluZXMubGVuZ3RoPjEpe1xuXHRcdFx0XHRcdGxldCBmaXJzdF9saW5lID0gaW5zZXJ0ZWRfbGluZXNbMF0udHJpbVN0YXJ0KCk7XG5cdFx0XHRcdFx0aWYgKGZpcnN0X2xpbmUuZW5kc1dpdGgoJ3snKSB8fCBmaXJzdF9saW5lLmVuZHNXaXRoKCcoJykgfHwgZmlyc3RfbGluZS5lbmRzV2l0aCgnWycpKXtcblx0XHRcdFx0XHRcdGV4dHJhX2luZGVudCA9IHRoaXMuZ2V0RGVmYXVsdEluZGVudENoYXIoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bGV0IHJlc3RfbGluZXMgPSBpbnNlcnRlZF9saW5lcy5zbGljZSgxKTtcblx0XHRcdFx0XHQvLyBmaW5kIHRoZSBtaW5pbXVtIGluZGVudCBzcGFjZSBpbiByZXN0IGxpbmVzXG5cdFx0XHRcdFx0bGV0IG1pbl9pbmRlbnRfc3BhY2UgPSBJbmZpbml0eTtcblx0XHRcdFx0XHRmb3IgKGxldCBsaW5lIG9mIHJlc3RfbGluZXMpe1xuXHRcdFx0XHRcdFx0bGV0IGluZGVudCA9IGxpbmUubWF0Y2goL15cXHMqLylbMF0ubGVuZ3RoO1xuXHRcdFx0XHRcdFx0aWYgKCEvXlxccyokLy50ZXN0KGxpbmUpICYmIGluZGVudDxtaW5faW5kZW50X3NwYWNlKSBtaW5faW5kZW50X3NwYWNlID0gaW5kZW50O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRsZXQgbmV3X3Jlc3RfbGluZXMgPSByZXN0X2xpbmVzLm1hcCgobGluZTpzdHJpbmcpPT5saW5lLnN1YnN0cmluZyhtaW5faW5kZW50X3NwYWNlKSk7XG5cdFx0XHRcdFx0XG5cdFx0XHRcdFx0bmV3X3Jlc3RfbGluZXMgPSBuZXdfcmVzdF9saW5lcy5tYXAoXG5cdFx0XHRcdFx0XHQobGluZTpzdHJpbmcpPT5saW5lLnJlcGxhY2UoL1tcXHRdL2csIHRoaXMuZ2V0RGVmYXVsdEluZGVudENoYXIoKSkpO1xuXHRcdFx0XHRcdGxldCBmaW5hbF9yZXN0X2xpbmVzID0gbmV3X3Jlc3RfbGluZXMubWFwKChsaW5lOnN0cmluZyk9PicgJy5yZXBlYXQoaW5kZW50X3NwYWNlKStleHRyYV9pbmRlbnQrbGluZSk7XG5cdFx0XHRcdFx0bGV0IG5ld19pbnNlcnRlZFN0ciA9IGZpcnN0X2xpbmUrJ1xcbicrZmluYWxfcmVzdF9saW5lcy5qb2luKCdcXG4nKTtcblx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0Y2hhbmdlczoge2Zyb206IGZyb21BLCB0bzogdG9BLCBpbnNlcnQ6IG5ld19pbnNlcnRlZFN0cn0sXG5cdFx0XHRcdFx0XHRzZWxlY3Rpb246IHthbmNob3I6IGZyb21BK25ld19pbnNlcnRlZFN0ci5sZW5ndGh9LFxuXHRcdFx0XHRcdFx0dXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCJcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdHJldHVybiB0cjtcblx0XHRcdFx0fVx0XHRcdFx0XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzZWxlY3RlZCkgcmV0dXJuIHRyO1xuXG5cdFx0XHQvLyBsZXQgdGVzdF9zID0gXCJcdTAwQTVcIlxuXHRcdFx0Ly8gY29uc29sZS5sb2coICdcdTAwQTUnLCB0ZXN0X3MgPT0gJ1x1RkZFNScpXG5cblx0XHRcdC8vIFx1NUMxRFx1OEJENVx1ODlFM1x1NTFCM1x1NUZBRVx1OEY2Rlx1NjVFN1x1NzI0OFx1OEY5M1x1NTE2NVx1NkNENVx1NzY4NFx1OTVFRVx1OTg5OH5cblx0XHRcdGlmICh0aGlzLnNldHRpbmdzLlRyeUZpeE1TSU1FICYmIFxuXHRcdFx0XHRjaGFuZ2VUeXBlU3RyID09IFwiaW5wdXQudHlwZS5jb21wb3NlXCIgJiYgXG5cdFx0XHRcdGNoYW5nZWRTdHIgPT0gJycgJiYgL15bXFx1NGUwMC1cXHU5ZmE1XSskLy50ZXN0KGluc2VydGVkU3RyKSl7XG5cdFx0XHRcdHByaW50KFwiTVMtSU1FIENvbXBvc2UgZGV0ZWN0ZWQ6XCIsIGluc2VydGVkU3RyKTtcblx0XHRcdFx0dHIgPSB0ci5zdGFydFN0YXRlLnVwZGF0ZSguLi5jaGFuZ2VzKTtcblx0XHRcdFx0cmV0dXJuIHRyO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBcdTUyMTdcdTg4NjhcdTRFMEJcdTc2ODRcdTRFRTNcdTc4MDFcdTU3NTdcdTUyMjBcdTk2NjRcdTUyOUZcdTgwRkRcdTRGMThcdTUzMTZcblx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkJldHRlckNvZGVFZGl0ICYmIGNoYW5nZVR5cGVTdHIgPT0gXCJkZWxldGUuYmFja3dhcmRcIiAmJiAhc2VsZWN0ZWQgJiYgXG5cdFx0XHRcdGdldFBvc0xpbmVUeXBlKHRyLnN0YXJ0U3RhdGUsIHRvQSkgPT0gTGluZVR5cGUuY29kZWJsb2NrICYmIFxuXHRcdFx0XHQodHIuc3RhcnRTdGF0ZS5zbGljZURvYyhmcm9tQSx0b0EpIT0nYCcgfHwgZ2V0UG9zTGluZVR5cGUodHIuc3RhdGUsIGZyb21BKT09TGluZVR5cGUuY29kZWJsb2NrKSkge1xuXHRcdFx0XHRsZXQgbGluZV9udW1iZXIgPSB0ci5zdGFydFN0YXRlLmRvYy5saW5lQXQodG9BKS5udW1iZXI7XG5cdFx0XHRcdGxldCBjdXJfbGluZSA9IHRyLnN0YXJ0U3RhdGUuZG9jLmxpbmVBdCh0b0EpO1xuXHRcdFx0XHRsZXQgbGlzdF9jb2RlID0gZmFsc2U7XG5cdFx0XHRcdGxldCBsaXN0X2NvZGVfaW5kZW50ID0gMDtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IGxpbmVfbnVtYmVyIC0gMTsgaSA+PSAxOyBpLS0pIHtcblx0XHRcdFx0XHRsZXQgbGluZSA9IHRyLnN0YXJ0U3RhdGUuZG9jLmxpbmUoaSk7XG5cdFx0XHRcdFx0aWYgKC9eXFxzK2BgYC8udGVzdChsaW5lLnRleHQpKSB7XG5cdFx0XHRcdFx0XHRsaXN0X2NvZGUgPSB0cnVlO1xuXHRcdFx0XHRcdFx0bGlzdF9jb2RlX2luZGVudCA9IGxpbmUudGV4dC5tYXRjaCgvXlxccyovKVswXS5sZW5ndGg7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSBpZiAoL15gYGAvLnRlc3QobGluZS50ZXh0KSkgYnJlYWs7XG5cdFx0XHRcdFx0ZWxzZSBjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChsaXN0X2NvZGUpIHtcblx0XHRcdFx0XHRwcmludCgnbGlzdF9jb2RlLCBpbmRlbnQ6ICcsIGxpc3RfY29kZV9pbmRlbnQpO1xuXHRcdFx0XHRcdGlmICh0b0EgPT0gY3VyX2xpbmUuZnJvbSArIGxpc3RfY29kZV9pbmRlbnQpIHtcblx0XHRcdFx0XHRcdGNoYW5nZXMucHVzaCh7IGNoYW5nZXM6IHsgZnJvbTogdHIuc3RhcnRTdGF0ZS5kb2MubGluZShsaW5lX251bWJlci0xKS50bywgdG86IHRvQSwgaW5zZXJ0OiAnJyB9LCB1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIiB9KTtcblx0XHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChmcm9tQT49Y3VyX2xpbmUuZnJvbSAmJiBmcm9tQSA8IGN1cl9saW5lLmZyb20rbGlzdF9jb2RlX2luZGVudCAmJiB0b0E+Y3VyX2xpbmUuZnJvbStsaXN0X2NvZGVfaW5kZW50KXtcblx0XHRcdFx0XHRcdGNoYW5nZXMucHVzaCh7IGNoYW5nZXM6IHsgZnJvbTogY3VyX2xpbmUuZnJvbStsaXN0X2NvZGVfaW5kZW50LCB0bzogdG9BLCBpbnNlcnQ6ICcnIH0sIHVzZXJFdmVudDogXCJFYXN5VHlwaW5nLmNoYW5nZVwiIH0pO1xuXHRcdFx0XHRcdFx0dHIgPSB0ci5zdGFydFN0YXRlLnVwZGF0ZSguLi5jaGFuZ2VzKTtcblx0XHRcdFx0XHRcdHJldHVybiB0cjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVXNlckRlZmluZWQgRGVsZXRlIFJ1bGVcblx0XHRcdGlmIChjaGFuZ2VUeXBlU3RyID09IFwiZGVsZXRlLmJhY2t3YXJkXCIpIHtcblx0XHRcdFx0Zm9yIChsZXQgcnVsZSBvZiB0aGlzLlVzZXJEZWxldGVSdWxlcykge1xuXHRcdFx0XHRcdGxldCBsZWZ0ID0gdHIuc3RhcnRTdGF0ZS5kb2Muc2xpY2VTdHJpbmcodG9BIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGgsIHRvQSk7XG5cdFx0XHRcdFx0bGV0IHJpZ2h0ID0gdHIuc3RhcnRTdGF0ZS5kb2Muc2xpY2VTdHJpbmcodG9BLCB0b0EgKyBydWxlLmJlZm9yZS5yaWdodC5sZW5ndGgpO1xuXHRcdFx0XHRcdGlmIChsZWZ0ID09PSBydWxlLmJlZm9yZS5sZWZ0ICYmIHJpZ2h0ID09PSBydWxlLmJlZm9yZS5yaWdodCkge1xuXHRcdFx0XHRcdFx0Y2hhbmdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdFx0Y2hhbmdlczoge1xuXHRcdFx0XHRcdFx0XHRcdGZyb206IHRvQSAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XHRcdHRvOiB0b0EgKyBydWxlLmJlZm9yZS5yaWdodC5sZW5ndGgsXG5cdFx0XHRcdFx0XHRcdFx0aW5zZXJ0OiBydWxlLmFmdGVyLmxlZnQgKyBydWxlLmFmdGVyLnJpZ2h0XG5cdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdHNlbGVjdGlvbjogeyBhbmNob3I6IHRvQSAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoICsgcnVsZS5hZnRlci5sZWZ0Lmxlbmd0aCB9LFxuXHRcdFx0XHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRyO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyA9PT09PT09PT09IGRlbGV0ZSBwYWlyIHN5bWJvbCA9PT09PT09PT09PT1cblx0XHRcdGlmIChjaGFuZ2VUeXBlU3RyID09PSBcImRlbGV0ZS5iYWNrd2FyZFwiICYmIHRoaXMuc2V0dGluZ3MuSW50cmluc2ljU3ltYm9sUGFpcnMpIHtcblx0XHRcdFx0aWYgKHRoaXMuU3ltYm9sUGFpcnNNYXAuaGFzKGNoYW5nZWRTdHIpICYmIHRoaXMuU3ltYm9sUGFpcnNNYXAuZ2V0KGNoYW5nZWRTdHIpID09PSB0ci5zdGFydFN0YXRlLnNsaWNlRG9jKHRvQSwgdG9BICsgMSkpIHtcblx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goeyBjaGFuZ2VzOiB7IGZyb206IGZyb21BLCB0bzogdG9BICsgMSB9LCB1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIiB9KTtcblx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdHJldHVybiB0cjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFx1NTkwNFx1NzQwNlx1NTIyMFx1OTY2NFx1NEVFM1x1NzgwMVx1NTc1N1xuXHRcdFx0XHRsZXQgbGluZV9jb250ZW50ID0gdHIuc3RhcnRTdGF0ZS5kb2MubGluZUF0KHRvQSkudGV4dDtcblx0XHRcdFx0bGV0IG5leHRfbGluZV9jb250ZW50ID0gdHIuc3RhcnRTdGF0ZS5kb2Muc2xpY2VTdHJpbmcodG9BLCB0b0EgKyBsaW5lX2NvbnRlbnQubGVuZ3RoKzEpO1xuXHRcdFx0XHRpZiAoL15cXHMqYGBgJC8udGVzdChsaW5lX2NvbnRlbnQpICYmICdcXG4nK2xpbmVfY29udGVudD09bmV4dF9saW5lX2NvbnRlbnQpIHtcblx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0Y2hhbmdlczp7XG5cdFx0XHRcdFx0XHRcdGZyb206IHRvQS0zLCBcblx0XHRcdFx0XHRcdFx0dG86IHRvQStsaW5lX2NvbnRlbnQubGVuZ3RoKzEsXG5cdFx0XHRcdFx0XHRcdGluc2VydDogJydcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRzZWxlY3Rpb246IHsgYW5jaG9yOiB0b0EgLSAzIH0sXG5cdFx0XHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0cmV0dXJuIHRyO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Zm9yIChsZXQgcnVsZSBvZiB0aGlzLkludHJpbnNpY0RlbGV0ZVJ1bGVzKSB7XG5cdFx0XHRcdFx0bGV0IGxlZnQgPSB0ci5zdGFydFN0YXRlLmRvYy5zbGljZVN0cmluZyh0b0EgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCwgdG9BKTtcblx0XHRcdFx0XHRsZXQgcmlnaHQgPSB0ci5zdGFydFN0YXRlLmRvYy5zbGljZVN0cmluZyh0b0EsIHRvQSArIHJ1bGUuYmVmb3JlLnJpZ2h0Lmxlbmd0aCk7XG5cdFx0XHRcdFx0aWYgKGxlZnQgPT09IHJ1bGUuYmVmb3JlLmxlZnQgJiYgcmlnaHQgPT09IHJ1bGUuYmVmb3JlLnJpZ2h0KSB7XG5cdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0XHRcdFx0ZnJvbTogdG9BIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGgsXG5cdFx0XHRcdFx0XHRcdFx0dG86IHRvQSArIHJ1bGUuYmVmb3JlLnJpZ2h0Lmxlbmd0aCxcblx0XHRcdFx0XHRcdFx0XHRpbnNlcnQ6IHJ1bGUuYWZ0ZXIubGVmdCArIHJ1bGUuYWZ0ZXIucmlnaHRcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogdG9BIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGggKyBydWxlLmFmdGVyLmxlZnQubGVuZ3RoIH0sXG5cdFx0XHRcdFx0XHRcdHVzZXJFdmVudDogXCJFYXN5VHlwaW5nLmNoYW5nZVwiXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFx1NTkwNFx1NzQwNlx1ODJGMVx1NjU4N1x1OEY5M1x1NTE2NVx1NkNENVx1NEUwQlx1OEY5M1x1NTE2NVx1NEVFM1x1NzgwMVx1NTc1N1xuXHRcdFx0aWYgKGNoYW5nZVR5cGVTdHIgPT0gJ2lucHV0LnR5cGUnICYmIGluc2VydGVkU3RyID09J2BcXG5gYGAnICYmIHRoaXMuc2V0dGluZ3MuQmFzZU9iRWRpdEVuaGFuY2Upe1xuXHRcdFx0XHRjb25zdCBsaW5lX2NvbnRlbnQgPSB0ci5zdGFydFN0YXRlLmRvYy5saW5lQXQoZnJvbUEpLnRleHQ7XG5cdFx0XHRcdGlmICgvXlxccypgYCQvLnRlc3QobGluZV9jb250ZW50KSl7XG5cdFx0XHRcdFx0Y2hhbmdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdGNoYW5nZXM6IHtmcm9tOiBmcm9tQSwgdG86IHRvQSwgaW5zZXJ0OiAnYFxcbicrbGluZV9jb250ZW50KydgJ30sXG5cdFx0XHRcdFx0XHRzZWxlY3Rpb246IHsgYW5jaG9yOiBmcm9tQSArIDEgfSxcblx0XHRcdFx0XHRcdHVzZXJFdmVudDogXCJFYXN5VHlwaW5nLmNoYW5nZVwiXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0dHIgPSB0ci5zdGFydFN0YXRlLnVwZGF0ZSguLi5jaGFuZ2VzKTtcblx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0Ly8gXHU5MDFBXHU1RTM4XHU1MzU1XHU1QjU3XHU4RjkzXHU1MTY1XG5cdFx0XHRpZiAoKGNoYW5nZVR5cGVTdHIgPT0gJ2lucHV0LnR5cGUnIHx8IGNoYW5nZVR5cGVTdHIgPT0gXCJpbnB1dC50eXBlLmNvbXBvc2VcIikgJiYgZnJvbUEgPT09IHRvQSAmJiBmcm9tQiArIDEgPT09IHRvQikge1xuXHRcdFx0XHQvLyBpZiAodGhpcy5zZXR0aW5ncy5kZWJ1ZykgY29uc29sZS5sb2coXCJJbnB1dC50eXBlID0+IFwiLCBpbnNlcnRlZFN0cilcblx0XHRcdFx0Ly8gPT09PT09PT09PT0gYmFzaWMgY29udmVydCBydWxlcyA9PT09PT09PT09PT1cblx0XHRcdFx0Ly8gbm90IHN1cHBvcnQgdW5kbyBhbmQgcmVkb1xuXHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5CYXNlT2JFZGl0RW5oYW5jZSkge1xuXHRcdFx0XHRcdC8vIFx1NTkwNFx1NzQwNlx1ODJGMVx1NjU4N1x1NjgwN1x1NzBCOVx1NEUwQmBgfFx1NzY4NFx1NjBDNVx1NTFCNVx1RkYwQ1x1NTE0OVx1NjgwN1x1ODFFQVx1NTJBOFx1OERGM1x1OEY2Q1x1NTIzMFx1NEUyRFx1OTVGNFxuXHRcdFx0XHRcdGlmIChpbnNlcnRlZFN0ciA9PT0gJ2AnICYmIFxuXHRcdFx0XHRcdFx0dG9BLXRyLnN0YXJ0U3RhdGUuZG9jLmxpbmVBdCh0b0EpLmZyb20+MiAmJiBcblx0XHRcdFx0XHRcdHRyLnN0YXJ0U3RhdGUuc2xpY2VEb2ModG9BLTEsIHRvQSkgPT09ICdgJ1xuXHRcdFx0XHRcdFx0JiYgdHIuc3RhcnRTdGF0ZS5zbGljZURvYyh0b0EtMiwgdG9BLTEpICE9ICdgJyl7XG5cdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRjaGFuZ2VzOiB7ZnJvbTp0b0EsIGluc2VydDonYCd9LFxuXHRcdFx0XHRcdFx0XHRzZWxlY3Rpb246IHsgYW5jaG9yOiB0b0EgfSwgdXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCIgXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gXHU1OTA0XHU3NDA2XHU0RTJEXHU2NTg3XHU4RjkzXHU1MTY1XHU2Q0Q1XHU0RTBCXHU4RjkzXHU1MTY1XHU0RUUzXHU3ODAxXHU1NzU3XG5cdFx0XHRcdFx0aWYgKGluc2VydGVkU3RyID09ICdcdTAwQjcnKXtcblx0XHRcdFx0XHRcdGxldCBsaW5lX2NvbnRlbnQgPSB0ci5zdGFydFN0YXRlLmRvYy5saW5lQXQoZnJvbUEpLnRleHQ7XG5cdFx0XHRcdFx0XHRsZXQgY2hfcG9zID0gZnJvbUEgLSB0ci5zdGFydFN0YXRlLmRvYy5saW5lQXQoZnJvbUEpLmZyb207XG5cdFx0XHRcdFx0XHRpZiAoL15cXHMqYGAkLy50ZXN0KGxpbmVfY29udGVudCkgJiYgY2hfcG9zPT1saW5lX2NvbnRlbnQubGVuZ3RoLTEpe1xuXHRcdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRcdGNoYW5nZXM6IHtmcm9tOiBmcm9tQSsxLCB0bzogdG9BKzEsIGluc2VydDogJ2BcXG4nK2xpbmVfY29udGVudCsnYCd9LFxuXHRcdFx0XHRcdFx0XHRcdHNlbGVjdGlvbjogeyBhbmNob3I6IGZyb21BICsgMiB9LFxuXHRcdFx0XHRcdFx0XHRcdHVzZXJFdmVudDogXCJFYXN5VHlwaW5nLmNoYW5nZVwiXG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Zm9yIChsZXQgcnVsZSBvZiB0aGlzLkJhc2ljQ29udlJ1bGVzKSB7XG5cdFx0XHRcdFx0XHRpZiAoaW5zZXJ0ZWRTdHIgIT0gcnVsZS5iZWZvcmUubGVmdC5jaGFyQXQocnVsZS5iZWZvcmUubGVmdC5sZW5ndGggLSAxKSkgY29udGludWU7XG5cdFx0XHRcdFx0XHQvLyBcdTU5MDRcdTc0MDZcdTY1ODdcdTY4NjNcdTdCMkMgMCBcdTg4NENcblx0XHRcdFx0XHRcdGlmIChydWxlLmJlZm9yZS5sZWZ0LmNoYXJBdCgwKSA9PT0gJ1xcbicgJiYgb2Zmc2V0VG9Qb3ModHIuc3RhdGUuZG9jLCBmcm9tQSkubGluZSA9PT0gMCAmJiB0b0IgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCArIDEgPT09IDApIHtcblx0XHRcdFx0XHRcdFx0bGV0IGxlZnQgPSB0ci5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcodG9CIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGggKyAxLCB0b0IpO1xuXHRcdFx0XHRcdFx0XHRsZXQgcmlnaHQgPSB0ci5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcodG9CLCB0b0IgKyBydWxlLmJlZm9yZS5yaWdodC5sZW5ndGgpO1xuXHRcdFx0XHRcdFx0XHRpZiAobGVmdCA9PT0gcnVsZS5iZWZvcmUubGVmdC5zdWJzdHJpbmcoMSkgJiYgcmlnaHQgPT09IHJ1bGUuYmVmb3JlLnJpZ2h0KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y2hhbmdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdFx0XHRcdGNoYW5nZXM6IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZnJvbTogdG9BIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGggKyAyLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bzogdG9BICsgcnVsZS5iZWZvcmUucmlnaHQubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpbnNlcnQ6IHJ1bGUuYWZ0ZXIubGVmdC5zdWJzdHJpbmcoMSkgKyBydWxlLmFmdGVyLnJpZ2h0XG5cdFx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogdG9BIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGggKyBydWxlLmFmdGVyLmxlZnQubGVuZ3RoICsgMSB9LFxuXHRcdFx0XHRcdFx0XHRcdFx0dXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCJcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gXHU5MDFBXHU1RTM4XHU2MEM1XHU1MUI1XHU1OTA0XHU3NDA2XG5cdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0bGV0IGxlZnQgPSB0ci5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcodG9CIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGgsIHRvQik7XG5cdFx0XHRcdFx0XHRcdGxldCByaWdodCA9IHRyLnN0YXRlLmRvYy5zbGljZVN0cmluZyh0b0IsIHRvQiArIHJ1bGUuYmVmb3JlLnJpZ2h0Lmxlbmd0aCk7XG5cdFx0XHRcdFx0XHRcdGlmIChsZWZ0ID09PSBydWxlLmJlZm9yZS5sZWZ0ICYmIHJpZ2h0ID09PSBydWxlLmJlZm9yZS5yaWdodCkge1xuXHRcdFx0XHRcdFx0XHRcdGNoYW5nZXMucHVzaCh7XG5cdFx0XHRcdFx0XHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGZyb206IHRvQSAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoICsgMSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0dG86IHRvQSArIHJ1bGUuYmVmb3JlLnJpZ2h0Lmxlbmd0aCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0aW5zZXJ0OiBydWxlLmFmdGVyLmxlZnQgKyBydWxlLmFmdGVyLnJpZ2h0XG5cdFx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogdG9BIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGggKyBydWxlLmFmdGVyLmxlZnQubGVuZ3RoICsgMSB9LFxuXHRcdFx0XHRcdFx0XHRcdFx0dXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCJcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkZXMkhXRW5oYW5jZSkge1xuXHRcdFx0XHRcdGZvciAobGV0IHJ1bGUgb2YgdGhpcy5GVzJIV1N5bWJvbFJ1bGVzKSB7XG5cdFx0XHRcdFx0XHRpZiAoaW5zZXJ0ZWRTdHIgIT0gcnVsZS5iZWZvcmUubGVmdC5jaGFyQXQocnVsZS5iZWZvcmUubGVmdC5sZW5ndGggLSAxKSkgY29udGludWU7XG5cdFx0XHRcdFx0XHRsZXQgbGVmdCA9IHRyLnN0YXRlLmRvYy5zbGljZVN0cmluZyh0b0IgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCwgdG9CKTtcblx0XHRcdFx0XHRcdGxldCByaWdodCA9IHRyLnN0YXRlLmRvYy5zbGljZVN0cmluZyh0b0IsIHRvQiArIHJ1bGUuYmVmb3JlLnJpZ2h0Lmxlbmd0aCk7XG5cdFx0XHRcdFx0XHRpZiAobGVmdCA9PT0gcnVsZS5iZWZvcmUubGVmdCAmJiByaWdodCA9PT0gcnVsZS5iZWZvcmUucmlnaHQpIHtcblx0XHRcdFx0XHRcdFx0Y2hhbmdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRmcm9tOiB0b0EgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCArIDEsXG5cdFx0XHRcdFx0XHRcdFx0XHR0bzogdG9BICsgcnVsZS5iZWZvcmUucmlnaHQubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XHRcdFx0aW5zZXJ0OiBydWxlLmFmdGVyLmxlZnQgKyBydWxlLmFmdGVyLnJpZ2h0XG5cdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRzZWxlY3Rpb246IHsgYW5jaG9yOiB0b0EgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCArIHJ1bGUuYWZ0ZXIubGVmdC5sZW5ndGggKyAxIH0sXG5cdFx0XHRcdFx0XHRcdFx0dXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCJcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cjtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyA9PT09PT09PT09PT09PT09IGF1dG8gcGFpciA9PT09PT09PT09PT09PT09PVxuXHRcdFx0XHQvLyBsZXQgUGFpclZhbGlkU2V0ID0gbmV3IFNldChbXCJcIiwgXCIgXCIsXCJcXG5cIl0pXG5cdFx0XHRcdC8vIGxldCBjaGFyQWZ0ZXJDdXJzb3IgPSB0ci5zdGFydFN0YXRlLnNsaWNlRG9jKHRvQSwgdG9BKzEpO1xuXHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5JbnRyaW5zaWNTeW1ib2xQYWlycykge1xuXHRcdFx0XHRcdGZvciAobGV0IHJ1bGUgb2YgdGhpcy5JbnRyaW5zaWNBdXRvUGFpclJ1bGVzUGF0Y2gpIHtcblx0XHRcdFx0XHRcdGlmIChpbnNlcnRlZFN0ciAhPSBydWxlLmJlZm9yZS5sZWZ0LmNoYXJBdChydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCAtIDEpKSBjb250aW51ZTtcblx0XHRcdFx0XHRcdGxldCBsZWZ0ID0gdHIuc3RhdGUuZG9jLnNsaWNlU3RyaW5nKHRvQiAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoLCB0b0IpO1xuXHRcdFx0XHRcdFx0bGV0IHJpZ2h0ID0gdHIuc3RhdGUuZG9jLnNsaWNlU3RyaW5nKHRvQiwgdG9CICsgcnVsZS5iZWZvcmUucmlnaHQubGVuZ3RoKTtcblx0XHRcdFx0XHRcdGlmIChsZWZ0ID09PSBydWxlLmJlZm9yZS5sZWZ0ICYmIHJpZ2h0ID09PSBydWxlLmJlZm9yZS5yaWdodCkge1xuXHRcdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRcdGNoYW5nZXM6IHtcblx0XHRcdFx0XHRcdFx0XHRcdGZyb206IHRvQSAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoICsgMSxcblx0XHRcdFx0XHRcdFx0XHRcdHRvOiB0b0EgKyBydWxlLmJlZm9yZS5yaWdodC5sZW5ndGgsXG5cdFx0XHRcdFx0XHRcdFx0XHRpbnNlcnQ6IHJ1bGUuYWZ0ZXIubGVmdCArIHJ1bGUuYWZ0ZXIucmlnaHRcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdHNlbGVjdGlvbjogeyBhbmNob3I6IHRvQSAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoICsgcnVsZS5hZnRlci5sZWZ0Lmxlbmd0aCArIDEgfSxcblx0XHRcdFx0XHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0dHIgPSB0ci5zdGFydFN0YXRlLnVwZGF0ZSguLi5jaGFuZ2VzKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRyO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICh0aGlzLlN5bWJvbFBhaXJzTWFwLmhhcyhpbnNlcnRlZFN0cikgJiYgaW5zZXJ0ZWRTdHIhPVwiJ1wiKSB7XG5cdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRjaGFuZ2VzOiB7IGZyb206IGZyb21BLCB0bzogdG9BLCBpbnNlcnQ6IGluc2VydGVkU3RyICsgdGhpcy5TeW1ib2xQYWlyc01hcC5nZXQoaW5zZXJ0ZWRTdHIpIH0sXG5cdFx0XHRcdFx0XHRcdHNlbGVjdGlvbjogeyBhbmNob3I6IGZyb21BICsgMSB9LFxuXHRcdFx0XHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR0ciA9IHRyLnN0YXJ0U3RhdGUudXBkYXRlKC4uLmNoYW5nZXMpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRyO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIGlmIChpbnNlcnRlZFN0ciA9PT0gXCInXCIpIHtcblx0XHRcdFx0XHRcdGxldCBjaGFyQmVmb3JlQ3Vyc29yID0gdHIuc3RhcnRTdGF0ZS5zbGljZURvYyhmcm9tQSAtIDEsIGZyb21BKTtcblx0XHRcdFx0XHRcdGlmIChbJycsICcgJywgJ1xcbiddLmluY2x1ZGVzKGNoYXJCZWZvcmVDdXJzb3IpKSB7XG5cdFx0XHRcdFx0XHRcdGNoYW5nZXMucHVzaCh7XG5cdFx0XHRcdFx0XHRcdFx0Y2hhbmdlczogeyBmcm9tOiBmcm9tQSwgdG86IHRvQSwgaW5zZXJ0OiBcIicnXCIgfSxcblx0XHRcdFx0XHRcdFx0XHRzZWxlY3Rpb246IHsgYW5jaG9yOiBmcm9tQSArIDEgfSxcblx0XHRcdFx0XHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0dHIgPSB0ci5zdGFydFN0YXRlLnVwZGF0ZSguLi5jaGFuZ2VzKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRyO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIGhhbmRsZSBhdXRvcGFpciBmb3IgXCJcdTIwMURcIiBhbmQgXCJcdTIwMTlcIlxuXHRcdFx0XHRcdGlmIChpbnNlcnRlZFN0ciA9PT0gJ1x1MjAxRCcgfHwgaW5zZXJ0ZWRTdHIgPT09ICdcdTIwMTknKSB7XG5cdFx0XHRcdFx0XHRsZXQgdGVtcFN0ciA9IGluc2VydGVkU3RyID09PSBcIlx1MjAxRFwiID8gXCJcdTIwMUNcdTIwMURcIiA6IFwiXHUyMDE4XHUyMDE5XCI7XG5cdFx0XHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRjaGFuZ2VzOiB7IGZyb206IGZyb21BLCB0bzogdG9BLCBpbnNlcnQ6IHRlbXBTdHIgfSxcblx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogZnJvbUEgKyAxIH0sXG5cdFx0XHRcdFx0XHRcdHVzZXJFdmVudDogXCJFYXN5VHlwaW5nLmNoYW5nZVwiXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdHRyID0gdHIuc3RhcnRTdGF0ZS51cGRhdGUoLi4uY2hhbmdlcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSlcblx0XHRyZXR1cm4gdHI7XG5cdH1cblxuXHRhc3luYyBub3JtYWxQYXN0ZShlZGl0b3I6IEVkaXRvcik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGxldCBjbGlwYm9hcmRUZXh0ID0gYXdhaXQgbmF2aWdhdG9yLmNsaXBib2FyZC5yZWFkVGV4dCgpO1xuXHRcdGlmIChjbGlwYm9hcmRUZXh0ID09PSBudWxsIHx8IGNsaXBib2FyZFRleHQgPT09IFwiXCIpIHJldHVybjtcblxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmRlYnVnKSBjb25zb2xlLmxvZyhcIk5vcm1hbCBQYXN0ZSEhXCIpXG5cdFx0Y29uc3QgZWRpdG9yVmlldyA9IGVkaXRvci5jbSBhcyBFZGl0b3JWaWV3O1xuXHRcdGxldCBtYWluU2VsZWN0aW9uID0gZWRpdG9yVmlldy5zdGF0ZS5zZWxlY3Rpb24uYXNTaW5nbGUoKS5tYWluO1xuXHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0Y2hhbmdlczogeyBmcm9tOiBtYWluU2VsZWN0aW9uLmZyb20sIHRvOiBtYWluU2VsZWN0aW9uLnRvLCBpbnNlcnQ6IGNsaXBib2FyZFRleHQgfSxcblx0XHRcdHNlbGVjdGlvbjoge2FuY2hvcjogbWFpblNlbGVjdGlvbi5mcm9tICsgY2xpcGJvYXJkVGV4dC5sZW5ndGh9LFxuXHRcdFx0dXNlckV2ZW50OiBcIkVhc3lUeXBpbmcucGFzdGVcIlxuXHRcdH0pO1xuXHR9XG5cblx0dmlld1VwZGF0ZVBsdWdpbiA9ICh1cGRhdGU6IFZpZXdVcGRhdGUpID0+IHtcblx0XHRpZiAodGhpcy5vbkZvcm1hdEFydGljbGUgPT09IHRydWUpIHJldHVybjtcblxuXHRcdGxldCBub3RTZWxlY3RlZCA9IHRydWU7XG5cdFx0bGV0IG1haW5TZWxlY3Rpb24gPSB1cGRhdGUudmlldy5zdGF0ZS5zZWxlY3Rpb24uYXNTaW5nbGUoKS5tYWluO1xuXHRcdGlmIChtYWluU2VsZWN0aW9uLmFuY2hvciAhPSBtYWluU2VsZWN0aW9uLmhlYWQpIG5vdFNlbGVjdGVkID0gZmFsc2U7XG5cdFx0aWYgKCF1cGRhdGUuZG9jQ2hhbmdlZCkgcmV0dXJuO1xuXG5cdFx0bGV0IGlzRXhjbHVkZUZpbGUgPSB0aGlzLmlzQ3VycmVudEZpbGVFeGNsdWRlKCk7XG5cdFx0Ly8gY29uc29sZS5sb2codGhpcy5DdXJBY3RpdmVNYXJrZG93biwgaXNFeGNsdWRlRmlsZSlcblxuXHRcdC8vIGlmICh0aGlzLnNldHRpbmdzLmRlYnVnKSBjb25zb2xlLmxvZyhcIi0tLS0tVmlld1VwZGF0ZUNoYW5nZS0tLS0tXCIpO1xuXHRcdGxldCB0ciA9IHVwZGF0ZS50cmFuc2FjdGlvbnNbMF1cblx0XHRsZXQgY2hhbmdlVHlwZSA9IGdldFR5cGVTdHJPZlRyYW5zYWModHIpO1xuXG5cdFx0dHIuY2hhbmdlcy5pdGVyQ2hhbmdlcygoZnJvbUEsIHRvQSwgZnJvbUIsIHRvQiwgaW5zZXJ0ZWQpID0+IHtcblx0XHRcdGxldCBpbnNlcnRlZFN0ciA9IGluc2VydGVkLnNsaWNlU3RyaW5nKDApO1xuXHRcdFx0bGV0IGNoYW5nZWRTdHIgPSB0ci5zdGFydFN0YXRlLmRvYy5zbGljZVN0cmluZyhmcm9tQSwgdG9BKTtcblx0XHRcdGlmICh0aGlzLnNldHRpbmdzLmRlYnVnKXtcblx0XHRcdFx0Y29uc29sZS5sb2coXCJbVmlld1VwZGF0ZV0gdHlwZSwgZnJvbUEsIHRvQSwgY2hhbmdlZCwgZnJvbUIsIHRvQiwgaW5zZXJ0ZWRcIik7XG5cdFx0XHRcdGNvbnNvbGUubG9nKGNoYW5nZVR5cGUsIGZyb21BLCB0b0EsIGNoYW5nZWRTdHIsIGZyb21CLCB0b0IsIGluc2VydGVkU3RyKVxuXHRcdFx0XHRjb25zb2xlLmxvZyhcIj09PltDb21wb3NpbmddXCIsIHVwZGF0ZS52aWV3LmNvbXBvc2luZylcblx0XHRcdH1cblxuXHRcdFx0Ly8gdGFibGUgXHU1MTg1XHU5MEU4XHU0RTBEXHU1MDVBXHU1OTA0XHU3NDA2XHVGRjBDXHU3NkY0XHU2M0E1XHU4RkQ0XHU1NkRFID0+IFx1OTE0RFx1NTQwOCBPYnNpZGlhbiBcdTc2ODRcdTY3M0FcdTUyMzZcblx0XHRcdGlmIChnZXRQb3NMaW5lVHlwZSh1cGRhdGUudmlldy5zdGF0ZSwgZnJvbUIpID09IExpbmVUeXBlLnRhYmxlKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0bGV0IGN1cnNvciA9IHVwZGF0ZS52aWV3LnN0YXRlLnNlbGVjdGlvbi5hc1NpbmdsZSgpLm1haW47XG5cblx0XHRcdGlmICh1cGRhdGUudmlldy5jb21wb3Npbmcpe1xuXHRcdFx0XHRpZiAodGhpcy5jb21wb3NlX25lZWRfaGFuZGxlKXtcblx0XHRcdFx0XHR0aGlzLmNvbXBvc2VfZW5kX3BvcyA9IGN1cnNvci5hbmNob3I7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZXtcblx0XHRcdFx0XHR0aGlzLmNvbXBvc2VfbmVlZF9oYW5kbGUgPSB0cnVlO1xuXHRcdFx0XHRcdHRoaXMuY29tcG9zZV9iZWdpbl9wb3MgPSBmcm9tQTtcblx0XHRcdFx0XHR0aGlzLmNvbXBvc2VfZW5kX3BvcyA9IGN1cnNvci5hbmNob3I7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgY2hhbmdlX2Zyb20gPSBmcm9tQjtcblx0XHRcdGxldCBjaGFuZ2VfdG8gPSB0b0I7XG5cdFx0XHRsZXQgY29tcG9zZUVuZCA9IGZhbHNlO1xuXHRcdFx0aWYgKHRoaXMuY29tcG9zZV9uZWVkX2hhbmRsZSl7XG5cdFx0XHRcdGNvbXBvc2VFbmQgPSB0cnVlO1xuXHRcdFx0XHR0aGlzLmNvbXBvc2VfbmVlZF9oYW5kbGUgPSBmYWxzZTtcblx0XHRcdFx0Y2hhbmdlX2Zyb20gPSB0aGlzLmNvbXBvc2VfYmVnaW5fcG9zO1xuXHRcdFx0XHRjaGFuZ2VfdG8gPSB0aGlzLmNvbXBvc2VfZW5kX3Bvcztcblx0XHRcdH1cblxuXHRcdFx0aWYgKGNoYW5nZVR5cGUuY29udGFpbnMoJ0Vhc3lUeXBpbmcnKSB8fCBjaGFuZ2VUeXBlPT0ndW5kbycgfHwgY2hhbmdlVHlwZT09J3JlZG8nKSByZXR1cm47XG5cdFx0XHQvLyBcdTUyMjRcdTY1QURcdTZCQ0ZcdTZCMjFcdThGOTNcdTUxNjVcdTdFRDNcdTY3NUZcblx0XHRcdGlmIChjaGFuZ2VUeXBlICE9ICdub25lJyAmJiBub3RTZWxlY3RlZCAmJiAhY2hhbmdlVHlwZS5pbmNsdWRlcygnZGVsZXRlJykpIHtcblx0XHRcdFx0Ly8gXHU3NTI4XHU2MjM3XHU4MUVBXHU1QjlBXHU0RTQ5XHU4RjZDXHU1MzE2XHU4OUM0XHU1MjE5XG5cdFx0XHRcdGlmICh0aGlzLnRyaWdnZXJVc2VyQ3Z0UnVsZSh1cGRhdGUudmlldywgbWFpblNlbGVjdGlvbi5hbmNob3IpKSByZXR1cm47XG5cdFx0XHRcdGlmIChjb21wb3NlRW5kICYmIHRoaXMudHJpZ2dlclB1bmNSZWN0aWZ5KHVwZGF0ZS52aWV3LCBjaGFuZ2VfZnJvbSkpIHJldHVybjtcblxuXHRcdFx0XHQvLyBcdTUyMjRcdTY1QURcdTY4M0NcdTVGMEZcdTUzMTZcdTY1ODdcdTY3MkNcblx0XHRcdFx0Ly8gY29uc29sZS5sb2coXCJyZWFkeSB0byBmb3JtYXRcIik7XG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKFwiY2hlY2sgaXMgZXhjbHVlIGZpbGU6XCIsIGlzRXhjbHVkZUZpbGUpXG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkF1dG9Gb3JtYXQgJiYgbm90U2VsZWN0ZWQgJiYgIWlzRXhjbHVkZUZpbGUgJiZcblx0XHRcdFx0XHQgKGNoYW5nZVR5cGUgIT0gJ25vbmUnIHx8IGluc2VydGVkU3RyPT1cIlxcblwiKSkge1xuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdGlmIChnZXRQb3NMaW5lVHlwZSh1cGRhdGUudmlldy5zdGF0ZSwgY2hhbmdlX2Zyb20pID09IExpbmVUeXBlLnRleHQgfHwgZ2V0UG9zTGluZVR5cGUodXBkYXRlLnZpZXcuc3RhdGUsIGNoYW5nZV9mcm9tKSA9PSBMaW5lVHlwZS50YWJsZSl7XG5cdFx0XHRcdFx0XHRsZXQgY2hhbmdlcyA9IHRoaXMuRm9ybWF0ZXIuZm9ybWF0TGluZU9mRG9jKHVwZGF0ZS5zdGF0ZSwgdGhpcy5zZXR0aW5ncywgY2hhbmdlX2Zyb20sIGN1cnNvci5hbmNob3IsIGluc2VydGVkU3RyKTtcblx0XHRcdFx0XHRcdGlmIChjaGFuZ2VzICE9IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0dXBkYXRlLnZpZXcuZGlzcGF0Y2goLi4uY2hhbmdlc1swXSk7XG5cdFx0XHRcdFx0XHRcdHVwZGF0ZS52aWV3LmRpc3BhdGNoKGNoYW5nZXNbMV0pO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFx1N0M5OFx1OEQzNFx1NjVGNlx1ODFFQVx1NTJBOFx1NjgzQ1x1NUYwRlx1NTMxNlxuXHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQXV0b0Zvcm1hdCAmJiAhaXNFeGNsdWRlRmlsZSAmJiBjaGFuZ2VUeXBlID09IFwiaW5wdXQucGFzdGVcIiAmJiAhUGxhdGZvcm0uaXNJb3NBcHApIHtcblx0XHRcdFx0bGV0IHVwZGF0ZUxpbmVTdGFydCA9IHVwZGF0ZS5zdGF0ZS5kb2MubGluZUF0KGZyb21CKS5udW1iZXI7XG5cdFx0XHRcdGxldCB1cGRhdGVMaW5lRW5kID0gdXBkYXRlLnN0YXRlLmRvYy5saW5lQXQodG9CKS5udW1iZXI7XG5cdFx0XHRcdGlmICh1cGRhdGVMaW5lU3RhcnQgPT0gdXBkYXRlTGluZUVuZCAmJiBnZXRQb3NMaW5lVHlwZSh1cGRhdGUudmlldy5zdGF0ZSwgdG9CKSA9PSBMaW5lVHlwZS50ZXh0KSB7XG5cdFx0XHRcdFx0bGV0IGNoYW5nZXMgPSB0aGlzLkZvcm1hdGVyLmZvcm1hdExpbmVPZkRvYyh1cGRhdGUuc3RhdGUsIHRoaXMuc2V0dGluZ3MsIGZyb21CLCB0b0IsIGluc2VydGVkU3RyKTtcblx0XHRcdFx0XHRpZiAoY2hhbmdlcyAhPSBudWxsKSB7XG5cdFx0XHRcdFx0XHR1cGRhdGUudmlldy5kaXNwYXRjaCguLi5jaGFuZ2VzWzBdKTtcblx0XHRcdFx0XHRcdC8vIHVwZGF0ZS52aWV3LmRpc3BhdGNoKGNoYW5nZXNbMV0pO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRsZXQgYWxsX2NoYW5nZXM6IFRyYW5zYWN0aW9uU3BlY1tdID0gW107XG5cdFx0XHRcdFx0bGV0IGluc2VydGVkX2FycmF5ID0gaW5zZXJ0ZWRTdHIuc3BsaXQoXCJcXG5cIik7XG5cdFx0XHRcdFx0bGV0IHVwZGF0ZV9zdGFydCA9IGZyb21CXG5cdFx0XHRcdFx0Zm9yIChsZXQgaSA9IHVwZGF0ZUxpbmVTdGFydDsgaSA8PSB1cGRhdGVMaW5lRW5kOyBpKyspIHtcblx0XHRcdFx0XHRcdGxldCByZWFsX2luc2VydGVkID0gaW5zZXJ0ZWRfYXJyYXlbaSAtIHVwZGF0ZUxpbmVTdGFydF07XG5cdFx0XHRcdFx0XHQvLyBjb25zb2xlLmxvZygncmVhbF9pbnNlcnRlZCcsIHJlYWxfaW5zZXJ0ZWQucmVwbGFjZSgvXFxuL2csICdcXFxcbicpKVxuXHRcdFx0XHRcdFx0Ly8gY29uc29sZS5sb2coJ3VwZGF0ZV9kb2NfdGV4dCcsIHVwZGF0ZS5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcodXBkYXRlX3N0YXJ0LCB1cGRhdGVfc3RhcnQgKyByZWFsX2luc2VydGVkLmxlbmd0aCkucmVwbGFjZSgvXFxuL2csICdcXFxcbicpKVxuXHRcdFx0XHRcdFx0bGV0IGNoYW5nZXMgPSB0aGlzLkZvcm1hdGVyLmZvcm1hdExpbmVPZkRvYyh1cGRhdGUuc3RhdGUsIHRoaXMuc2V0dGluZ3MsIHVwZGF0ZV9zdGFydCwgdXBkYXRlX3N0YXJ0ICsgcmVhbF9pbnNlcnRlZC5sZW5ndGgsIHJlYWxfaW5zZXJ0ZWQpO1xuXHRcdFx0XHRcdFx0Ly8gY29uc29sZS5sb2coJ2NoYW5nZXMnLCBjaGFuZ2VzKVxuXHRcdFx0XHRcdFx0aWYgKGNoYW5nZXMgIT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRhbGxfY2hhbmdlcy5wdXNoKC4uLmNoYW5nZXNbMF0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0dXBkYXRlX3N0YXJ0ICs9IHJlYWxfaW5zZXJ0ZWQubGVuZ3RoICsgMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKGFsbF9jaGFuZ2VzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRcdHVwZGF0ZS52aWV3LmRpc3BhdGNoKC4uLmFsbF9jaGFuZ2VzKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcdC8vIGl0ZXJjaGFuZ2VzIGVuZFxuXHR9XG5cblx0cHJpdmF0ZSByZWFkb25seSBoYW5kbGVUYWJEb3duID0gKHZpZXc6IEVkaXRvclZpZXcpID0+IHtcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuVGFib3V0KSByZXR1cm4gZmFsc2U7XG5cblx0XHRsZXQgc3RhdGUgPSB2aWV3LnN0YXRlO1xuXHRcdGxldCBkb2MgPSBzdGF0ZS5kb2Ncblx0XHRjb25zdCB0cmVlID0gc3ludGF4VHJlZShzdGF0ZSk7XG5cdFx0Y29uc3QgcyA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuXHRcdGlmIChzLnJhbmdlcy5sZW5ndGggPiAxKSByZXR1cm4gZmFsc2U7XG5cdFx0Y29uc3QgcG9zID0gcy5tYWluLnRvO1xuXHRcdGxldCBsaW5lID0gZG9jLmxpbmVBdChwb3MpXG5cblx0XHQvLyBEZWJ1ZyBpbmZvXG5cdFx0Ly8gY29uc29sZS5sb2cobGluZS50ZXh0KVxuXHRcdC8vIGZvciAobGV0IHA9bGluZS5mcm9tOyBwPD1saW5lLnRvOyBwKz0xKXtcblx0XHQvLyBcdGNvbnN0IHRva2VuID0gdHJlZS5yZXNvbHZlKHAsIDEpLm5hbWVcblx0XHQvLyBcdGNvbnNvbGUubG9nKHAtbGluZS5mcm9tLCB0b2tlbilcblx0XHQvLyB9XG5cdFx0Ly8gcmV0dXJuIHRydWU7XG5cblx0XHRpZiAocy5tYWluLmZyb209PXMubWFpbi50byAmJiBnZXRQb3NMaW5lVHlwZSh2aWV3LnN0YXRlLCBzLm1haW4uZnJvbSkgPT0gTGluZVR5cGUuY29kZWJsb2NrKXtcblx0XHRcdHZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogcy5tYWluLmZyb20sXG5cdFx0XHRcdFx0aW5zZXJ0OiB0aGlzLmdldERlZmF1bHRJbmRlbnRDaGFyKClcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0aW9uOiB7XG5cdFx0XHRcdFx0YW5jaG9yOiBzLm1haW4uZnJvbSArIHRoaXMuZ2V0RGVmYXVsdEluZGVudENoYXIoKS5sZW5ndGhcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHQvLyByZXR1cm4gdHJ1ZTtcblxuXHRcdC8vIFx1NUY1M1x1NTE0OVx1NjgwN1x1NTcyOFx1ODg0Q1x1NTE4NVx1NEVFM1x1NzgwMVx1NTE4NVx1OTBFOFxuXHRcdGlmICh0aGlzLnNldHRpbmdzLkJldHRlckNvZGVFZGl0ICYmIHBvcyAtIGxpbmUuZnJvbSAhPSAwICYmIHRyZWUucmVzb2x2ZShwb3MgLSAxLCAxKS5uYW1lLmNvbnRhaW5zKCdpbmxpbmUtY29kZScpKSB7XG5cdFx0XHRpZiAodHJlZS5yZXNvbHZlKHBvcywgMSkubmFtZS5jb250YWlucygnZm9ybWF0dGluZy1jb2RlX2lubGluZS1jb2RlJykpIHtcblx0XHRcdFx0dmlldy5kaXNwYXRjaCh7XG5cdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogcG9zICsgMSwgaGVhZDogcG9zICsgMSB9XG5cdFx0XHRcdH0pXG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKGxldCBwID0gcG9zICsgMTsgcCA8IGxpbmUudG8gJiYgdHJlZS5yZXNvbHZlKHAsIDEpLm5hbWUuY29udGFpbnMoJ2lubGluZS1jb2RlJyk7IHAgKz0gMSkge1xuXHRcdFx0XHQvLyBcdTU5ODJcdTY3OUNcdTYyN0VcdTUyMzAgYCBcdTUyMTlcdTUxNDlcdTY4MDdcdThERjNcdTUyMzBcdTUxNzZcdTU0MEVcblx0XHRcdFx0aWYgKHRyZWUucmVzb2x2ZShwLCAxKS5uYW1lLmNvbnRhaW5zKCdmb3JtYXR0aW5nLWNvZGVfaW5saW5lLWNvZGUnKSkge1xuXHRcdFx0XHRcdHZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogcCwgaGVhZDogcCB9XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBcdTU5ODJcdTY3OUNcdTZDQTFcdTYyN0VcdTUyMzAgYCBcdTUyMTlcdTc2RjRcdTYzQTVcdThERjNcdTUyMzBcdTg4NENcdTVDM0Vcblx0XHRcdFx0aWYgKHAgPT0gbGluZS50byAtIDEgJiYgdHJlZS5yZXNvbHZlKHAsIDEpLm5hbWUuY29udGFpbnMoJ2lubGluZS1jb2RlJykpIHtcblx0XHRcdFx0XHR2aWV3LmRpc3BhdGNoKHtcblx0XHRcdFx0XHRcdHNlbGVjdGlvbjogeyBhbmNob3I6IHAgKyAxLCBoZWFkOiBwICsgMSB9XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFx1NUY1M1x1NTE0OVx1NjgwN1x1NTcyOFx1ODg0Q1x1NTE4NVx1NEVFM1x1NzgwMVx1NTkxNlx1OTBFOFx1RkYwQ1x1NUU3Nlx1NTcyOFx1OTAwOVx1NEUyRFx1NjU4N1x1NjcyQ1x1NzY4NFx1NjBDNVx1NTFCNVx1NEUwQlx1RkYwQ3RhYlx1NUMwNlx1NEYxQVx1OERGM1x1NTFGQVx1NTIzMHBhaXJzdHJpbmdcdTc2ODRcdTU5MTZcdTkwRThcblx0XHRsZXQgc2VsZWN0aW9uID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24uYXNTaW5nbGUoKS5tYWluO1xuXHRcdGxldCBzZWxlY3RlZCA9IHNlbGVjdGlvbi5hbmNob3IgIT0gc2VsZWN0aW9uLmhlYWQ7XG5cdFx0aWYgKHNlbGVjdGVkKXtcblx0XHRcdGxldCBuZXdfYW5jaG9yID0gc2VsZWN0aW9uLmFuY2hvcjxzZWxlY3Rpb24uaGVhZD9zZWxlY3Rpb24uYW5jaG9yOnNlbGVjdGlvbi5oZWFkO1xuXHRcdFx0bGV0IG5ld19oZWFkID0gc2VsZWN0aW9uLmFuY2hvcj5zZWxlY3Rpb24uaGVhZD9zZWxlY3Rpb24uYW5jaG9yOnNlbGVjdGlvbi5oZWFkO1xuXHRcdFx0Ly8gY29uc29sZS5sb2coXCJzZWxlY3Rpb25cIiwgc2VsZWN0aW9uLmFuY2hvciwgc2VsZWN0aW9uLmhlYWQpXG5cblx0XHRcdGZvciAobGV0IHBzdHIgb2YgdGhpcy5UYWJvdXRQYWlyU3Rycyl7XG5cdFx0XHRcdGlmIChkb2Muc2xpY2VTdHJpbmcobmV3X2FuY2hvci1wc3RyLmxlZnQubGVuZ3RoLCBuZXdfYW5jaG9yKSA9PSBwc3RyLmxlZnQgJiZcblx0XHRcdFx0XHRkb2Muc2xpY2VTdHJpbmcobmV3X2hlYWQsIG5ld19oZWFkK3BzdHIucmlnaHQubGVuZ3RoKSA9PSBwc3RyLnJpZ2h0KXtcblx0XHRcdFx0XHRcdHZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRcdFx0XHRzZWxlY3Rpb246IHsgYW5jaG9yOiBuZXdfaGVhZCtwc3RyLnJpZ2h0Lmxlbmd0aCwgaGVhZDogbmV3X2hlYWQrcHN0ci5yaWdodC5sZW5ndGggfVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHByaXZhdGUgcmVhZG9ubHkgaGFuZGxlRW50ZXIgPSAodmlldzogRWRpdG9yVmlldykgPT4ge1xuXHRcdC8vIGNvbnNvbGUubG9nKFwidGhpcy5zZXR0aW5ncy5FbnRlclR3aWNlXCIsIHRoaXMuc2V0dGluZ3MuRW50ZXJUd2ljZSlcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuRW50ZXJUd2ljZSkgcmV0dXJuIGZhbHNlO1xuXG5cdFx0bGV0IHN0cmljdExpbmVCcmVha3MgPSB0aGlzLmFwcC52YXVsdC5jb25maWcuc3RyaWN0TGluZUJyZWFrcyB8fCBmYWxzZTtcblx0XHRpZiAoIXN0cmljdExpbmVCcmVha3MpIHJldHVybiBmYWxzZTtcblxuXHRcdGxldCBzdGF0ZSA9IHZpZXcuc3RhdGU7XG5cdFx0bGV0IGRvYyA9IHN0YXRlLmRvY1xuXHRcdGNvbnN0IHRyZWUgPSBzeW50YXhUcmVlKHN0YXRlKTtcblx0XHRjb25zdCBzID0gdmlldy5zdGF0ZS5zZWxlY3Rpb247XG5cdFx0aWYgKHMucmFuZ2VzLmxlbmd0aCA+IDEpIHJldHVybiBmYWxzZTtcblx0XHRjb25zdCBwb3MgPSBzLm1haW4udG87XG5cdFx0bGV0IGxpbmUgPSBkb2MubGluZUF0KHBvcylcblxuXHRcdC8vIGNvbnNvbGUubG9nKGxpbmUudGV4dCwgZ2V0UG9zTGluZVR5cGUyKHN0YXRlLCBwb3MpKVxuXHRcdC8vIGZvciAobGV0IHA9bGluZS5mcm9tOyBwPD1saW5lLnRvOyBwKz0xKXtcblx0XHQvLyBcdGNvbnN0IHRva2VuID0gdHJlZS5yZXNvbHZlKHAsIDEpLm5hbWVcblx0XHQvLyBcdGNvbnNvbGUubG9nKHAtbGluZS5mcm9tLCB0b2tlbilcblx0XHQvLyB9XG5cdFx0aWYgKC9eXFxzKiQvLnRlc3QobGluZS50ZXh0KSkgcmV0dXJuIGZhbHNlO1xuXHRcdGVsc2UgaWYgKGdldFBvc0xpbmVUeXBlMihzdGF0ZSwgcG9zKSA9PSBMaW5lVHlwZS50ZXh0KSB7XG5cdFx0XHR2aWV3LmRpc3BhdGNoKHtcblx0XHRcdFx0Y2hhbmdlczoge1xuXHRcdFx0XHRcdGZyb206IHBvcyxcblx0XHRcdFx0XHR0bzogcG9zLFxuXHRcdFx0XHRcdGluc2VydDogJ1xcblxcbidcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogcG9zICsgMiB9LFxuXHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0fSlcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cblx0cHJpdmF0ZSByZWFkb25seSBoYW5kbGVNb2RBSW5Db2RlQmxvY2sgPSAodmlldzogRWRpdG9yVmlldykgPT4ge1xuXHRcdGlmICghdGhpcy5zZXR0aW5ncy5CZXR0ZXJDb2RlRWRpdCkgcmV0dXJuIGZhbHNlO1xuXHRcdGxldCBzZWxlY3RlZCA9IGZhbHNlO1xuXHRcdGxldCBtYWluU2VsZWN0aW9uID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24uYXNTaW5nbGUoKS5tYWluO1xuXHRcdGlmIChtYWluU2VsZWN0aW9uLmFuY2hvciAhPSBtYWluU2VsZWN0aW9uLmhlYWQpIHNlbGVjdGVkID0gdHJ1ZTtcblx0XHRpZiAoc2VsZWN0ZWQpIHJldHVybiBmYWxzZTtcblxuXHRcdGxldCBjdXJzb3JfcG9zID0gbWFpblNlbGVjdGlvbi5hbmNob3I7XG5cblx0XHRyZXR1cm4gc2VsZWN0Q29kZUJsb2NrSW5Qb3ModmlldywgY3Vyc29yX3Bvcyk7XG5cdH1cblxuXHRwcml2YXRlIHJlYWRvbmx5IG9uS2V5dXAgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQsIHZpZXc6IEVkaXRvclZpZXcpID0+IHtcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5kZWJ1Zykge1xuXHRcdFx0Ly8gY29uc29sZS5sb2coXCJLZXl1cDpcIiwgZXZlbnQua2V5LCBldmVudC5zaGlmdEtleSwgZXZlbnQuY3RybEtleXx8ZXZlbnQubWV0YUtleSk7XG5cdFx0XHRjb25zb2xlLmxvZyhcIktleXVwOlwiLCBldmVudC5rZXkpO1xuXHRcdH1cblx0XHR0aGlzLmhhbmRsZUVuZENvbXBvc2VUeXBlS2V5KGV2ZW50LCB2aWV3KTtcblx0fVxuXG5cdHRyaWdnZXJVc2VyQ3Z0UnVsZSA9ICh2aWV3OiBFZGl0b3JWaWV3LCBjdXJzb3JfcG9zOiBudW1iZXIpOmJvb2xlYW4gPT4ge1xuXHRcdGZvciAobGV0IHJ1bGUgb2YgdGhpcy5Vc2VyQ29udmVydFJ1bGVzKSB7XG5cdFx0XHQvLyBpZiAoaW5zZXJ0ZWRTdHIgIT0gcnVsZS5iZWZvcmUubGVmdC5zdWJzdHJpbmcocnVsZS5iZWZvcmUubGVmdC5sZW5ndGggLSBpbnNlcnRlZFN0ci5sZW5ndGgpKSBjb250aW51ZTtcblx0XHRcdGxldCBsZWZ0ID0gdmlldy5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcoY3Vyc29yX3BvcyAtIHJ1bGUuYmVmb3JlLmxlZnQubGVuZ3RoLCBjdXJzb3JfcG9zKTtcblx0XHRcdGxldCByaWdodCA9IHZpZXcuc3RhdGUuZG9jLnNsaWNlU3RyaW5nKGN1cnNvcl9wb3MsIGN1cnNvcl9wb3MgKyBydWxlLmJlZm9yZS5yaWdodC5sZW5ndGgpO1xuXHRcdFx0bGV0IGluc2VydGVkID0gcnVsZS5hZnRlci5sZWZ0ICsgcnVsZS5hZnRlci5yaWdodDtcblx0XHRcdGxldCBhbmNob3IgPSBjdXJzb3JfcG9zIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGggKyBydWxlLmFmdGVyLmxlZnQubGVuZ3RoO1xuXHRcdFx0bGV0IGZyb20gPSBjdXJzb3JfcG9zIC0gcnVsZS5iZWZvcmUubGVmdC5sZW5ndGg7XG5cdFx0XHRsZXQgdG8gPSBjdXJzb3JfcG9zICsgcnVsZS5iZWZvcmUucmlnaHQubGVuZ3RoO1xuXHRcdFx0Ly8gXHU1QkY5XHU2NTg3XHU2ODYzXHU5OTk2XHU4ODRDXHU4OUM0XHU1MjE5XHU1MDVBXHU3Mjc5XHU2QjhBXHU1OTA0XHU3NDA2XG5cdFx0XHRpZiAocnVsZS5iZWZvcmUubGVmdC5jaGFyQXQoMCkgPT09ICdcXG4nICYmIHJ1bGUuYWZ0ZXIubGVmdC5jaGFyQXQoMCkgPT09ICdcXG4nICYmXG5cdFx0XHRcdGN1cnNvcl9wb3MgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCsxPT0wKSB7XG5cdFx0XHRcdGxlZnQgPSAnXFxuJyArIGxlZnQ7XG5cdFx0XHRcdGluc2VydGVkID0gaW5zZXJ0ZWQuc3Vic3RyaW5nKDEpO1xuXHRcdFx0XHRmcm9tID0gMDtcblx0XHRcdH1cblx0XHRcdGlmIChsZWZ0ID09PSBydWxlLmJlZm9yZS5sZWZ0ICYmIHJpZ2h0ID09PSBydWxlLmJlZm9yZS5yaWdodCkge1xuXHRcdFx0XHR2aWV3LmRpc3BhdGNoKHtcblx0XHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0XHRmcm9tOiBmcm9tLFxuXHRcdFx0XHRcdFx0dG86IHRvLFxuXHRcdFx0XHRcdFx0aW5zZXJ0OiBpbnNlcnRlZFxuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0c2VsZWN0aW9uOiB7IGFuY2hvcjogYW5jaG9yIH0sXG5cdFx0XHRcdFx0dXNlckV2ZW50OiBcIkVhc3lUeXBpbmcuY2hhbmdlXCJcblx0XHRcdFx0fSlcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHRyaWdnZXJQdW5jUmVjdGlmeSA9ICh2aWV3OiBFZGl0b3JWaWV3LCBjaGFuZ2VfZnJvbV9wb3M6IG51bWJlcik6Ym9vbGVhbiA9PiB7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MuUHVuY1JlY3RpZnkgJiZcblx0XHRcdC9bLC4/IV0vLnRlc3Qodmlldy5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcoY2hhbmdlX2Zyb21fcG9zIC0gMSwgY2hhbmdlX2Zyb21fcG9zKSkpIHtcblx0XHRcdGxldCBwdW5jID0gdmlldy5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcoY2hhbmdlX2Zyb21fcG9zIC0gMSwgY2hhbmdlX2Zyb21fcG9zKVxuXHRcdFx0aWYgKGNoYW5nZV9mcm9tX3BvcyA+IDIgJiYgL1teXFx1NGUwMC1cXHU5ZmE1XS8udGVzdCh2aWV3LnN0YXRlLmRvYy5zbGljZVN0cmluZyhjaGFuZ2VfZnJvbV9wb3MgLSAyLCBjaGFuZ2VfZnJvbV9wb3MgLSAxKSkpIHsgfVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdHZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRcdGNoYW5nZXM6IHtcblx0XHRcdFx0XHRcdGZyb206IGNoYW5nZV9mcm9tX3BvcyAtIDEsXG5cdFx0XHRcdFx0XHR0bzogY2hhbmdlX2Zyb21fcG9zLFxuXHRcdFx0XHRcdFx0aW5zZXJ0OiB0aGlzLmhhbGZUb0Z1bGxTeW1ib2xNYXAuZ2V0KHB1bmMpXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHQvLyBzZWxlY3Rpb246IHsgYW5jaG9yOiB0b0IgLSBydWxlLmJlZm9yZS5sZWZ0Lmxlbmd0aCArIHJ1bGUuYWZ0ZXIubGVmdC5sZW5ndGggfSxcblx0XHRcdFx0XHR1c2VyRXZlbnQ6IFwiRWFzeVR5cGluZy5jaGFuZ2VcIlxuXHRcdFx0XHR9KVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aGFuZGxlRW5kQ29tcG9zZVR5cGVLZXkgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQsIHZpZXc6IEVkaXRvclZpZXcpID0+IHtcblx0XHRpZiAoKFsnRW50ZXInLCAnUHJvY2VzcycsICcgJywgJ1NoaWZ0J10uY29udGFpbnMoZXZlbnQua2V5KSB8fCAvXFxkLy50ZXN0KGV2ZW50LmtleSkpICYmXG5cdFx0XHR0aGlzLmNvbXBvc2VfbmVlZF9oYW5kbGUpIHtcblx0XHRcdGxldCBjdXJzb3IgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbi5hc1NpbmdsZSgpLm1haW47XG5cdFx0XHRpZiAoY3Vyc29yLmhlYWQgIT0gY3Vyc29yLmFuY2hvcikgcmV0dXJuO1xuXHRcdFx0bGV0IGluc2VydGVkU3RyID0gdmlldy5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcodGhpcy5jb21wb3NlX2JlZ2luX3BvcywgY3Vyc29yLmFuY2hvcik7XG5cdFx0XHQvLyBjb25zb2xlLmxvZyhcImluc2VydGVkIHN0clwiLCBpbnNlcnRlZFN0cik7XG5cdFx0XHR0aGlzLmNvbXBvc2VfbmVlZF9oYW5kbGUgPSBmYWxzZTtcblx0XHRcdGlmICh0aGlzLnRyaWdnZXJVc2VyQ3Z0UnVsZSh2aWV3LCBjdXJzb3IuYW5jaG9yKSkgcmV0dXJuO1xuXHRcdFx0aWYgKHRoaXMudHJpZ2dlclB1bmNSZWN0aWZ5KHZpZXcsIHRoaXMuY29tcG9zZV9iZWdpbl9wb3MpKSByZXR1cm47XG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5BdXRvRm9ybWF0ICYmICF0aGlzLmlzQ3VycmVudEZpbGVFeGNsdWRlKCkpe1xuXHRcdFx0XHRpZiAoZ2V0UG9zTGluZVR5cGUodmlldy5zdGF0ZSwgY3Vyc29yLmFuY2hvcikgIT0gTGluZVR5cGUudGV4dCkgcmV0dXJuO1xuXHRcdFx0XHRsZXQgY2hhbmdlcyA9IHRoaXMuRm9ybWF0ZXIuZm9ybWF0TGluZU9mRG9jKHZpZXcuc3RhdGUsIHRoaXMuc2V0dGluZ3MsXG5cdFx0XHRcdFx0dGhpcy5jb21wb3NlX2JlZ2luX3BvcywgY3Vyc29yLmFuY2hvciwgaW5zZXJ0ZWRTdHIpO1xuXHRcdFx0XHRpZiAoY2hhbmdlcyAhPSBudWxsKSB7XG5cdFx0XHRcdFx0dmlldy5kaXNwYXRjaCguLi5jaGFuZ2VzWzBdKTtcblx0XHRcdFx0XHR2aWV3LmRpc3BhdGNoKGNoYW5nZXNbMV0pO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGZvcm1hdEFydGljbGUgPSAoZWRpdG9yOiBFZGl0b3IsIHZpZXc6IE1hcmtkb3duVmlldyk6IHZvaWQgPT4ge1xuXHRcdGNvbnN0IGVkaXRvclZpZXcgPSBlZGl0b3IuY20gYXMgRWRpdG9yVmlldztcblx0XHRjb25zdCB0cmVlID0gZW5zdXJlU3ludGF4VHJlZShlZGl0b3JWaWV3LnN0YXRlLCBlZGl0b3JWaWV3LnN0YXRlLmRvYy5sZW5ndGgpO1xuXHRcdGlmICghdHJlZSl7XG5cdFx0XHRuZXcgTm90aWNlKCdFYXN5VHlwaW5nOiBTeW50YXggdHJlZSBpcyBub3QgcmVhZHkgeWV0LCBwbGVhc2Ugd2FpdCBhIG1vbWVudCBhbmQgdHJ5IGFnYWluIGxhdGVyIScsIDUwMDApO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMub25Gb3JtYXRBcnRpY2xlID0gdHJ1ZTtcblx0XHRcblx0XHRsZXQgbGluZUNvdW50ID0gZWRpdG9yLmxpbmVDb3VudCgpO1xuXHRcdGxldCBuZXdfYXJ0aWNsZSA9IFwiXCI7XG5cdFx0bGV0IGNzID0gZWRpdG9yLmdldEN1cnNvcigpO1xuXHRcdGxldCBjaCA9IDA7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lQ291bnQ7IGkrKykge1xuXHRcdFx0aWYgKGkgIT0gMCkgbmV3X2FydGljbGUgKz0gJ1xcbic7XG5cdFx0XHRpZiAoaSAhPSBjcy5saW5lKSB7XG5cdFx0XHRcdG5ld19hcnRpY2xlICs9IHRoaXMucHJlRm9ybWF0T25lTGluZShlZGl0b3IsIGkgKyAxKVswXTtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRsZXQgbmV3RGF0YSA9IHRoaXMucHJlRm9ybWF0T25lTGluZShlZGl0b3IsIGkgKyAxLCBjcy5jaCk7XG5cdFx0XHRcdG5ld19hcnRpY2xlICs9IG5ld0RhdGFbMF07XG5cdFx0XHRcdGNoID0gbmV3RGF0YVsxXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0ZWRpdG9yLnNldFZhbHVlKG5ld19hcnRpY2xlKTtcblx0XHRlZGl0b3Iuc2V0Q3Vyc29yKHsgbGluZTogY3MubGluZSwgY2g6IGNoIH0pO1xuXG5cdFx0dGhpcy5vbkZvcm1hdEFydGljbGUgPSBmYWxzZTtcblxuXHRcdG5ldyBOb3RpY2UoXCJFYXN5VHlwaW5nOiBGb3JtYXQgQXJ0aWNsZSBEb25lIVwiKTtcblx0fVxuXG5cdGlzQ3VycmVudEZpbGVFeGNsdWRlKCk6IGJvb2xlYW4ge1xuXHRcdGlmICh0aGlzLkN1ckFjdGl2ZU1hcmtkb3duID09IFwiXCIpIHtcblx0XHRcdGxldCBmaWxlID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKTtcblx0XHRcdGlmIChmaWxlICE9IG51bGwgJiYgdGhpcy5DdXJBY3RpdmVNYXJrZG93biAhPSBmaWxlLnBhdGgpIHtcblx0XHRcdFx0dGhpcy5DdXJBY3RpdmVNYXJrZG93biA9IGZpbGUucGF0aDtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0bGV0IGV4Y2x1ZGVQYXRocyA9IHRoaXMuc2V0dGluZ3MuRXhjbHVkZUZpbGVzLnNwbGl0KCdcXG4nKTtcblx0XHRmb3IgKGxldCBlcGF0aCBvZiBleGNsdWRlUGF0aHMpIHtcblx0XHRcdGlmIChlcGF0aC5jaGFyQXQoMCkgPT0gJy8nKSBlcGF0aCA9IGVwYXRoLnN1YnN0cmluZygxKTtcblx0XHRcdGlmICh0aGlzLkN1ckFjdGl2ZU1hcmtkb3duID09IGVwYXRoKSByZXR1cm4gdHJ1ZTtcblx0XHRcdGxldCBsZW4gPSBlcGF0aC5sZW5ndGg7XG5cdFx0XHRpZiAodGhpcy5DdXJBY3RpdmVNYXJrZG93bi5zdWJzdHJpbmcoMCwgbGVuKSA9PSBlcGF0aCAmJiAodGhpcy5DdXJBY3RpdmVNYXJrZG93bi5jaGFyQXQobGVuKSA9PSAnLycgfHwgdGhpcy5DdXJBY3RpdmVNYXJrZG93bi5jaGFyQXQobGVuKSA9PSAnXFxcXCcgfHxcblx0XHRcdFx0ZXBhdGguY2hhckF0KGxlbiAtIDEpID09IFwiL1wiIHx8IGVwYXRoLmNoYXJBdChsZW4gLSAxKSA9PSBcIlxcXFxcIikpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGZvcm1hdFNlbGVjdGlvbk9yQ3VyTGluZSA9IChlZGl0b3I6IEVkaXRvciwgdmlldzogTWFya2Rvd25WaWV3KTogdm9pZCA9PiB7XG5cdFx0aWYgKCFlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKSB8fCBlZGl0b3IuZ2V0U2VsZWN0aW9uKCkgPT09ICcnKSB7XG5cdFx0XHRsZXQgbGluZU51bWJlciA9IGVkaXRvci5nZXRDdXJzb3IoKS5saW5lO1xuXHRcdFx0bGV0IG5ld0xpbmVEYXRhID0gdGhpcy5wcmVGb3JtYXRPbmVMaW5lKGVkaXRvciwgbGluZU51bWJlciArIDEsIGVkaXRvci5nZXRDdXJzb3IoKS5jaCk7XG5cdFx0XHRlZGl0b3IucmVwbGFjZVJhbmdlKG5ld0xpbmVEYXRhWzBdLCB7IGxpbmU6IGxpbmVOdW1iZXIsIGNoOiAwIH0sIHsgbGluZTogbGluZU51bWJlciwgY2g6IGVkaXRvci5nZXRMaW5lKGxpbmVOdW1iZXIpLmxlbmd0aCB9KTtcblx0XHRcdGVkaXRvci5zZXRTZWxlY3Rpb24oeyBsaW5lOiBsaW5lTnVtYmVyLCBjaDogbmV3TGluZURhdGFbMV0gfSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGxldCBzZWxlY3Rpb24gPSBlZGl0b3IubGlzdFNlbGVjdGlvbnMoKVswXTtcblx0XHRsZXQgYmVnaW4gPSBzZWxlY3Rpb24uYW5jaG9yLmxpbmU7XG5cdFx0bGV0IGVuZCA9IHNlbGVjdGlvbi5oZWFkLmxpbmU7XG5cdFx0aWYgKGJlZ2luID4gZW5kKSB7XG5cdFx0XHRsZXQgdGVtcCA9IGJlZ2luO1xuXHRcdFx0YmVnaW4gPSBlbmQ7XG5cdFx0XHRlbmQgPSB0ZW1wO1xuXHRcdH1cblx0XHQvLyBjb25zb2xlLmxvZyhiZWdpbiwgZW5kKVxuXHRcdGxldCBuZXdfbGluZXMgPSBcIlwiO1xuXHRcdGZvciAobGV0IGkgPSBiZWdpbjsgaSA8PSBlbmQ7IGkrKykge1xuXHRcdFx0aWYgKGkgIT0gYmVnaW4pIG5ld19saW5lcyArPSAnXFxuJztcblx0XHRcdG5ld19saW5lcyArPSB0aGlzLnByZUZvcm1hdE9uZUxpbmUoZWRpdG9yLCBpICsgMSlbMF07XG5cdFx0fVxuXHRcdGVkaXRvci5yZXBsYWNlUmFuZ2UobmV3X2xpbmVzLCB7IGxpbmU6IGJlZ2luLCBjaDogMCB9LCB7IGxpbmU6IGVuZCwgY2g6IGVkaXRvci5nZXRMaW5lKGVuZCkubGVuZ3RoIH0pO1xuXHRcdGlmIChzZWxlY3Rpb24uYW5jaG9yLmxpbmUgPCBzZWxlY3Rpb24uaGVhZC5saW5lKSB7XG5cdFx0XHRlZGl0b3Iuc2V0U2VsZWN0aW9uKHsgbGluZTogc2VsZWN0aW9uLmFuY2hvci5saW5lLCBjaDogMCB9LCB7IGxpbmU6IHNlbGVjdGlvbi5oZWFkLmxpbmUsIGNoOiBlZGl0b3IuZ2V0TGluZShzZWxlY3Rpb24uaGVhZC5saW5lKS5sZW5ndGggfSk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0ZWRpdG9yLnNldFNlbGVjdGlvbih7IGxpbmU6IHNlbGVjdGlvbi5hbmNob3IubGluZSwgY2g6IGVkaXRvci5nZXRMaW5lKHNlbGVjdGlvbi5hbmNob3IubGluZSkubGVuZ3RoIH0sIHsgbGluZTogc2VsZWN0aW9uLmhlYWQubGluZSwgY2g6IDAgfSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gcGFyYW06IGxpbmVOdW1iZXIgaXMgKDEtYmFzZWQpLCBcdTVFOUZcdTVGMDNcdTUxRkRcdTY1NzBcblx0Zm9ybWF0T25lTGluZSA9IChlZGl0b3I6IEVkaXRvciwgbGluZU51bWJlcjogbnVtYmVyKTogdm9pZCA9PiB7XG5cdFx0Y29uc3QgZWRpdG9yVmlldyA9IGVkaXRvci5jbSBhcyBFZGl0b3JWaWV3O1xuXHRcdGxldCBzdGF0ZSA9IGVkaXRvclZpZXcuc3RhdGU7XG5cdFx0bGV0IGxpbmUgPSBzdGF0ZS5kb2MubGluZShsaW5lTnVtYmVyKVxuXG5cdFx0aWYgKGdldFBvc0xpbmVUeXBlKHN0YXRlLCBsaW5lLmZyb20pID09IExpbmVUeXBlLnRleHQgfHwgZ2V0UG9zTGluZVR5cGUoc3RhdGUsIGxpbmUuZnJvbSkgPT0gTGluZVR5cGUudGFibGUpIHtcblx0XHRcdGxldCBvbGRMaW5lID0gbGluZS50ZXh0O1xuXHRcdFx0bGV0IG5ld0xpbmUgPSB0aGlzLkZvcm1hdGVyLmZvcm1hdExpbmUoc3RhdGUsIGxpbmVOdW1iZXIsIHRoaXMuc2V0dGluZ3MsIG9sZExpbmUubGVuZ3RoLCAwKVswXTtcblx0XHRcdGlmIChvbGRMaW5lICE9IG5ld0xpbmUpIHtcblx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VSYW5nZShuZXdMaW5lLCB7IGxpbmU6IGxpbmVOdW1iZXIgLSAxLCBjaDogMCB9LCB7IGxpbmU6IGxpbmVOdW1iZXIgLSAxLCBjaDogb2xkTGluZS5sZW5ndGggfSk7XG5cdFx0XHRcdGVkaXRvci5zZXRDdXJzb3IoeyBsaW5lOiBsaW5lTnVtYmVyIC0gMSwgY2g6IGVkaXRvci5nZXRMaW5lKGxpbmVOdW1iZXIgLSAxKS5sZW5ndGggfSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIHBhcmFtOiBsaW5lTnVtYmVyIGlzICgxLWJhc2VkKVxuXHRwcmVGb3JtYXRPbmVMaW5lID0gKGVkaXRvcjogRWRpdG9yLCBsaW5lTnVtYmVyOiBudW1iZXIsIGNoOiBudW1iZXIgPSAtMSk6IFtzdHJpbmcsIG51bWJlcl0gPT4ge1xuXHRcdGNvbnN0IGVkaXRvclZpZXcgPSBlZGl0b3IuY20gYXMgRWRpdG9yVmlldztcblx0XHRsZXQgc3RhdGUgPSBlZGl0b3JWaWV3LnN0YXRlO1xuXHRcdGxldCBsaW5lID0gc3RhdGUuZG9jLmxpbmUobGluZU51bWJlcilcblxuXHRcdGxldCBuZXdMaW5lID0gbGluZS50ZXh0O1xuXHRcdGxldCBuZXdDaCA9IDA7XG5cdFx0bGV0IGN1ckNoID0gbGluZS50ZXh0Lmxlbmd0aDtcblx0XHRpZiAoY2ggIT0gLTEpIHtcblx0XHRcdGN1ckNoID0gY2g7XG5cdFx0fVxuXHRcdGlmIChnZXRQb3NMaW5lVHlwZShzdGF0ZSwgbGluZS5mcm9tKSA9PSBMaW5lVHlwZS50ZXh0IHx8IGdldFBvc0xpbmVUeXBlKHN0YXRlLCBsaW5lLmZyb20pID09IExpbmVUeXBlLnRhYmxlKSB7XG5cdFx0XHRsZXQgbmV3TGluZURhdGEgPSB0aGlzLkZvcm1hdGVyLmZvcm1hdExpbmUoc3RhdGUsIGxpbmVOdW1iZXIsIHRoaXMuc2V0dGluZ3MsIGN1ckNoLCAwKTtcblx0XHRcdG5ld0xpbmUgPSBuZXdMaW5lRGF0YVswXTtcblx0XHRcdG5ld0NoID0gbmV3TGluZURhdGFbMV07XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtuZXdMaW5lLCBuZXdDaF07XG5cdH1cblxuXHRkZWxldGVCbGFua0xpbmVzID0gKGVkaXRvcjogRWRpdG9yKTogdm9pZCA9PiB7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MuZGVidWcpIHtcblx0XHRcdGNvbnNvbGUubG9nKHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZyhcInN0cmljdExpbmVCcmVha3NcIikpO1xuXHRcdFx0Ly8gcmV0dXJuO1xuXHRcdH1cblx0XHRsZXQgc3RyaWN0TGluZUJyZWFrcyA9IHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZyhcInN0cmljdExpbmVCcmVha3NcIik7XG5cblx0XHRjb25zdCBlZGl0b3JWaWV3ID0gZWRpdG9yLmNtIGFzIEVkaXRvclZpZXc7XG5cdFx0bGV0IHN0YXRlID0gZWRpdG9yVmlldy5zdGF0ZTtcblx0XHRsZXQgZG9jID0gc3RhdGUuZG9jXG5cdFx0XG5cdFx0Y29uc3QgdHJlZSA9IGVuc3VyZVN5bnRheFRyZWUoc3RhdGUsIGRvYy5sZW5ndGgpO1xuXHRcdGlmICghdHJlZSl7XG5cdFx0XHRuZXcgTm90aWNlKCdFYXN5VHlwaW5nOiBTeW50YXggdHJlZSBpcyBub3QgcmVhZHkgeWV0LCBwbGVhc2Ugd2FpdCBhIG1vbWVudCBhbmQgdHJ5IGFnYWluIGxhdGVyIScsIDUwMDApO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRcblx0XHRsZXQgc3RhcnRfbGluZSA9IDE7XG5cdFx0bGV0IGVuZF9saW5lID0gZG9jLmxpbmVzO1xuXHRcdGxldCBsaW5lX251bSA9IGRvYy5saW5lcztcblx0XHRjb25zdCBzZWxlY3RlZCA9IGVkaXRvci5zb21ldGhpbmdTZWxlY3RlZCgpICYmIGVkaXRvci5nZXRTZWxlY3Rpb24oKSAhPSAnJztcblx0XHRpZiAoc2VsZWN0ZWQpIHtcblx0XHRcdGxldCBzZWxlY3Rpb24gPSBlZGl0b3IubGlzdFNlbGVjdGlvbnMoKVswXTtcblx0XHRcdGxldCBiZWdpbiA9IHNlbGVjdGlvbi5hbmNob3IubGluZSArIDE7XG5cdFx0XHRsZXQgZW5kID0gc2VsZWN0aW9uLmhlYWQubGluZSArIDE7XG5cdFx0XHRpZiAoYmVnaW4gPiBlbmQpIHtcblx0XHRcdFx0bGV0IHRlbXAgPSBiZWdpbjtcblx0XHRcdFx0YmVnaW4gPSBlbmQ7XG5cdFx0XHRcdGVuZCA9IHRlbXA7XG5cdFx0XHR9XG5cdFx0XHRzdGFydF9saW5lID0gYmVnaW47XG5cdFx0XHRlbmRfbGluZSA9IGVuZFxuXHRcdH1cblxuXHRcdC8vIGlmKHRoaXMuc2V0dGluZ3MuZGVidWcpe1xuXHRcdC8vIFx0bGV0IGxpbmVfaW5kZXggPSBlZGl0b3IuZ2V0Q3Vyc29yKCkubGluZSArIDE7XG5cdFx0Ly8gXHRsZXQgY29udGVudCA9IGVkaXRvci5nZXRMaW5lKGVkaXRvci5nZXRDdXJzb3IoKS5saW5lKTtcblx0XHQvLyBcdGNvbnNvbGUubG9nKGNvbnRlbnQpO1xuXHRcdC8vIFx0Zm9yIChsZXQgaT0wO2k8Y29udGVudC5sZW5ndGg7aSsrKXtcblx0XHQvLyBcdFx0bGV0IG5vZGUgPSB0cmVlLnJlc29sdmUoZG9jLmxpbmUobGluZV9pbmRleCkuZnJvbStpLCAxKTtcblx0XHQvLyBcdFx0Y29uc29sZS5sb2coaSwgbm9kZS5uYW1lKVxuXHRcdC8vIFx0fVxuXHRcdC8vIFx0cmV0dXJuO1xuXHRcdC8vIH1cblxuXHRcdGxldCBkZWxldGVfaW5kZXg6IG51bWJlcltdID0gW107XG5cdFx0bGV0IGJsYW5rX3JlZyA9IC9eXFxzKiQvO1xuXHRcdGxldCByZW1haW5fbmV4dF9ibGFuayA9IGZhbHNlO1xuXG5cdFx0aWYgKHN0YXJ0X2xpbmUgIT0gMSkge1xuXHRcdFx0bGV0IG5vZGUgPSB0cmVlLnJlc29sdmUoZG9jLmxpbmUoc3RhcnRfbGluZSAtIDEpLmZyb20sIDEpO1xuXHRcdFx0aWYgKG5vZGUubmFtZS5jb250YWlucygnbGlzdCcpIHx8IG5vZGUubmFtZS5jb250YWlucygncXVvdGUnKSB8fCBub2RlLm5hbWUuY29udGFpbnMoJ2Jsb2NraWQnKSkge1xuXHRcdFx0XHRyZW1haW5fbmV4dF9ibGFuayA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChlbmRfbGluZSAhPSBsaW5lX251bSAmJiAhYmxhbmtfcmVnLnRlc3QoZG9jLmxpbmUoZW5kX2xpbmUgKyAxKS50ZXh0KSkge1xuXHRcdFx0ZW5kX2xpbmUgKz0gMTtcblx0XHR9XG5cblx0XHRmb3IgKGxldCBpID0gc3RhcnRfbGluZTsgaSA8PSBlbmRfbGluZTsgaSsrKSB7XG5cdFx0XHRsZXQgbGluZSA9IGRvYy5saW5lKGkpO1xuXHRcdFx0bGV0IHBvcyA9IGxpbmUuZnJvbTtcblx0XHRcdGxldCBub2RlID0gdHJlZS5yZXNvbHZlKHBvcywgMSk7XG5cblx0XHRcdC8vIFx1NUJGOVx1NEU4RVx1N0E3QVx1NzY3RFx1ODg0Q1xuXHRcdFx0aWYgKGJsYW5rX3JlZy50ZXN0KGxpbmUudGV4dCkgJiYgIXJlbWFpbl9uZXh0X2JsYW5rKSB7XG5cdFx0XHRcdGRlbGV0ZV9pbmRleC5wdXNoKGkpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKGJsYW5rX3JlZy50ZXN0KGxpbmUudGV4dCkgJiYgcmVtYWluX25leHRfYmxhbmspIHtcblx0XHRcdFx0cmVtYWluX25leHRfYmxhbmsgPSBmYWxzZTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChub2RlLm5hbWUuY29udGFpbnMoJ2hyJykgJiYgZGVsZXRlX2luZGV4W2RlbGV0ZV9pbmRleC5sZW5ndGggLSAxXSA9PSBpIC0gMSkge1xuXHRcdFx0XHRkZWxldGVfaW5kZXgucG9wKClcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKG5vZGUubmFtZS5jb250YWlucygnbGlzdCcpIHx8IG5vZGUubmFtZS5jb250YWlucygncXVvdGUnKSB8fCBub2RlLm5hbWUuY29udGFpbnMoJ2Jsb2NraWQnKSkge1xuXHRcdFx0XHRyZW1haW5fbmV4dF9ibGFuayA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0cmVtYWluX25leHRfYmxhbmsgPSBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gY29uc29sZS5sb2coXCJkZWxldGVfaW5kZXhcIixkZWxldGVfaW5kZXgpXG5cdFx0bGV0IG5ld0NvbnRlbnQgPSBcIlwiO1xuXHRcdGZvciAobGV0IGkgPSAxOyBpIDwgbGluZV9udW07IGkrKykge1xuXHRcdFx0aWYgKCFkZWxldGVfaW5kZXguY29udGFpbnMoaSkpIHtcblx0XHRcdFx0bmV3Q29udGVudCArPSBkb2MubGluZShpKS50ZXh0ICsgJ1xcbic7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICghZGVsZXRlX2luZGV4LmNvbnRhaW5zKGxpbmVfbnVtKSkge1xuXHRcdFx0bmV3Q29udGVudCArPSBkb2MubGluZShsaW5lX251bSkudGV4dFxuXHRcdH1cblxuXHRcdGVkaXRvci5zZXRWYWx1ZShuZXdDb250ZW50KTtcblx0XHQvLyB0aGlzLkNvbnRlbnRQYXJzZXIucmVwYXJzZShlZGl0b3IuZ2V0VmFsdWUoKSwgMCk7XG5cdH1cblxuXHRzd2l0Y2hBdXRvRm9ybWF0dGluZygpIHtcblx0XHR0aGlzLnNldHRpbmdzLkF1dG9Gb3JtYXQgPSAhdGhpcy5zZXR0aW5ncy5BdXRvRm9ybWF0O1xuXHRcdGxldCBzdGF0dXMgPSB0aGlzLnNldHRpbmdzLkF1dG9Gb3JtYXQgPyAnb24nIDogJ29mZic7XG5cdFx0bmV3IE5vdGljZSgnRWFzeVR5cGluZzogQXV0b2Zvcm1hdCBpcyAnICsgc3RhdHVzICsgJyEnKTtcblx0fVxuXG5cdGNvbnZlcnQyQ29kZUJsb2NrKGVkaXRvcjogRWRpdG9yKSB7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MuZGVidWcpIGNvbnNvbGUubG9nKFwiLS0tLS0gRWFzeVR5cGluZzogaW5zZXJ0IGNvZGUgYmxvY2stLS0tLVwiKTtcblx0XHRpZiAoZWRpdG9yLnNvbWV0aGluZ1NlbGVjdGVkICYmIGVkaXRvci5nZXRTZWxlY3Rpb24oKSAhPSBcIlwiKSB7XG5cdFx0XHRsZXQgc2VsZWN0ZWQgPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCk7XG5cdFx0XHRsZXQgc2VsZWN0ZWRSYW5nZSA9IGVkaXRvci5saXN0U2VsZWN0aW9ucygpWzBdO1xuXHRcdFx0bGV0IGFuY2hvciA9IHNlbGVjdGVkUmFuZ2UuYW5jaG9yO1xuXHRcdFx0bGV0IGhlYWQgPSBzZWxlY3RlZFJhbmdlLmhlYWQ7XG5cblx0XHRcdGxldCByZXBsYWNlbWVudCA9IFwiYGBgXFxuXCIgKyBzZWxlY3RlZCArIFwiXFxuYGBgXCI7XG5cdFx0XHQvLyBtYWtlIHN1cmUgYW5jaG9yIDwgaGVhZFxuXHRcdFx0aWYgKGFuY2hvci5saW5lID4gaGVhZC5saW5lIHx8IChhbmNob3IubGluZSA9PSBoZWFkLmxpbmUgJiYgYW5jaG9yLmNoID4gaGVhZC5jaCkpIHtcblx0XHRcdFx0bGV0IHRlbXAgPSBhbmNob3I7XG5cdFx0XHRcdGFuY2hvciA9IGhlYWQ7XG5cdFx0XHRcdGhlYWQgPSB0ZW1wO1xuXHRcdFx0fVxuXHRcdFx0bGV0IGRzdExpbmUgPSBhbmNob3IubGluZTtcblx0XHRcdGlmIChhbmNob3IuY2ggIT0gMCkge1xuXHRcdFx0XHRyZXBsYWNlbWVudCA9ICdcXG4nICsgcmVwbGFjZW1lbnQ7XG5cdFx0XHRcdGRzdExpbmUgKz0gMTtcblx0XHRcdH1cblx0XHRcdGlmIChoZWFkLmNoICE9IGVkaXRvci5nZXRMaW5lKGhlYWQubGluZSkubGVuZ3RoKSB7XG5cdFx0XHRcdHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQgKyAnXFxuJztcblx0XHRcdH1cblx0XHRcdGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKHJlcGxhY2VtZW50KTtcblx0XHRcdGVkaXRvci5zZXRDdXJzb3IoeyBsaW5lOiBkc3RMaW5lLCBjaDogMyB9KTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRsZXQgY3MgPSBlZGl0b3IuZ2V0Q3Vyc29yKCk7XG5cdFx0XHRsZXQgcmVwbGFjZSA9IFwiYGBgXFxuYGBgXCI7XG5cdFx0XHRsZXQgZHN0TGluZSA9IGNzLmxpbmU7XG5cdFx0XHRpZiAoY3MuY2ggIT0gMCkge1xuXHRcdFx0XHRyZXBsYWNlID0gXCJcXG5cIiArIHJlcGxhY2U7XG5cdFx0XHRcdGRzdExpbmUgKz0gMTtcblx0XHRcdH1cblx0XHRcdGlmIChjcy5jaCAhPSBlZGl0b3IuZ2V0TGluZShjcy5saW5lKS5sZW5ndGgpIHtcblx0XHRcdFx0cmVwbGFjZSA9IHJlcGxhY2UgKyAnXFxuJztcblx0XHRcdH1cblx0XHRcdGVkaXRvci5yZXBsYWNlUmFuZ2UocmVwbGFjZSwgY3MpO1xuXHRcdFx0ZWRpdG9yLnNldEN1cnNvcih7IGxpbmU6IGRzdExpbmUsIGNoOiAzIH0pO1xuXHRcdH1cblxuXHR9XG5cblx0cmVmcmVzaFNlbGVjdGlvblJlcGxhY2VSdWxlKCkge1xuXHRcdHRoaXMuU2VsZWN0aW9uUmVwbGFjZU1hcCA9IG5ldyBNYXAodGhpcy5zZWxlY3Rpb25SZXBsYWNlTWFwSW5pdGFsRGF0YSk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVHJpZ2dlci5sZW5ndGg7IGkrKykge1xuXHRcdFx0bGV0IHRyaWdnZXIgPSB0aGlzLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVHJpZ2dlcltpXTtcblx0XHRcdGxldCBsZWZ0cyA9IHRoaXMuc2V0dGluZ3MudXNlclNlbFJlcFJ1bGVWYWx1ZVtpXS5sZWZ0O1xuXHRcdFx0bGV0IHJpZ2h0cyA9IHRoaXMuc2V0dGluZ3MudXNlclNlbFJlcFJ1bGVWYWx1ZVtpXS5yaWdodDtcblxuXHRcdFx0dGhpcy5TZWxlY3Rpb25SZXBsYWNlTWFwLnNldCh0cmlnZ2VyLCB7IGxlZnQ6IGxlZnRzLCByaWdodDogcmlnaHRzIH0pO1xuXHRcdH1cblx0fVxuXG5cdGFkZFVzZXJTZWxlY3Rpb25SZXBSdWxlKHRyaWdnZXI6IHN0cmluZywgbGVmdDogc3RyaW5nLCByaWdodDogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MudXNlclNlbFJlcFJ1bGVUcmlnZ2VyLmluY2x1ZGVzKHRyaWdnZXIpKSByZXR1cm4gZmFsc2U7XG5cdFx0dGhpcy5zZXR0aW5ncy51c2VyU2VsUmVwUnVsZVRyaWdnZXIucHVzaCh0cmlnZ2VyKVxuXHRcdHRoaXMuc2V0dGluZ3MudXNlclNlbFJlcFJ1bGVWYWx1ZS5wdXNoKHsgbGVmdDogbGVmdCwgcmlnaHQ6IHJpZ2h0IH0pO1xuXHRcdHRoaXMucmVmcmVzaFNlbGVjdGlvblJlcGxhY2VSdWxlKCk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRkZWxldGVVc2VyU2VsZWN0aW9uUmVwUnVsZShpZHg6IG51bWJlcik6IHZvaWQge1xuXHRcdGlmIChpZHggPCAwIHx8IGlkeCA+PSB0aGlzLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVHJpZ2dlci5sZW5ndGgpIHJldHVybjtcblx0XHR0aGlzLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVHJpZ2dlci5zcGxpY2UoaWR4LCAxKTtcblx0XHR0aGlzLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVmFsdWUuc3BsaWNlKGlkeCwgMSk7XG5cdFx0dGhpcy5yZWZyZXNoU2VsZWN0aW9uUmVwbGFjZVJ1bGUoKTtcblx0fVxuXG5cdHVwZGF0ZVVzZXJTZWxlY3Rpb25SZXBSdWxlKGlkeDogbnVtYmVyLCBsZWZ0OiBzdHJpbmcsIHJpZ2h0OiBzdHJpbmcpIHtcblx0XHRpZiAoaWR4IDwgMCB8fCBpZHggPj0gdGhpcy5zZXR0aW5ncy51c2VyU2VsUmVwUnVsZVRyaWdnZXIubGVuZ3RoKSByZXR1cm47XG5cdFx0dGhpcy5zZXR0aW5ncy51c2VyU2VsUmVwUnVsZVZhbHVlW2lkeF0ubGVmdCA9IGxlZnQ7XG5cdFx0dGhpcy5zZXR0aW5ncy51c2VyU2VsUmVwUnVsZVZhbHVlW2lkeF0ucmlnaHQgPSByaWdodDtcblx0XHR0aGlzLnJlZnJlc2hTZWxlY3Rpb25SZXBsYWNlUnVsZSgpO1xuXHR9XG5cblx0cmVmcmVzaFVzZXJEZWxldGVSdWxlKCkge1xuXHRcdHRoaXMuVXNlckRlbGV0ZVJ1bGVzID0gcnVsZVN0cmluZ0xpc3QyUnVsZUxpc3QodGhpcy5zZXR0aW5ncy51c2VyRGVsZXRlUnVsZXNTdHJMaXN0KTtcblx0fVxuXG5cdGFkZFVzZXJEZWxldGVSdWxlKGJlZm9yZTogc3RyaW5nLCBhZnRlcjogc3RyaW5nKSB7XG5cdFx0dGhpcy5zZXR0aW5ncy51c2VyRGVsZXRlUnVsZXNTdHJMaXN0LnB1c2goW2JlZm9yZSwgYWZ0ZXJdKTtcblx0XHR0aGlzLnJlZnJlc2hVc2VyRGVsZXRlUnVsZSgpO1xuXHR9XG5cblx0ZGVsZXRlVXNlckRlbGV0ZVJ1bGUoaWR4OiBudW1iZXIpIHtcblx0XHRpZiAoaWR4ID49IHRoaXMuc2V0dGluZ3MudXNlckRlbGV0ZVJ1bGVzU3RyTGlzdC5sZW5ndGggfHwgaWR4IDwgMCkgcmV0dXJuO1xuXHRcdHRoaXMuc2V0dGluZ3MudXNlckRlbGV0ZVJ1bGVzU3RyTGlzdC5zcGxpY2UoaWR4LCAxKTtcblx0XHR0aGlzLnJlZnJlc2hVc2VyRGVsZXRlUnVsZSgpO1xuXHR9XG5cblx0dXBkYXRlVXNlckRlbGV0ZVJ1bGUoaWR4OiBudW1iZXIsIGJlZm9yZTogc3RyaW5nLCBhZnRlcjogc3RyaW5nKSB7XG5cdFx0aWYgKGlkeCA+PSB0aGlzLnNldHRpbmdzLnVzZXJEZWxldGVSdWxlc1N0ckxpc3QubGVuZ3RoIHx8IGlkeCA8IDApIHJldHVybjtcblx0XHR0aGlzLnNldHRpbmdzLnVzZXJEZWxldGVSdWxlc1N0ckxpc3RbaWR4XVswXSA9IGJlZm9yZTtcblx0XHR0aGlzLnNldHRpbmdzLnVzZXJEZWxldGVSdWxlc1N0ckxpc3RbaWR4XVsxXSA9IGFmdGVyO1xuXHRcdHRoaXMucmVmcmVzaFVzZXJEZWxldGVSdWxlKCk7XG5cdH1cblxuXHRyZWZyZXNoVXNlckNvbnZlcnRSdWxlKCkge1xuXHRcdHRoaXMuVXNlckNvbnZlcnRSdWxlcyA9IHJ1bGVTdHJpbmdMaXN0MlJ1bGVMaXN0KHRoaXMuc2V0dGluZ3MudXNlckNvbnZlcnRSdWxlc1N0ckxpc3QpO1xuXHR9XG5cblx0YWRkVXNlckNvbnZlcnRSdWxlKGJlZm9yZTogc3RyaW5nLCBhZnRlcjogc3RyaW5nKSB7XG5cdFx0dGhpcy5zZXR0aW5ncy51c2VyQ29udmVydFJ1bGVzU3RyTGlzdC5wdXNoKFtiZWZvcmUsIGFmdGVyXSk7XG5cdFx0dGhpcy5yZWZyZXNoVXNlckNvbnZlcnRSdWxlKCk7XG5cdH1cblxuXHRkZWxldGVVc2VyQ29udmVydFJ1bGUoaWR4OiBudW1iZXIpIHtcblx0XHRpZiAoaWR4ID49IHRoaXMuc2V0dGluZ3MudXNlckNvbnZlcnRSdWxlc1N0ckxpc3QubGVuZ3RoIHx8IGlkeCA8IDApIHJldHVybjtcblx0XHR0aGlzLnNldHRpbmdzLnVzZXJDb252ZXJ0UnVsZXNTdHJMaXN0LnNwbGljZShpZHgsIDEpO1xuXHRcdHRoaXMucmVmcmVzaFVzZXJDb252ZXJ0UnVsZSgpO1xuXHR9XG5cblx0Z2V0Q29tbWFuZE5hbWVNYXAoKTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG5cdFx0Y29uc3QgbGFuZyA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbGFuZ3VhZ2UnKTtcblxuXHRcdGxldCBjb21tYW5kX25hbWVfbWFwX2VuID0gbmV3IE1hcChbXG5cdFx0XHRbXCJmb3JtYXRfYXJ0aWNsZVwiLCBcIkZvcm1hdCBjdXJyZW50IGFydGljbGVcIl0sXG5cdFx0XHRbXCJmb3JtYXRfc2VsZWN0aW9uXCIsIFwiRm9ybWF0IHNlbGVjdGVkIHRleHQgb3IgY3VycmVudCBsaW5lXCJdLFxuXHRcdFx0W1wiZGVsZXRlX2JsYW5rX2xpbmVcIiwgXCJEZWxldGUgYmxhbmsgbGluZXMgb2YgdGhlIHNlbGVjdGVkIG9yIHdob2xlIGFydGljbGVcIl0sXG5cdFx0XHRbXCJpbnNlcnRfY29kZWJsb2NrXCIsIFwiSW5zZXJ0IGNvZGUgYmxvY2sgdy93byBzZWxlY3Rpb25cIl0sXG5cdFx0XHRbXCJzd2l0Y2hfYXV0b2Zvcm1hdFwiLCBcIlN3aXRjaCBhdXRvZm9ybWF0XCJdLFxuXHRcdFx0W1wicGFzdGVfd29fZm9ybWF0XCIsIFwiUGFzdGUgd2l0aG91dCBmb3JtYXRcIl0sXG5cdFx0XSk7XG5cblx0XHRsZXQgY29tbWFuZF9uYW1lX21hcF96aF9UVyA9IG5ldyBNYXAoW1xuXHRcdFx0W1wiZm9ybWF0X2FydGljbGVcIiwgXCJcdTY4M0NcdTVGMEZcdTUzMTZcdTUxNjhcdTY1ODdcIl0sXG5cdFx0XHRbXCJmb3JtYXRfc2VsZWN0aW9uXCIsIFwiXHU2ODNDXHU1RjBGXHU1MzE2XHU5MDc4XHU0RTJEXHU5MEU4XHU1MjA2L1x1NzU3Nlx1NTI0RFx1ODg0Q1wiXSxcblx0XHRcdFtcImRlbGV0ZV9ibGFua19saW5lXCIsIFwiXHU1MjJBXHU5NjY0XHU5MDc4XHU0RTJEXHU5MEU4XHU1MjA2L1x1NTE2OFx1NjU4N1x1NzY4NFx1NTkxQVx1OTkxOFx1N0E3QVx1NzY3RFx1ODg0Q1wiXSxcblx0XHRcdFtcImluc2VydF9jb2RlYmxvY2tcIiwgXCJcdTYzRDJcdTUxNjVcdTRFRTNcdTc4QkNcdTU4NEFcIl0sXG5cdFx0XHRbXCJzd2l0Y2hfYXV0b2Zvcm1hdFwiLCBcIlx1NTIwN1x1NjNEQlx1ODFFQVx1NTJENVx1NjgzQ1x1NUYwRlx1NTMxNlx1OTU4Qlx1OTVEQ1wiXSxcblx0XHRcdFtcInBhc3RlX3dvX2Zvcm1hdFwiLCBcIlx1NzEyMVx1NjgzQ1x1NUYwRlx1NTMxNlx1N0M5OFx1OENCQ1wiXSxcblx0XHRdKTtcblxuXHRcdGxldCBjb21tYW5kX25hbWVfbWFwX3poID0gbmV3IE1hcChbXG5cdFx0XHRbXCJmb3JtYXRfYXJ0aWNsZVwiLCBcIlx1NjgzQ1x1NUYwRlx1NTMxNlx1NTE2OFx1NjU4N1wiXSxcblx0XHRcdFtcImZvcm1hdF9zZWxlY3Rpb25cIiwgXCJcdTY4M0NcdTVGMEZcdTUzMTZcdTkwMDlcdTRFMkRcdTkwRThcdTUyMDYvXHU1RjUzXHU1MjREXHU4ODRDXCJdLFxuXHRcdFx0W1wiZGVsZXRlX2JsYW5rX2xpbmVcIiwgXCJcdTUyMkFcdTk2NjRcdTkwMDlcdTRFMkRcdTkwRThcdTUyMDYvXHU1MTY4XHU2NTg3XHU3Njg0XHU1OTFBXHU0RjU5XHU3QTdBXHU3NjdEXHU4ODRDXCJdLFxuXHRcdFx0W1wiaW5zZXJ0X2NvZGVibG9ja1wiLCBcIlx1NjNEMlx1NTE2NVx1NEVFM1x1NzgwMVx1NTc1N1wiXSxcblx0XHRcdFtcInN3aXRjaF9hdXRvZm9ybWF0XCIsIFwiXHU1MjA3XHU2MzYyXHU4MUVBXHU1MkE4XHU2ODNDXHU1RjBGXHU1MzE2XHU1RjAwXHU1MTczXCJdLFxuXHRcdFx0W1wicGFzdGVfd29fZm9ybWF0XCIsIFwiXHU2NUUwXHU2ODNDXHU1RjBGXHU1MzE2XHU3Qzk4XHU4RDM0XCJdLFxuXHRcdF0pO1xuXG5cdFx0bGV0IGNvbW1hbmRfbmFtZV9tYXAgPSBjb21tYW5kX25hbWVfbWFwX2VuO1xuXHRcdGlmIChsYW5nID09ICd6aCcpIHtcblx0XHRcdGNvbW1hbmRfbmFtZV9tYXAgPSBjb21tYW5kX25hbWVfbWFwX3poO1xuXHRcdH1cblx0XHRlbHNlIGlmIChsYW5nID09ICd6aC1UVycpIHtcblx0XHRcdGNvbW1hbmRfbmFtZV9tYXAgPSBjb21tYW5kX25hbWVfbWFwX3poX1RXO1xuXHRcdH1cblxuXHRcdHJldHVybiBjb21tYW5kX25hbWVfbWFwO1xuXHR9XG5cblx0dXBkYXRlVXNlckNvbnZlcnRSdWxlKGlkeDogbnVtYmVyLCBiZWZvcmU6IHN0cmluZywgYWZ0ZXI6IHN0cmluZykge1xuXHRcdGlmIChpZHggPj0gdGhpcy5zZXR0aW5ncy51c2VyQ29udmVydFJ1bGVzU3RyTGlzdC5sZW5ndGggfHwgaWR4IDwgMCkgcmV0dXJuO1xuXHRcdHRoaXMuc2V0dGluZ3MudXNlckNvbnZlcnRSdWxlc1N0ckxpc3RbaWR4XVswXSA9IGJlZm9yZTtcblx0XHR0aGlzLnNldHRpbmdzLnVzZXJDb252ZXJ0UnVsZXNTdHJMaXN0W2lkeF1bMV0gPSBhZnRlcjtcblx0XHR0aGlzLnJlZnJlc2hVc2VyQ29udmVydFJ1bGUoKTtcblx0fVxuXG5cdGdldEVkaXRvciA9ICgpOiBFZGl0b3IgfCBudWxsID0+IHtcblx0XHRsZXQgZWRpdG9yID0gbnVsbDtcblx0XHRsZXQgbWFya2Rvd25WaWV3ID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcblx0XHRpZiAobWFya2Rvd25WaWV3KSB7XG5cdFx0XHRlZGl0b3IgPSBtYXJrZG93blZpZXcuZWRpdG9yO1xuXHRcdH1cblx0XHRpZiAoZWRpdG9yID09PSBudWxsKSBjb25zb2xlLmxvZygnY2FuXFwndCBnZXQgZWRpdG9yJyk7XG5cdFx0cmV0dXJuIGVkaXRvcjtcblx0fVxuXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcblx0fVxuXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcblx0XHRhd2FpdCB0aGlzLnNhdmVEYXRhKHRoaXMuc2V0dGluZ3MpO1xuXHR9XG59IiwgImltcG9ydCB7IE5vdGljZX0gZnJvbSBcIm9ic2lkaWFuXCJcbmltcG9ydCB7IEVhc3lUeXBpbmdTZXR0aW5ncywgV29ya01vZGUgfSBmcm9tICcuL3NldHRpbmdzJ1xuaW1wb3J0IHsgQW5ub3RhdGlvbiwgRWRpdG9yU3RhdGUsIEV4dGVuc2lvbiwgU3RhdGVGaWVsZCwgVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uU3BlYywgVGV4dCwgTGluZSB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcbmltcG9ydCB7IG9mZnNldFRvUG9zLCBwb3NUb09mZnNldCwgc3RyaW5nRGVsZXRlQXQsIHN0cmluZ0luc2VydEF0LCBpc1BhcmFtRGVmaW5lZH0gZnJvbSAnLi91dGlscydcbmltcG9ydCB7IGVuc3VyZVN5bnRheFRyZWUsIHN5bnRheFRyZWUgfSBmcm9tIFwiQGNvZGVtaXJyb3IvbGFuZ3VhZ2VcIjtcbmltcG9ydCB7IHByaW50IH0gZnJvbSBcIi4vdXRpbHNcIlxuXG5leHBvcnQgZW51bSBMaW5lVHlwZSB7IHRleHQgPSAndGV4dCcsIGNvZGVibG9jayA9ICdjb2RlYmxvY2snLCBmb3JtdWxhID0gJ2Zvcm11bGEnLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVfc3RhcnQgPSAnY29kZV9ibG9ja19zdGFydCcsIGNvZGVfZW5kID0gJ2NvZGVfYmxvY2tfZW5kJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vbmUgPSAnbm9uZScsIGZyb250bWF0dGVyPVwiZnJvbnRtYXR0ZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlPSdxdW90ZScsIGNhbGxvdXRfdGl0bGU9J2NhbGxvdXRfdGl0bGUnLCBsaXN0PSdsaXN0JywgdGFibGU9ICd0YWJsZScgfVxuXG5leHBvcnQgZW51bSBTcGFjZVN0YXRlIHtcbiAgICBub25lLFxuICAgIHNvZnQsXG4gICAgc3RyaWN0XG59XG5cbmV4cG9ydCBlbnVtIElubGluZVR5cGUge1xuICAgIHRleHQgPSAndGV4dCcsIGNvZGUgPSAnY29kZScsIGZvcm11bGEgPSAnZm9ybXVsYScsXG4gICAgd2lraWxpbmsgPSAnd2lraWxpbmsnLCBtZGxpbmsgPSBcIm1kbGlua1wiLFxuICAgIHVzZXIgPSAndXNlci1kZWZpbmVkJywgbm9uZSA9ICdub25lJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElubGluZUNoYW5nZSB7XG4gICAgdGV4dDogc3RyaW5nLFxuICAgIGJlZ2luOiBudW1iZXIsXG4gICAgZW5kOiBudW1iZXIsXG4gICAgb3JpZ2luOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBcnRpY2xlUGFydCB7XG4gICAgdHlwZTogTGluZVR5cGU7XG4gICAgYmVnaW46IG51bWJlcjtcbiAgICBlbmQ6IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElubGluZVBhcnQge1xuICAgIGNvbnRlbnQ6IHN0cmluZztcbiAgICB0eXBlOiBJbmxpbmVUeXBlO1xuICAgIGJlZ2luOiBudW1iZXI7XG4gICAgZW5kOiBudW1iZXI7XG4gICAgbGVmdFNwYWNlUmVxdWlyZTogU3BhY2VTdGF0ZTtcbiAgICByaWdodFNwYWNlUmVxdWlyZTogU3BhY2VTdGF0ZTtcbn1cblxuZXhwb3J0IGNsYXNzIExpbmVGb3JtYXRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7IH1cbiAgICBzeW50YXhUcmVlTm9kZU5hbWVUeXBlKG5hbWU6c3RyaW5nKTpJbmxpbmVUeXBle1xuICAgICAgICBpZihuYW1lLmNvbnRhaW5zKCdjb2RlJykgJiYgIW5hbWUuY29udGFpbnMoXCJsaW5rXCIpKXtcbiAgICAgICAgICAgIHJldHVybiBJbmxpbmVUeXBlLmNvZGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZihuYW1lLmNvbnRhaW5zKCdtYXRoJykpe1xuICAgICAgICAgICAgcmV0dXJuIElubGluZVR5cGUuZm9ybXVsYTtcbiAgICAgICAgfVxuICAgICAgICBlbHNle1xuICAgICAgICAgICAgcmV0dXJuIElubGluZVR5cGUudGV4dDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHBhcmFtIGxpbmVOdW06IDEtYmFzZWQgbGluZSBudW1iZXJcbiAgICBwYXJzZUxpbmVXaXRoU3ludGF4VHJlZShzdGF0ZTogRWRpdG9yU3RhdGUsIGxpbmVOdW06bnVtYmVyLCByZWdSZWdFeHA/OiBzdHJpbmcpe1xuICAgICAgICBsZXQgbGluZVBhcnRzT2ZUeHRDb2RlRm9ybXVsYTogSW5saW5lUGFydFtdID0gW107XG4gICAgICAgIGxldCBsaW5lID0gc3RhdGUuZG9jLmxpbmUobGluZU51bSk7XG4gICAgICAgIGNvbnN0IHRyZWUgPSBzeW50YXhUcmVlKHN0YXRlKTtcbiAgICAgICAgbGV0IHBvcyA9IGxpbmUuZnJvbTtcbiAgICAgICAgbGV0IHByZXZOb2RlVHlwZTpJbmxpbmVUeXBlID0gSW5saW5lVHlwZS5ub25lO1xuICAgICAgICBsZXQgcHJldkJlZ2luSWR4ID0gMDtcbiAgICAgICAgd2hpbGUocG9zPGxpbmUudG8pe1xuICAgICAgICAgICAgbGV0IG5vZGUgPSB0cmVlLnJlc29sdmUocG9zLCAxKTtcbiAgICAgICAgICAgIGxldCBjdXJOb2RlVHlwZSA9IHRoaXMuc3ludGF4VHJlZU5vZGVOYW1lVHlwZShub2RlLm5hbWUpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmKHByZXZOb2RlVHlwZT09SW5saW5lVHlwZS5ub25lKXtcbiAgICAgICAgICAgICAgICBwcmV2Tm9kZVR5cGU9Y3VyTm9kZVR5cGU7XG4gICAgICAgICAgICAgICAgcHJldkJlZ2luSWR4PTA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmKHByZXZOb2RlVHlwZT09Y3VyTm9kZVR5cGUpe31cbiAgICAgICAgICAgIGVsc2V7XG4gICAgICAgICAgICAgICAgbGluZVBhcnRzT2ZUeHRDb2RlRm9ybXVsYS5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDpsaW5lLnRleHQuc3Vic3RyaW5nKHByZXZCZWdpbklkeCwgcG9zLWxpbmUuZnJvbSksXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6cHJldk5vZGVUeXBlLFxuICAgICAgICAgICAgICAgICAgICBiZWdpbjpwcmV2QmVnaW5JZHgsXG4gICAgICAgICAgICAgICAgICAgIGVuZDpwb3MtbGluZS5mcm9tLFxuICAgICAgICAgICAgICAgICAgICBsZWZ0U3BhY2VSZXF1aXJlOlNwYWNlU3RhdGUubm9uZSxcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRTcGFjZVJlcXVpcmU6U3BhY2VTdGF0ZS5ub25lXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBwcmV2Tm9kZVR5cGUgPSBjdXJOb2RlVHlwZTtcbiAgICAgICAgICAgICAgICBwcmV2QmVnaW5JZHggPSBwb3MtbGluZS5mcm9tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdXBkYXRlIG5leHQgcG9zXG4gICAgICAgICAgICBpZiAoY3VyTm9kZVR5cGUgPT0gSW5saW5lVHlwZS50ZXh0KXtcbiAgICAgICAgICAgICAgICBwb3MrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2V7XG4gICAgICAgICAgICAgICAgcG9zID0gbm9kZS50bztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYocG9zPT1saW5lLnRvKXtcbiAgICAgICAgICAgICAgICBsaW5lUGFydHNPZlR4dENvZGVGb3JtdWxhLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50OmxpbmUudGV4dC5zdWJzdHJpbmcocHJldkJlZ2luSWR4LCBwb3MtbGluZS5mcm9tKSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTpwcmV2Tm9kZVR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGJlZ2luOnByZXZCZWdpbklkeCxcbiAgICAgICAgICAgICAgICAgICAgZW5kOnBvcy1saW5lLmZyb20sXG4gICAgICAgICAgICAgICAgICAgIGxlZnRTcGFjZVJlcXVpcmU6U3BhY2VTdGF0ZS5ub25lLFxuICAgICAgICAgICAgICAgICAgICByaWdodFNwYWNlUmVxdWlyZTpTcGFjZVN0YXRlLm5vbmVcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwibGluZSBwYXJ0czogXCIsIGxpbmVQYXJ0c09mVHh0Q29kZUZvcm11bGEpO1xuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgbGV0IHJldEFycmF5OiBJbmxpbmVQYXJ0W10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lUGFydHNPZlR4dENvZGVGb3JtdWxhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAobGluZVBhcnRzT2ZUeHRDb2RlRm9ybXVsYVtpXS50eXBlICE9IElubGluZVR5cGUudGV4dCkge1xuICAgICAgICAgICAgICAgIHJldEFycmF5LnB1c2gobGluZVBhcnRzT2ZUeHRDb2RlRm9ybXVsYVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgdGVtcEFycmF5OiBJbmxpbmVQYXJ0W107XG4gICAgICAgICAgICAgICAgaWYgKGlzUGFyYW1EZWZpbmVkKHJlZ1JlZ0V4cCkpXG4gICAgICAgICAgICAgICAgICAgIHRlbXBBcnJheSA9IHNwbGl0VGV4dFdpdGhMaW5rQW5kVXNlckRlZmluZWQobGluZVBhcnRzT2ZUeHRDb2RlRm9ybXVsYVtpXS5jb250ZW50LCByZWdSZWdFeHApO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgdGVtcEFycmF5ID0gc3BsaXRUZXh0V2l0aExpbmtBbmRVc2VyRGVmaW5lZChsaW5lUGFydHNPZlR4dENvZGVGb3JtdWxhW2ldLmNvbnRlbnQpO1xuICAgIFxuICAgICAgICAgICAgICAgIHRlbXBBcnJheS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLmJlZ2luICs9IGxpbmVQYXJ0c09mVHh0Q29kZUZvcm11bGFbaV0uYmVnaW47XG4gICAgICAgICAgICAgICAgICAgIGl0ZW0uZW5kICs9IGxpbmVQYXJ0c09mVHh0Q29kZUZvcm11bGFbaV0uYmVnaW47XG4gICAgICAgICAgICAgICAgICAgIHJldEFycmF5LnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29uc29sZS5sb2cocmV0QXJyYXkpXG4gICAgICAgIHJldHVybiByZXRBcnJheTtcbiAgICB9XG5cbiAgICBmb3JtYXRMaW5lT2ZEb2Moc3RhdGU6IEVkaXRvclN0YXRlLCBzZXR0aW5nczogRWFzeVR5cGluZ1NldHRpbmdzLCBmcm9tQjogbnVtYmVyLCB0b0I6IG51bWJlciwgaW5zZXJ0ZWRTdHI6IHN0cmluZyk6IFtUcmFuc2FjdGlvblNwZWNbXSwgVHJhbnNhY3Rpb25TcGVjXSB8IG51bGwge1xuICAgICAgICBsZXQgZG9jID0gc3RhdGUuZG9jO1xuICAgICAgICBsZXQgbGluZSA9IGRvYy5saW5lQXQoZnJvbUIpLnRleHQ7XG4gICAgICAgIGxldCByZXMgPSBudWxsXG4gICAgICAgIGlmIChpbnNlcnRlZFN0ci5jb250YWlucyhcIlxcblwiKSlcbiAgICAgICAge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0Zyb21CLCBUb0InLCBmcm9tQiwgdG9CKVxuICAgICAgICAgICAgcmVzID0gdGhpcy5mb3JtYXRMaW5lKHN0YXRlLCBkb2MubGluZUF0KGZyb21CKS5udW1iZXIsIHNldHRpbmdzLCBvZmZzZXRUb1Bvcyhkb2MsIGZyb21CKS5jaCwgb2Zmc2V0VG9Qb3MoZG9jLCBmcm9tQikuY2gpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAge1xuICAgICAgICAgICAgcmVzID0gdGhpcy5mb3JtYXRMaW5lKHN0YXRlLCBkb2MubGluZUF0KGZyb21CKS5udW1iZXIsIHNldHRpbmdzLCBvZmZzZXRUb1Bvcyhkb2MsIHRvQikuY2gsIG9mZnNldFRvUG9zKGRvYywgZnJvbUIpLmNoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzID09PW51bGwgfHwgcmVzWzJdLmxlbmd0aD09MCkgcmV0dXJuIG51bGw7XG4gICAgICAgIFxuICAgICAgICBsZXQgbmV3bGluZSA9IHN0cmluZ0luc2VydEF0KHJlc1swXSwgcmVzWzFdLCBcInxcIik7XG4gICAgICAgIC8vIGlmIChzZXR0aW5ncy5kZWJ1ZykgY29uc29sZS5sb2coXCJFYXN5VHlwaW5nOiBOZXcgTGluZSBTdHJpbmc6XCIsIG5ld2xpbmUpXG5cbiAgICAgICAgbGV0IGNoYW5nZXM6IFRyYW5zYWN0aW9uU3BlY1tdID0gW107XG4gICAgICAgIGxldCBvZmZzZXQgPSBkb2MubGluZUF0KGZyb21CKS5mcm9tO1xuXG4gICAgICAgIGZvcihsZXQgY2hhbmdlSXRlbSBvZiByZXNbMl0pXG4gICAgICAgIHtcbiAgICAgICAgICAgIGNoYW5nZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgY2hhbmdlczp7ZnJvbTogb2Zmc2V0K2NoYW5nZUl0ZW0uYmVnaW4sIHRvOm9mZnNldCtjaGFuZ2VJdGVtLmVuZCwgaW5zZXJ0OmNoYW5nZUl0ZW0udGV4dH0sIHVzZXJFdmVudDpcIkVhc3lUeXBpbmcuY2hhbmdlXCJcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluc2VydGVkU3RyLmNvbnRhaW5zKFwiXFxuXCIpKXtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiaW5zZXJ0U3RyXCIsIGluc2VydGVkU3RyKVxuICAgICAgICAgICAgcmVzWzFdKz0gaW5zZXJ0ZWRTdHIubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbY2hhbmdlcywge3NlbGVjdGlvbjp7YW5jaG9yOm9mZnNldCtyZXNbMV19LCB1c2VyRXZlbnQ6XCJFYXN5VHlwaW5nLmNoYW5nZVwifV07XG4gICAgfVxuXG4gICAgLy8gXHU4RkQ0XHU1NkRFXHU1MDNDXHVGRjFBIFtcdTY3MDBcdTdFQzhcdTc2ODRcdTg4NENcdUZGMENcdTY3MDBcdTdFQzhcdTUxNDlcdTY4MDdcdTRGNERcdTdGNkVcdUZGMENcdTUxODVcdTVCQjlcdTY1MzlcdTUzRDhdXG4gICAgLy8gcGFyYW0gbGluZU51bTogMS1iYXNlZCBsaW5lIG51bWJlclxuICAgIC8vIGN1ckNoOiBcdTUxNDlcdTY4MDdcdTU3MjhcdTVGNTNcdTUyNERcdTg4NENcdTc2ODRcdTRGNERcdTdGNkVcbiAgICAvLyBwcmV2Q2g6IFx1NTE0OVx1NjgwN1x1NTcyOFx1NTI0RFx1NEUwMFx1NjVGNlx1NTIzQlx1NTcyOFx1NUY1M1x1NTI0RFx1ODg0Q1x1NzY4NFx1NEY0RFx1N0Y2RVxuICAgIGZvcm1hdExpbmUoc3RhdGU6IEVkaXRvclN0YXRlLCBsaW5lTnVtOm51bWJlciwgc2V0dGluZ3M6IEVhc3lUeXBpbmdTZXR0aW5ncywgY3VyQ2g6IG51bWJlciwgcHJldkNoPzogbnVtYmVyKTogW3N0cmluZywgbnVtYmVyLCBJbmxpbmVDaGFuZ2VbXV0gfCBudWxsIHtcbiAgICAgICAgLy8gbmV3IE5vdGljZShcImZvcm1hdC1ub3dcIik7XG4gICAgICAgIGxldCBsaW5lID0gc3RhdGUuZG9jLmxpbmUobGluZU51bSkudGV4dDtcbiAgICAgICAgbGV0IHJlZ051bGwgPSAvXlxccyokL2c7XG4gICAgICAgIGlmIChyZWdOdWxsLnRlc3QobGluZSkpIHJldHVybiBbbGluZSwgY3VyQ2gsIFtdXTtcbiAgICAgICAgLy8gMS4gXHU1MjEyXHU1MjA2XHU0RTAwXHU4ODRDXHU2NTg3XHU1QjU3XHU3Njg0XHU1MTg1XHU5MEU4XHU0RTBEXHU1NDBDXHU2QTIxXHU1NzU3XHU1MzNBXHU1N0RGXG5cbiAgICAgICAgbGV0IGxpbmVQYXJ0cyA9IHNldHRpbmdzLlVzZXJEZWZpbmVkUmVnU3dpdGNoXG4gICAgICAgID8gdGhpcy5wYXJzZUxpbmVXaXRoU3ludGF4VHJlZShzdGF0ZSwgbGluZU51bSwgc2V0dGluZ3MuVXNlckRlZmluZWRSZWdFeHApXG4gICAgICAgIDogdGhpcy5wYXJzZUxpbmVXaXRoU3ludGF4VHJlZShzdGF0ZSwgbGluZU51bSk7XG4gICAgICAgIFxuICAgICAgICBpZiAoc2V0dGluZ3MuZGVidWcpIGNvbnNvbGUubG9nKFwibGluZSBwYXJ0c1xcblwiLCBsaW5lUGFydHMpO1xuXG4gICAgICAgIC8vIFx1NTkwN1x1NEVGRFx1NTM5Rlx1Njc2NVx1NzY4NGxpbmVQYXJ0cywgXHU2REYxXHU2MkY3XHU4RDFEXG4gICAgICAgIGxldCBsaW5lUGFydHNPcmlnaW4gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGxpbmVQYXJ0cykpO1xuICAgICAgICBsZXQgaW5saW5lQ2hhbmdlTGlzdDogSW5saW5lQ2hhbmdlW10gPSBbXTtcblxuICAgICAgICBsZXQgY3Vyc29yTGluZVBhcnRJbmRleCA9IC0xO1xuICAgICAgICBsZXQgY3Vyc29yUmVsYXRpdmVJbmRleCA9IC0xO1xuICAgICAgICBsZXQgcmVzdWx0Q3Vyc29yQ2ggPSAwOyAgICAgLy8gXHU4RjkzXHU1MUZBXHU3Njg0XHU1MTQ5XHU2ODA3XHU0RjREXHU3RjZFXG5cbiAgICAgICAgLy8gMi4gXHU2MjdFXHU1MjMwXHU1MTQ5XHU2ODA3XHU2MjQwXHU1NzI4XHU3Njg0XHU5MEU4XHU1MjA2XHVGRjBDXHU1OTgyXHU2NzlDXHU2NjJGIElubGluZVBhcnQudGV4dFx1RkYwQ1x1NTIxOVx1NTcyOFx1NTE0OVx1NjgwN1x1NTkwNFx1NjNEMlx1NTE2NSdcXDAnXHU2NzY1XHU2ODA3XHU4QkIwXHU1MTQ5XHU2ODA3XHU0RjREXHU3RjZFXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZVBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY3VyQ2ggPiBsaW5lUGFydHNbaV0uYmVnaW4gJiYgY3VyQ2ggPD0gbGluZVBhcnRzW2ldLmVuZCkge1xuICAgICAgICAgICAgICAgIGN1cnNvckxpbmVQYXJ0SW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGN1cnNvclJlbGF0aXZlSW5kZXggPSBjdXJDaCAtIGxpbmVQYXJ0c1tpXS5iZWdpbjtcbiAgICAgICAgICAgICAgICBpZiAobGluZVBhcnRzW2ldLnR5cGUgPT09IElubGluZVR5cGUudGV4dCkge1xuICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaV0uY29udGVudCA9IHN0cmluZ0luc2VydEF0KGxpbmVQYXJ0c1tpXS5jb250ZW50LCBjdXJzb3JSZWxhdGl2ZUluZGV4LCAnXFwwJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHRMaW5lID0gJyc7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICAvLyBcdTRGRERcdTVCNThcdTUyNERcdTRFMDBcdTkwRThcdTUyMDZcdTc2ODRcdTUzM0FcdTU3NTdcdTdDN0JcdTU3OEJcdUZGMENJbmxpbmVUeXBlLm5vbmUgXHU0RUUzXHU4ODY4XHU0RTAwXHU4ODRDXHU3Njg0XHU1RjAwXHU1OUNCXG4gICAgICAgIGxldCBwcmV2UGFydFR5cGU6IHN0cmluZyA9IElubGluZVR5cGUubm9uZTtcbiAgICAgICAgbGV0IHByZXZUZXh0RW5kU3BhY2VTdGF0ZSA9IFNwYWNlU3RhdGUubm9uZTtcblxuICAgICAgICAvLyAzLiBcdTkwNERcdTUzODZcdTZCQ0ZcdTRFMkFcdTg4NENcdTkwRThcdTUyMDZcdUZGMENcdThGREJcdTg4NENcdTY4M0NcdTVGMEZcdTUzMTZcdTU5MDRcdTc0MDZcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lUGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIC8vIDMuMSBcdTU5ODJcdTY3OUNcdTg4NENcdTUxODVcdTdCMkNcdTRFMDBcdTkwRThcdTUyMDZcdTRFM0FcdTY1ODdcdTY3MkNcdUZGMENcdTUyMTlcdTU5MDRcdTc0MDZcdTUzRTVcdTk5OTZcdTVCNTdcdTZCQ0RcdTU5MjdcdTUxOTlcdTc2ODRcdTkwRThcdTUyMDZcbiAgICAgICAgICAgIGlmIChpID09PSAwICYmIGxpbmVQYXJ0c1tpXS50eXBlID09PSBJbmxpbmVUeXBlLnRleHQgJiYgc2V0dGluZ3MuQXV0b0NhcGl0YWwpIHtcbiAgICAgICAgICAgICAgICAvLyAzLjEuMSBcdTU5ODJcdTY3OUMgcHJldkN1cnNvciBcdTRFMTRcdTUxNDlcdTY4MDdcdTRFMERcdTU3MjhcdTZCNjRcdTkwRThcdTUyMDZcdUZGMENcdTUyMTlcdThERjNcdThGQzdcbiAgICAgICAgICAgICAgICBpZiAoaXNQYXJhbURlZmluZWQocHJldkNoKSAmJiBjdXJzb3JMaW5lUGFydEluZGV4ICE9IDApIHsgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVnRmlyc3RTZW50ZW5jZSA9IC9eXFxzKihcXC0gKFxcW1t4IF1cXF0gKT8pP1x1MjAxQz9bYS16XFx1MDQwMVxcdTA0NTFcXHUwNDEwLVxcdTA0NGZdL2c7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZWdIZWFkZXJTZW50ZW5jZSA9IC9eKCMrIHw+KyA/fFx1MjAxQylbYS16XFx1MDQwMVxcdTA0NTFcXHUwNDEwLVxcdTA0NGZdL2c7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZXh0Y29weSA9IGxpbmVQYXJ0c1swXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWF0Y2ggPSByZWdGaXJzdFNlbnRlbmNlLmV4ZWModGV4dGNvcHkpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWF0Y2hIZWFkZXIgPSByZWdIZWFkZXJTZW50ZW5jZS5leGVjKHRleHRjb3B5KTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRzdENoYXJJbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdENoYXJJbmRleCA9IHJlZ0ZpcnN0U2VudGVuY2UubGFzdEluZGV4IC0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChtYXRjaEhlYWRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZHN0Q2hhckluZGV4ID0gcmVnSGVhZGVyU2VudGVuY2UubGFzdEluZGV4IC0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5BdXRvQ2FwaXRhbE1vZGUgPT0gV29ya01vZGUuR2xvYmFsbHkgfHwgKGlzUGFyYW1EZWZpbmVkKHByZXZDaCkgJiYgZHN0Q2hhckluZGV4ID49IHByZXZDaCAmJiBkc3RDaGFySW5kZXggPCBjdXJDaCkpIHsgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdENoYXJJbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRzdENoYXJJbmRleCAhPSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbMF0uY29udGVudCA9IHRleHRjb3B5LnN1YnN0cmluZygwLCBkc3RDaGFySW5kZXgpICsgdGV4dGNvcHkuY2hhckF0KGRzdENoYXJJbmRleCkudG9VcHBlckNhc2UoKSArIHRleHRjb3B5LnN1YnN0cmluZyhkc3RDaGFySW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3dpdGNoIChsaW5lUGFydHNbaV0udHlwZSkge1xuICAgICAgICAgICAgICAgIC8vIDMuMi4xIFx1NTkwNFx1NzQwNlx1NjU4N1x1NjcyQ1x1NTMzQVx1NTc1N1xuICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS50ZXh0OlxuICAgICAgICAgICAgICAgICAgICBsZXQgY29udGVudCA9IGxpbmVQYXJ0c1tpXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICAvLyBUZXh0LjQgXHU1OTA0XHU3NDA2XHU1M0U1XHU5OTk2XHU1QjU3XHU2QkNEXHU1OTI3XHU1MTk5XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5BdXRvQ2FwaXRhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZyA9IC9bXFwuXFw/XFwhXHUzMDAyXHVGRjAxXHVGRjFGXShbXFxzXSopW2EtelxcdTA0MDFcXHUwNDUxXFx1MDQxMC1cXHUwNDRmXS9nO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWF0Y2ggPSByZWcuZXhlYyhjb250ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEluZGV4ID0gcmVnLmxhc3RJbmRleCAtIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJwcmV2Q2gsIGN1ckNoLCBvZmZzZXQsIHRlbXBJbmRleFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHByZXZDaCwgY3VyQ2gsIG9mZnNldCwgdGVtcEluZGV4KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpc1NwYWNlRG90ID0gdGVtcEluZGV4LTI8MCB8fCBjb250ZW50LnN1YnN0cmluZyh0ZW1wSW5kZXgtMiwgdGVtcEluZGV4KT09JyAuJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3MuQXV0b0NhcGl0YWxNb2RlID09IFdvcmtNb2RlLkdsb2JhbGx5ICYmICFpc1NwYWNlRG90KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpXS5jb250ZW50ID0gY29udGVudC5zdWJzdHJpbmcoMCwgdGVtcEluZGV4KSArIGNvbnRlbnQuY2hhckF0KHRlbXBJbmRleCkudG9VcHBlckNhc2UoKSArIGNvbnRlbnQuc3Vic3RyaW5nKHJlZy5sYXN0SW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzUGFyYW1EZWZpbmVkKHByZXZDaCkgJiYgdGVtcEluZGV4ID49IHByZXZDaCAtIG9mZnNldCAmJiB0ZW1wSW5kZXggPCBjdXJDaCAtIG9mZnNldCAmJiAhaXNTcGFjZURvdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaV0uY29udGVudCA9IGNvbnRlbnQuc3Vic3RyaW5nKDAsIHRlbXBJbmRleCkgKyBjb250ZW50LmNoYXJBdCh0ZW1wSW5kZXgpLnRvVXBwZXJDYXNlKCkgKyBjb250ZW50LnN1YnN0cmluZyhyZWcubGFzdEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGxpbmVQYXJ0c1tpXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSAgIFxuXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGluc2VydFNwYWNlKGNvbnRlbnQ6IHN0cmluZywgcmVnOiBSZWdFeHAsIHByZXZDaDogbnVtYmVyLCBjdXJDaDogbnVtYmVyLCBvZmZzZXQ6IG51bWJlcik6IFtzdHJpbmcsIG51bWJlcl0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWF0Y2ggPSByZWcuZXhlYyhjb250ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEluZGV4ID0gcmVnLmxhc3RJbmRleCAtIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzUGFyYW1EZWZpbmVkKHByZXZDaCkgJiYgdGVtcEluZGV4ID49IHByZXZDaCAtIG9mZnNldCAmJiB0ZW1wSW5kZXggPCBjdXJDaCAtIG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gY29udGVudC5zdWJzdHJpbmcoMCwgdGVtcEluZGV4KSArIFwiIFwiICsgY29udGVudC5zdWJzdHJpbmcodGVtcEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyQ2ggKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2NvbnRlbnQsIGN1ckNoXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFRleHQuMSBcdTU5MDRcdTc0MDZcdTRFMkRcdTgyRjFcdTY1ODdcdTRFNEJcdTk1RjRcdTdBN0FcdTY4M0NcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLkNoaW5lc2VFbmdsaXNoU3BhY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZWcxID0gLyhbQS1aYS16XSkoW1xcdTRlMDAtXFx1OWZhNV0pL2dpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlZzIgPSAvKFtcXHU0ZTAwLVxcdTlmYTVdKShbQS1aYS16XSkvZ2k7XG4gICAgICAgICAgICAgICAgICAgICAgICBbY29udGVudCwgY3VyQ2hdID0gaW5zZXJ0U3BhY2UoY29udGVudCwgcmVnMSwgcHJldkNoLCBjdXJDaCwgb2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50LCBjdXJDaF0gPSBpbnNlcnRTcGFjZShjb250ZW50LCByZWcyLCBwcmV2Q2gsIGN1ckNoLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLkNoaW5lc2VOdW1iZXJTcGFjZSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnID0gLyhbMC05XSkoW1xcdTRlMDAtXFx1OWZhNV0pL2c7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnMSA9IC8oW1xcdTRlMDAtXFx1OWZhNV0pKFswLTldKS9nO1xuICAgICAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnQsIGN1ckNoXSA9IGluc2VydFNwYWNlKGNvbnRlbnQsIHJlZywgcHJldkNoLCBjdXJDaCwgb2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50LCBjdXJDaF0gPSBpbnNlcnRTcGFjZShjb250ZW50LCByZWcxLCBwcmV2Q2gsIGN1ckNoLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLkVuZ2xpc2hOdW1iZXJTcGFjZSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnID0gLyhbQS1aYS16XSkoXFxkKS9nO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlZzEgPSAvKFxcZCkoW0EtWmEtel0pL2c7XG4gICAgICAgICAgICAgICAgICAgICAgICBbY29udGVudCwgY3VyQ2hdID0gaW5zZXJ0U3BhY2UoY29udGVudCwgcmVnLCBwcmV2Q2gsIGN1ckNoLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnQsIGN1ckNoXSA9IGluc2VydFNwYWNlKGNvbnRlbnQsIHJlZzEsIHByZXZDaCwgY3VyQ2gsIG9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBUZXh0LjIgXHU1OTA0XHU3NDA2XHU0RTJEXHU2NTg3XHU5NUY0XHU2NUUwXHU3QTdBXHU2ODNDXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5DaGluZXNlTm9TcGFjZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlZyA9IC8oW1xcdTRlMDAtXFx1OWZhNVx1RkYwQ1x1MzAwMlx1MzAwMVx1RkYwMVx1RkYxQlx1MjAxOFx1MjAxOVx1MzAwQVx1MzAwQl0rKShcXHMrKShbXFx1NGUwMC1cXHU5ZmE1XHVGRjBDXHUzMDAyXHUzMDAxXHVGRjAxXHVGRjFCXHUyMDE4XHUyMDE5XHUzMDBBXHUzMDBCXSspL2c7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVnLmV4ZWMoY29udGVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaV0uY29udGVudCA9IGNvbnRlbnQucmVwbGFjZShyZWcsIFwiJDEkM1wiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBcdTY4MDdcdTcwQjlcdTRFMEVcdTY1ODdcdTY3MkNcdTdBN0FcdTY4M0NcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLlB1bmN0dWF0aW9uU3BhY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRleHQuMyBcdTU5MDRcdTc0MDZcdTY4MDdcdTcwQjlcdTRFMEVcdTY1ODdcdTY3MkNcdTdBN0FcdTY4M0NcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmKHNldHRpbmdzLkVuZ2xpc2hTcGFjZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnID0gLyhbLFxcLjtcXD9cXCFcXCldKShbMC05QS1aYS16XFx1MDQwMVxcdTA0NTFcXHUwNDEwLVxcdTA0NGZcXHU0ZTAwLVxcdTlmYTVdKXwoW0EtWmEtejAtOVxcdTRlMDAtXFx1OWZhNTosXFwuXFw/XFwhJ1wiXSspKFxcKCl8WyxcXC47XFw/OiFdW1xcdTRlMDAtXFx1OWZhNV0vZ2k7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG1hdGNoID0gcmVnLmV4ZWMoY29udGVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWF0Y2gpIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEluZGV4ID0gcmVnLmxhc3RJbmRleCAtIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpc1NwYWNlRG90ID0gJyEuPzssJy5jb250YWlucyhjb250ZW50LmNoYXJBdCh0ZW1wSW5kZXgtMSkpICYmICgodGVtcEluZGV4LTI8MCAmJiBpPT0wKSB8fCBjb250ZW50LmNoYXJBdCh0ZW1wSW5kZXgtMik9PScgJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpc051bVB1bmNOdW0gPSAvWywuXVxcZC8udGVzdChjb250ZW50LnN1YnN0cmluZyh0ZW1wSW5kZXgtMSwgdGVtcEluZGV4KzEpKSAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGVtcEluZGV4LTI8MCB8fCAvXFxkLy50ZXN0KGNvbnRlbnQuY2hhckF0KHRlbXBJbmRleC0yKSkpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLlB1bmN0dWF0aW9uU3BhY2VNb2RlID09IFdvcmtNb2RlLkdsb2JhbGx5ICYmICFpc1NwYWNlRG90ICYmICFpc051bVB1bmNOdW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnN1YnN0cmluZygwLCB0ZW1wSW5kZXgpICsgXCIgXCIgKyBjb250ZW50LnN1YnN0cmluZyh0ZW1wSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzUGFyYW1EZWZpbmVkKHByZXZDaCkgJiYgdGVtcEluZGV4ID49IHByZXZDaCAtIG9mZnNldCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiB0ZW1wSW5kZXggPCBjdXJDaCAtIG9mZnNldCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhaXNTcGFjZURvdCAmJiAhaXNOdW1QdW5jTnVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gY29udGVudC5zdWJzdHJpbmcoMCwgdGVtcEluZGV4KSArIFwiIFwiICsgY29udGVudC5zdWJzdHJpbmcodGVtcEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ckNoICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBcdTUzNTVcdTcyRUNcdTU5MDRcdTc0MDZcdTUxOTJcdTUzRjdcdTU0MEVcdTY1ODdcdTY3MkNcdTc2ODRcdTgxRUFcdTUyQThcdTdBN0FcdTY4M0NcdUZGMENcdTRFM0FcdTRFODZcdTUxN0NcdTVCQjkgOmVtb2ppOiBcdTY4M0NcdTVGMEZcdTc2ODRcdThGOTNcdTUxNjVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnMiA9IC8oOikoW0EtWmEtejAtOV9dK1sgLFxcLlxcP1xcXFxcXC87J1wiXHVGRjBDXHUzMDAyXHVGRjFGXHVGRjFCXHUyMDE4XHUyMDFDXHUyMDFEXHUyMDE5XHUzMDAxXFxbXFxdXFwtXFx7XFx9XSkvZ2k7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVBhcnRzW2ldLmNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UocmVnMiwgXCIkMSAkMlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnMyA9IC8oOikoW1wiJ10pL2c7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVBhcnRzW2ldLmNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UocmVnMywgXCIkMSAkMlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBUZXh0LjcgXHU1Rjk3XHU1MjMwXHU2NTg3XHU2NzJDXHU5MEU4XHU1MjA2XHU2NjJGXHU1NDI2XHU0RUU1XHU3QTdBXHU3NjdEXHU3QjI2XHU1RjAwXHU1OUNCXHU2MjE2XHU3RUQzXHU2NzVGXHVGRjBDXHU3NTI4XHU2NzY1XHU1MjI0XHU2NUFEXHU1NDBFXHU3RUVEXHU2NTg3XHU2NzJDXHU1MjREXHU1NDBFXHU2NjJGXHU1NDI2XHU5NzAwXHU4OTgxXHU2REZCXHU1MkEwXHU3QTdBXHU2ODNDXG4gICAgICAgICAgICAgICAgICAgIGxldCByZWdTdHJpY3RTcGFjZVN0YXJ0ID0gL15cXDA/XFxzLztcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlZ1N0cmljdFNwYWNlRW5kID0gL1xcc1xcMD8kLztcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlZ1N0YXJ0V2l0aFNwYWNlID0gL15cXDA/W1xccyxcXC47XFw/XFwhXHVGRjBDXHUzMDAyXHVGRjFCXHUzMDBCXHVGRjFGXHVGRjFBOlx1RkYwMX5cXCpcdTMwMDFcdUZGMDhcdUZGMDlcIlx1MjAxRFxcW1xcXVxcKVxce1xcfV0vO1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVnRW5kV2l0aFNwYWNlID0gL1tcXHNcdUZGMENcdTMwMDJcdTMwMDFcdUZGMUFcdUZGMUJcdUZGMUZcdUZGMDFcdUZGMDhcdUZGMDl+XFwqXCJcdTMwMEFcdTIwMUNcXFtcXF1cXChcXHtcXH1dXFwwPyQvO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdHh0U3RhcnRTcGFjZVNhdGUgPSBTcGFjZVN0YXRlLm5vbmU7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0eHRFbmRTcGFjZVN0YXRlID0gU3BhY2VTdGF0ZS5ub25lO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVnU3RhcnRXaXRoU3BhY2UudGVzdChjb250ZW50KXx8Y29udGVudC5zdGFydHNXaXRoKFwiPGJyPlwiKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ1N0cmljdFNwYWNlU3RhcnQudGVzdChjb250ZW50KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eHRTdGFydFNwYWNlU2F0ZSA9IFNwYWNlU3RhdGUuc3RyaWN0XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHh0U3RhcnRTcGFjZVNhdGUgPSBTcGFjZVN0YXRlLnNvZnRcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWdFbmRXaXRoU3BhY2UudGVzdChjb250ZW50KSB8fCBjb250ZW50LmVuZHNXaXRoKFwiPGJyPlwiKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ1N0cmljdFNwYWNlRW5kLnRlc3QoY29udGVudCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHh0RW5kU3BhY2VTdGF0ZSA9IFNwYWNlU3RhdGUuc3RyaWN0O1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR4dEVuZFNwYWNlU3RhdGUgPSBTcGFjZVN0YXRlLnNvZnQ7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBUZXh0LjggXHU2ODM5XHU2MzZFXHU1MjREXHU0RTAwXHU5MEU4XHU1MjA2XHU3Njg0XHU1MzNBXHU1NzU3XHU3QzdCXHU1NzhCXHU1OTA0XHU3NDA2XHU3QTdBXHU2ODNDXHU2REZCXHU1MkEwXHU3Njg0XHU5NUVFXHU5ODk4XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocHJldlBhcnRUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUubm9uZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5jb2RlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVDb2RlU3BhY2VNb2RlID4gdHh0U3RhcnRTcGFjZVNhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVBhcnRzW2ldLmNvbnRlbnQgPSAnICcgKyBjb250ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLmZvcm11bGE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLklubGluZUZvcm11bGFTcGFjZU1vZGUgPiB0eHRTdGFydFNwYWNlU2F0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaV0uY29udGVudCA9ICcgJyArIGNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBsaW5lUGFydHNbaV0uY29udGVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUud2lraWxpbms6XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUubWRsaW5rOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2V0dGluZ3MuSW5saW5lTGlua1NtYXJ0U3BhY2UgJiYgc2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZSA+IHR4dFN0YXJ0U3BhY2VTYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpXS5jb250ZW50ID0gJyAnICsgY29udGVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGxpbmVQYXJ0c1tpXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChzZXR0aW5ncy5JbmxpbmVMaW5rU21hcnRTcGFjZSAmJiB0eHRTdGFydFNwYWNlU2F0ZSA9PSBTcGFjZVN0YXRlLm5vbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNoYXJBdFRleHRCZWdpbiA9IGNvbnRlbnQuY2hhckF0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnTWRMaW5rRW5kID0gL1xcXS87XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjaGFyQXRMaW5rRW5kSW5kZXggPSBsaW5lUGFydHNbaSAtIDFdLmNvbnRlbnQuc2VhcmNoKHJlZ01kTGlua0VuZCkgLSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2hhckF0TGlua0VuZCA9IGxpbmVQYXJ0c1tpIC0gMV0uY29udGVudC5jaGFyQXQoY2hhckF0TGlua0VuZEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJBdExpbmtFbmQgPT09ICdbJykgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0d29OZWlnaGJvckNoYXJzID0gY2hhckF0TGlua0VuZCArIGNoYXJBdFRleHRCZWdpbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlZ05vdE5lZWRTcGFjZSA9IC9bXFx1NGUwMC1cXHU5ZmE1XHVGRjBDXHUzMDAyXHVGRjFGXHVGRjFBXHVGRjFCXHUyMDFEXHUyMDFDXHUyMDE5XHUyMDE4LVx1RkYwOX1dW1xcdTRlMDAtXFx1OWZhNV0vZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWdOb3ROZWVkU3BhY2UudGVzdCh0d29OZWlnaGJvckNoYXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVBhcnRzW2ldLmNvbnRlbnQgPSAnICcgKyBjb250ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGxpbmVQYXJ0c1tpXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLnVzZXI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVQYXJ0c1tpIC0gMV0ucmlnaHRTcGFjZVJlcXVpcmUgPiB0eHRTdGFydFNwYWNlU2F0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaV0uY29udGVudCA9ICcgJyArIGNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBsaW5lUGFydHNbaV0uY29udGVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBUZXh0LjkgXHU1OTgyXHU2NzlDXHU1MTQ5XHU2ODA3XHU1NzI4XHU4QkU1XHU1MzNBXHU1NzU3XHVGRjBDXHU1MjE5XHU4QkExXHU3Qjk3XHU2NzAwXHU3RUM4XHU1MTQ5XHU2ODA3XHU3Njg0XHU0RjREXHU3RjZFXG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09PSBjdXJzb3JMaW5lUGFydEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVnID0gJ1xcMCc7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbiA9IGNvbnRlbnQuc2VhcmNoKHJlZylcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEN1cnNvckNoID0gb2Zmc2V0ICsgbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFx1NTIyMFx1OTY2NCBcXDBcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpXS5jb250ZW50ID0gc3RyaW5nRGVsZXRlQXQoY29udGVudCwgbik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9IGxpbmVQYXJ0c1tpXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gbGluZVBhcnRzW2ldLmNvbnRlbnQubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBwcmV2UGFydFR5cGUgPSBJbmxpbmVUeXBlLnRleHQ7XG4gICAgICAgICAgICAgICAgICAgIHByZXZUZXh0RW5kU3BhY2VTdGF0ZSA9IHR4dEVuZFNwYWNlU3RhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIC8vIDMuMi4yIFx1NTkwNFx1NzQwNlx1ODg0Q1x1NTE4NVx1NEVFM1x1NzgwMVx1NTc1N1x1OTBFOFx1NTIwNlxuICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5jb2RlOlxuICAgICAgICAgICAgICAgICAgICAvLyBDb2RlLjEgXHU2ODM5XHU2MzZFXHU1MjREXHU0RTAwXHU1MzNBXHU1NzU3XHU3QzdCXHU1NzhCXHU1NDhDc2V0dGluZ3NcdTZERkJcdTUyQTBcdTdBN0FcdTY4M0NcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHByZXZQYXJ0VHlwZSlcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLm5vbmU6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUudGV4dDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3MuSW5saW5lQ29kZVNwYWNlTW9kZSA+IHByZXZUZXh0RW5kU3BhY2VTdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpLTFdLmNvbnRlbnQgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLmNvZGU6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLklubGluZUNvZGVTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6JyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOicnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUuZm9ybXVsYTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3MuSW5saW5lQ29kZVNwYWNlTW9kZT5TcGFjZVN0YXRlLm5vbmUgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLklubGluZUZvcm11bGFTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6JyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOicnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUubWRsaW5rOlxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLndpa2lsaW5rOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVDb2RlU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZT5TcGFjZVN0YXRlLm5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmVDaGFuZ2VMaXN0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDonICcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW46IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46JydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS51c2VyOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVDb2RlU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaS0xXS5yaWdodFNwYWNlUmVxdWlyZT5TcGFjZVN0YXRlLm5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmVDaGFuZ2VMaXN0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDonICcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW46IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46JydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBDb2RlLjIgXHU1OTgyXHU2NzlDXHU1MTQ5XHU2ODA3XHU1NzI4XHU4QkU1XHU1MzNBXHU1NzU3XHVGRjBDXHU1MjE5XHU4QkExXHU3Qjk3XHU2NzAwXHU3RUM4XHU1MTQ5XHU2ODA3XHU3Njg0XHU0RjREXHU3RjZFXG4gICAgICAgICAgICAgICAgICAgIGlmKGkgPT09IGN1cnNvckxpbmVQYXJ0SW5kZXgpXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEN1cnNvckNoID0gb2Zmc2V0ICsgY3Vyc29yUmVsYXRpdmVJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBDb2RlLjMgXHU1M0Q4XHU5MUNGXHU2NkY0XHU2NUIwXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSBsaW5lUGFydHNbaV0uY29udGVudC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIHByZXZQYXJ0VHlwZSA9IElubGluZVR5cGUuY29kZTtcbiAgICAgICAgICAgICAgICAgICAgcHJldlRleHRFbmRTcGFjZVN0YXRlID0gU3BhY2VTdGF0ZS5ub25lO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAvLyAzLjIuMyBcdTU5MDRcdTc0MDZcdTg4NENcdTUxODVcdTUxNkNcdTVGMEZcdTc2ODRcdTkwRThcdTUyMDZcbiAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUuZm9ybXVsYTpcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVQYXJ0c1tpXS5jb250ZW50ID09IFwiJFxcXFxxcXVhZCRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldlBhcnRUeXBlID0gSW5saW5lVHlwZS50ZXh0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldlRleHRFbmRTcGFjZVN0YXRlID0gU3BhY2VTdGF0ZS5zdHJpY3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBGb3JtdWxhLjEgXHU2ODM5XHU2MzZFXHU1MjREXHU0RTAwXHU1MzNBXHU1NzU3XHU3QzdCXHU1NzhCXHU1NDhDc2V0dGluZ3NcdTZERkJcdTUyQTBcdTdBN0FcdTY4M0NcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHByZXZQYXJ0VHlwZSlcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLm5vbmU6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUudGV4dDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3MuSW5saW5lRm9ybXVsYVNwYWNlTW9kZT5wcmV2VGV4dEVuZFNwYWNlU3RhdGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaS0xXS5jb250ZW50ICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5jb2RlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVGb3JtdWxhU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncy5JbmxpbmVDb2RlU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZUNoYW5nZUxpc3QucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OicgJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbjogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjonJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLmZvcm11bGE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLklubGluZUNvZGVTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6JyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOicnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUubWRsaW5rOlxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLndpa2lsaW5rOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVGb3JtdWxhU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZT5TcGFjZVN0YXRlLm5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmVDaGFuZ2VMaXN0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDonICcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW46IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46JydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS51c2VyOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVGb3JtdWxhU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaS0xXS5yaWdodFNwYWNlUmVxdWlyZT5TcGFjZVN0YXRlLm5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmVDaGFuZ2VMaXN0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDonICcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW46IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46JydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBGb3JtdWxhLjIgXHU1OTgyXHU2NzlDXHU1MTQ5XHU2ODA3XHU1NzI4XHU4QkU1XHU1MzNBXHU1NzU3XHVGRjBDXHU1MjE5XHU4QkExXHU3Qjk3XHU2NzAwXHU3RUM4XHU1MTQ5XHU2ODA3XHU3Njg0XHU0RjREXHU3RjZFXG4gICAgICAgICAgICAgICAgICAgIGlmKGkgPT09IGN1cnNvckxpbmVQYXJ0SW5kZXgpXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEN1cnNvckNoID0gb2Zmc2V0ICsgY3Vyc29yUmVsYXRpdmVJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBGb3JtdWxhLjMgXHU1M0Q4XHU5MUNGXHU2NkY0XHU2NUIwXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gbGluZVBhcnRzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSBsaW5lUGFydHNbaV0uY29udGVudC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIHByZXZQYXJ0VHlwZSA9IElubGluZVR5cGUuZm9ybXVsYTtcbiAgICAgICAgICAgICAgICAgICAgcHJldlRleHRFbmRTcGFjZVN0YXRlID0gU3BhY2VTdGF0ZS5ub25lO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5tZGxpbms6XG4gICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLndpa2lsaW5rOlxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2gocHJldlBhcnRUeXBlKVxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUubm9uZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS50ZXh0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2VGV4dEVuZFNwYWNlU3RhdGU+c2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZSkgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLklubGluZUxpbmtTcGFjZU1vZGU9PVNwYWNlU3RhdGUuc3RyaWN0ICYmIHByZXZUZXh0RW5kU3BhY2VTdGF0ZTxTcGFjZVN0YXRlLnN0cmljdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpLTFdLmNvbnRlbnQgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNldHRpbmdzLklubGluZUxpbmtTbWFydFNwYWNlICYmIHByZXZUZXh0RW5kU3BhY2VTdGF0ZT09U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlZ05vTmVlZFNwYWNlID0gL1tcXHU0ZTAwLVxcdTlmYTVdW1xcdTRlMDAtXFx1OWZhNV0vZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNoYXJBdFRleHRFbmQgPSBsaW5lUGFydHNbaS0xXS5jb250ZW50LmNoYXJBdChsaW5lUGFydHNbaS0xXS5jb250ZW50Lmxlbmd0aC0xKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNoYXJBdExpbmtCZWdpbjpzdHJpbmcgPSBcIlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZVBhcnRzW2ldLnR5cGU9PUlubGluZVR5cGUud2lraWxpbmspXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZWdBbGlhcyA9IC9cXHwvO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNoYXJPZkFsaWFzQmVnaW4gPSBsaW5lUGFydHNbaV0uY29udGVudC5zZWFyY2gocmVnQWxpYXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJjaGFyT2ZBbGlhc0JlZ2luXCIsY2hhck9mQWxpYXNCZWdpbilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBiZWdpbkluZGV4ID0gMjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxpbmVQYXJ0c1tpXS5jb250ZW50LmNoYXJBdCgwKT09PSchJykgYmVnaW5JbmRleD0zO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhck9mQWxpYXNCZWdpbiE9LTEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW5JbmRleCA9IGNoYXJPZkFsaWFzQmVnaW4rMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYobGluZVBhcnRzW2ldLmNvbnRlbnQuY2hhckF0KGJlZ2luSW5kZXgpPT0nIycpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luSW5kZXggKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhckF0TGlua0JlZ2luID0gbGluZVBhcnRzW2ldLmNvbnRlbnQuY2hhckF0KGJlZ2luSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJiZWdpbkluZGV4XCIsIGJlZ2luSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hhckF0TGlua0JlZ2luPT0nXScpIGJyZWFrOyAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlZ01kTGlua0JlZ2luID0gL1xcWy87XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2hhckF0TGlua0JlZ2luSW5kZXggPSBsaW5lUGFydHNbaV0uY29udGVudC5zZWFyY2gocmVnTWRMaW5rQmVnaW4pKzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQXRMaW5rQmVnaW4gPSBsaW5lUGFydHNbaV0uY29udGVudC5jaGFyQXQoY2hhckF0TGlua0JlZ2luSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hhckF0TGlua0JlZ2luPT09J10nKSBicmVhazsgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0d29OZWlnaGJvckNoYXJzID0gY2hhckF0VGV4dEVuZCtjaGFyQXRMaW5rQmVnaW47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFyZWdOb05lZWRTcGFjZS50ZXN0KHR3b05laWdoYm9yQ2hhcnMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaS0xXS5jb250ZW50ICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZighc2V0dGluZ3MuSW5saW5lTGlua1NtYXJ0U3BhY2UgJiYgc2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZT5wcmV2VGV4dEVuZFNwYWNlU3RhdGUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lUGFydHNbaS0xXS5jb250ZW50ICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5jb2RlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy5JbmxpbmVMaW5rU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncy5JbmxpbmVDb2RlU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZUNoYW5nZUxpc3QucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OicgJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbjogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjonJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLmZvcm11bGE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLklubGluZUxpbmtTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuSW5saW5lRm9ybXVsYVNwYWNlTW9kZT5TcGFjZVN0YXRlLm5vbmUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmVDaGFuZ2VMaXN0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDonICcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW46IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGxpbmVQYXJ0c1tpXS5iZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46JydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSAnICc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5tZGxpbms6XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUud2lraWxpbms6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzLklubGluZUxpbmtTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6JyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOicnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUudXNlcjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZVBhcnRzW2ktMV0ucmlnaHRTcGFjZVJlcXVpcmU+U3BhY2VTdGF0ZS5ub25lICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLklubGluZUxpbmtTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6JyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOicnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gTGluay4yIFx1NTk4Mlx1Njc5Q1x1OEJFNVx1NTMzQVx1NTc1N1x1NjcwOVx1NTE0OVx1NjgwN1x1RkYwQ1x1NTIxOVx1OEJBMVx1N0I5N1x1NjcwMFx1N0VDOFx1NTE0OVx1NjgwN1x1NEY0RFx1N0Y2RVxuICAgICAgICAgICAgICAgICAgICBpZihpID09PSBjdXJzb3JMaW5lUGFydEluZGV4KVxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRDdXJzb3JDaCA9IG9mZnNldCArIGN1cnNvclJlbGF0aXZlSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gTGluay4zIFx1NjZGNFx1NjVCMFx1NTNEOFx1OTFDRlxuICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9IGxpbmVQYXJ0c1tpXS5jb250ZW50O1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gbGluZVBhcnRzW2ldLmNvbnRlbnQubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBwcmV2UGFydFR5cGUgPSBsaW5lUGFydHNbaV0udHlwZTtcbiAgICAgICAgICAgICAgICAgICAgcHJldlRleHRFbmRTcGFjZVN0YXRlID0gU3BhY2VTdGF0ZS5ub25lO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAvLyAzLjIuNSBcdTU5MDRcdTc0MDZcdTc1MjhcdTYyMzdcdTgxRUFcdTVCOUFcdTRFNDlcdTUzM0FcdTU3NTdcdTc2ODRcdTkwRThcdTUyMDZcbiAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUudXNlcjpcbiAgICAgICAgICAgICAgICAgICAgLy8gVXNlci4xIFx1NjgzOVx1NjM2RVx1NTI0RFx1NEUwMFx1NTMzQVx1NTc1N1x1N0M3Qlx1NTc4Qlx1NTQ4Q3NldHRpbmdzXHU2REZCXHU1MkEwXHU3QTdBXHU2ODNDXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaChwcmV2UGFydFR5cGUpXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS5ub25lOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLnRleHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVQYXJ0c1tpXS5sZWZ0U3BhY2VSZXF1aXJlPnByZXZUZXh0RW5kU3BhY2VTdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpLTFdLmNvbnRlbnQgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLmNvZGU6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVQYXJ0c1tpXS5sZWZ0U3BhY2VSZXF1aXJlPlNwYWNlU3RhdGUubm9uZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncy5JbmxpbmVDb2RlU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZUNoYW5nZUxpc3QucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OicgJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbjogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjonJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLmZvcm11bGE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVQYXJ0c1tpXS5sZWZ0U3BhY2VSZXF1aXJlPlNwYWNlU3RhdGUubm9uZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncy5JbmxpbmVGb3JtdWxhU3BhY2VNb2RlPlNwYWNlU3RhdGUubm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZUNoYW5nZUxpc3QucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OicgJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbjogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjonJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJbmxpbmVUeXBlLm1kbGluazpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSW5saW5lVHlwZS53aWtpbGluazpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZVBhcnRzW2ldLmxlZnRTcGFjZVJlcXVpcmU+U3BhY2VTdGF0ZS5ub25lICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLklubGluZUxpbmtTcGFjZU1vZGU+U3BhY2VTdGF0ZS5ub25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6JyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiBsaW5lUGFydHNbaV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luOicnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpbmUgKz0gJyAnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElubGluZVR5cGUudXNlcjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGluZVBhcnRzW2ldLmxlZnRTcGFjZVJlcXVpcmU+U3BhY2VTdGF0ZS5ub25lICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVQYXJ0c1tpLTFdLnJpZ2h0U3BhY2VSZXF1aXJlPlNwYWNlU3RhdGUubm9uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZUNoYW5nZUxpc3QucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OicgJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbjogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogbGluZVBhcnRzW2ldLmJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjonJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaW5lICs9ICcgJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFVzZXIuMiBcdTU5ODJcdTY3OUNcdThCRTVcdTUzM0FcdTU3NTdcdTY3MDlcdTUxNDlcdTY4MDdcdUZGMENcdTUyMTlcdThCQTFcdTdCOTdcdTY3MDBcdTdFQzhcdTUxNDlcdTY4MDdcdTRGNERcdTdGNkVcbiAgICAgICAgICAgICAgICAgICAgaWYoaSA9PT0gY3Vyc29yTGluZVBhcnRJbmRleClcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0Q3Vyc29yQ2ggPSBvZmZzZXQgKyBjdXJzb3JSZWxhdGl2ZUluZGV4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIExpbmsuMyBcdTY2RjRcdTY1QjBcdTUzRDhcdTkxQ0ZcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGluZSArPSBsaW5lUGFydHNbaV0uY29udGVudDtcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGxpbmVQYXJ0c1tpXS5jb250ZW50Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgcHJldlBhcnRUeXBlID0gSW5saW5lVHlwZS51c2VyO1xuICAgICAgICAgICAgICAgICAgICBwcmV2VGV4dEVuZFNwYWNlU3RhdGUgPSBTcGFjZVN0YXRlLm5vbmU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yKGxldCBpPTA7aTxsaW5lUGFydHMubGVuZ3RoO2krKylcbiAgICAgICAge1xuICAgICAgICAgICAgaWYobGluZVBhcnRzW2ldLnR5cGUgPT09IElubGluZVR5cGUudGV4dCAmJiBsaW5lUGFydHNbaV0uY29udGVudCE9bGluZVBhcnRzT3JpZ2luW2ldLmNvbnRlbnQpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaW5saW5lQ2hhbmdlTGlzdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBsaW5lUGFydHNbaV0uY29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luOiBsaW5lUGFydHNPcmlnaW5baV0uYmVnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGxpbmVQYXJ0c09yaWdpbltpXS5lbmQsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46IGxpbmVQYXJ0c09yaWdpbltpXS5jb250ZW50XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgaW5saW5lQ2hhbmdlTGlzdCA9IGlubGluZUNoYW5nZUxpc3Quc29ydCgoYSwgYik6bnVtYmVyPT5hLmJlZ2luLWIuYmVnaW4pO1xuICAgICAgICByZXR1cm4gW3Jlc3VsdExpbmUsIHJlc3VsdEN1cnNvckNoLCBpbmxpbmVDaGFuZ2VMaXN0XTtcbiAgICB9XG4gICAgXG59XG5cblxuZXhwb3J0IGNsYXNzIE1hcmtkb3duUGFyc2Vye1xuICAgIGNvbnN0cnVjdG9yKCl7fVxuXG59XG5cbmZ1bmN0aW9uIG1hdGNoV2l0aFJlZyh0ZXh0OiBzdHJpbmcsIHJlZ0V4cDogUmVnRXhwLCB0eXBlOiBJbmxpbmVUeXBlLCBpbmxpbmVUeXBlQXJyYXk6IElubGluZVBhcnRbXSxcbiAgICBjaGVja0FycmF5ID0gZmFsc2UsIGxlZnRTcGFjZVJlOiBTcGFjZVN0YXRlID0gU3BhY2VTdGF0ZS5ub25lLCByaWdodFNwYWNlUmU6IFNwYWNlU3RhdGUgPSBTcGFjZVN0YXRlLm5vbmUpOiBJbmxpbmVQYXJ0W10ge1xuICAgIGxldCByZXRBcnJheSA9IGlubGluZVR5cGVBcnJheTtcbiAgICBsZXQgbWF0Y2hBcnJheTogSW5saW5lUGFydFtdID0gW107XG4gICAgcmV0QXJyYXkgPSByZXRBcnJheS5zb3J0KChhLCBiKTogbnVtYmVyID0+IGEuYmVnaW4gLSBiLmJlZ2luKTtcbiAgICAvLyBjb25zb2xlLmxvZygnYmVmb3JlLS0tLS0tLS0tLS1cXG4nLHJldEFycmF5KVxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGxldCBtYXRjaCA9IHJlZ0V4cC5leGVjKHRleHQpO1xuICAgICAgICBpZiAoIW1hdGNoKSBicmVhaztcbiAgICAgICAgbGV0IHZhbGlkID0gdHJ1ZTtcbiAgICAgICAgLy8gXHU2OEMwXHU2N0U1XHU1MUIyXHU3QTgxXG4gICAgICAgIGlmIChjaGVja0FycmF5KSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYocmVnRXhwLmxhc3RJbmRleD5yZXRBcnJheVtpXS5iZWdpbiAmJiByZXRBcnJheVtpXS5lbmQ+bWF0Y2guaW5kZXgpe1xuICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF2YWxpZCkgY29udGludWU7XG4gICAgICAgIG1hdGNoQXJyYXkucHVzaChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiBtYXRjaFswXSxcbiAgICAgICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgICAgIGJlZ2luOiBtYXRjaC5pbmRleCxcbiAgICAgICAgICAgICAgICBlbmQ6IHJlZ0V4cC5sYXN0SW5kZXgsXG4gICAgICAgICAgICAgICAgbGVmdFNwYWNlUmVxdWlyZTogbGVmdFNwYWNlUmUsXG4gICAgICAgICAgICAgICAgcmlnaHRTcGFjZVJlcXVpcmU6IHJpZ2h0U3BhY2VSZVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cbiAgICByZXRBcnJheSA9IHJldEFycmF5LmNvbmNhdChtYXRjaEFycmF5KTtcbiAgICAvLyBjb25zb2xlLmxvZygnQWZ0ZXI9PT09PT09PT09PVxcbicsIHJldEFycmF5KTtcbiAgICByZXR1cm4gcmV0QXJyYXk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoV2l0aEFiYnIodGV4dDogc3RyaW5nLCB0eXBlOiBJbmxpbmVUeXBlLCBpbmxpbmVUeXBlQXJyYXk6IElubGluZVBhcnRbXSwgY2hlY2tBcnJheSA9IGZhbHNlKXtcbiAgICBsZXQgcmV0QXJyYXkgPSBpbmxpbmVUeXBlQXJyYXk7XG4gICAgbGV0IG1hdGNoQXJyYXk6IElubGluZVBhcnRbXSA9IFtdO1xuICAgIHJldEFycmF5ID0gcmV0QXJyYXkuc29ydCgoYSwgYik6IG51bWJlciA9PiBhLmJlZ2luIC0gYi5iZWdpbik7XG4gICAgbGV0IHJlZ0FiYnIgPSAvKFthLXpBLVpdXFwuKSsvZztcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBsZXQgbWF0Y2ggPSByZWdBYmJyLmV4ZWModGV4dCk7XG4gICAgICAgIGlmICghbWF0Y2gpIGJyZWFrO1xuICAgICAgICBsZXQgdmFsaWQgPSB0cnVlO1xuICAgICAgICBsZXQgaXNJbkJsb2NrQmVnaW46Ym9vbGVhbiA9IChtYXRjaC5pbmRleD09MCk7XG4gICAgICAgIC8vIFx1NjhDMFx1NjdFNVx1NTFCMlx1N0E4MVxuICAgICAgICBpZiAoY2hlY2tBcnJheSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmKG1hdGNoLmluZGV4ID09IHJldEFycmF5W2ldLmVuZCl7XG4gICAgICAgICAgICAgICAgICAgIGlzSW5CbG9ja0JlZ2luID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYocmVnQWJici5sYXN0SW5kZXg+cmV0QXJyYXlbaV0uYmVnaW4gJiYgcmV0QXJyYXlbaV0uZW5kPm1hdGNoLmluZGV4KXtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmKCFpc0luQmxvY2tCZWdpbiAmJiB2YWxpZClcbiAgICAgICAge1xuICAgICAgICAgICAgbGV0IHJlZ0NoYXIgPSAvW2EtekEtWjAtOV0vO1xuICAgICAgICAgICAgaWYocmVnQ2hhci50ZXN0KHRleHQuY2hhckF0KG1hdGNoLmluZGV4LTEpKSl7XG4gICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmFsaWQpIGNvbnRpbnVlO1xuICAgICAgICBtYXRjaEFycmF5LnB1c2goXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29udGVudDogbWF0Y2hbMF0sXG4gICAgICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICAgICAgICBiZWdpbjogbWF0Y2guaW5kZXgsXG4gICAgICAgICAgICAgICAgZW5kOiByZWdBYmJyLmxhc3RJbmRleCxcbiAgICAgICAgICAgICAgICBsZWZ0U3BhY2VSZXF1aXJlOiBTcGFjZVN0YXRlLm5vbmUsXG4gICAgICAgICAgICAgICAgcmlnaHRTcGFjZVJlcXVpcmU6IFNwYWNlU3RhdGUubm9uZVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cbiAgICByZXRBcnJheSA9IHJldEFycmF5LmNvbmNhdChtYXRjaEFycmF5KTtcbiAgICAvLyBjb25zb2xlLmxvZygnQWZ0ZXI9PT09PT09PT09PVxcbicsIHJldEFycmF5KTtcbiAgICByZXR1cm4gcmV0QXJyYXk7XG59XG5cbi8qKlxuICogXHU1MjA2XHU1MjcyXHU0RTAwXHU4ODRDXHU2NTg3XHU2NzJDXHU0RTJEXHU3Njg0XHU5NEZFXHU2M0E1XHU1NDhDXHU3NTI4XHU2MjM3XHU4MUVBXHU1QjlBXHU0RTQ5XHU3Njg0XHU2QjYzXHU1MjE5XHU5MEU4XHU1MjA2XHVGRjBDXHU1Rjk3XHU1MjMwIElubGluZVBhcnQgXHU3Njg0XHU0RTBEXHU1NDBDXHU1MzNBXHU1N0RGXG4gKi9cbmZ1bmN0aW9uIHNwbGl0VGV4dFdpdGhMaW5rQW5kVXNlckRlZmluZWQodGV4dDogc3RyaW5nLCByZWdFeHBzPzogc3RyaW5nKTogSW5saW5lUGFydFtdIHtcbiAgICBsZXQgcmV0QXJyYXk6IElubGluZVBhcnRbXSA9IFtdO1xuICAgIGxldCByZWdXaWtpTGluayA9IC9cXCF7MCwyfVxcW1xcW1teXFxbXFxdXSo/XFxdXFxdL2c7XG4gICAgbGV0IHJlZ01kTGluayA9IC9cXCF7MCwyfVxcW1teXFxbXFxdXSo/XFxdXFwoW15cXHNcXClcXChcXFtcXF1cXHtcXH0nXSpcXCkvZztcbiAgICAvLyBsZXQgcmVnQmFyZUxpbmsgPSAvKGh0dHBzPzpcXC9cXC98ZnRwOlxcL1xcL3xvYnNpZGlhbjpcXC9cXC98em90ZXJvOlxcL1xcL3x3d3cuKVteXFxzXHVGRjA4XHVGRjA5XHUzMDBBXHUzMDBCXHUzMDAyXHVGRjBDXHVGRjAxXHVGRjFGXHVGRjFCXHVGRjFBXHUyMDFDXHUyMDFEXHUyMDE4XHUyMDE5XFwpXFwoXFxbXFxdXFx7XFx9J10rL2c7XG5cbiAgICAvLyAxLiBcdTUzMzlcdTkxNER3aWtpbGlua1xuICAgIHJldEFycmF5ID0gbWF0Y2hXaXRoUmVnKHRleHQsIHJlZ1dpa2lMaW5rLCBJbmxpbmVUeXBlLndpa2lsaW5rLCByZXRBcnJheSk7XG4gICAgLy8gMi4gXHU1MzM5XHU5MTREbWRsaW5rXG4gICAgcmV0QXJyYXkgPSBtYXRjaFdpdGhSZWcodGV4dCwgcmVnTWRMaW5rLCBJbmxpbmVUeXBlLm1kbGluaywgcmV0QXJyYXkpO1xuXG4gICAgLy8gMy4gXHU1MzM5XHU5MTREXHU3NTI4XHU2MjM3XHU4MUVBXHU1QjlBXHU0RTQ5XHU2QjYzXHU1MjE5XG4gICAgbGV0IHJlZ0V4cExpc3Q6IFJlZ0V4cFtdID0gW107XG4gICAgbGV0IGxlZnRTUmVxdWlyZUxpc3Q6IFNwYWNlU3RhdGVbXSA9IFtdO1xuICAgIGxldCByaWdodFNSZXF1aXJlTGlzdDogU3BhY2VTdGF0ZVtdID0gW107XG4gICAgbGV0IHJlZ051bGwgPSAvXlxccyokL2c7XG4gICAgbGV0IHJlZ1NSZXF1aXJlID0gL1xcfFtcXC09XFwrXVtcXC09XFwrXSQvO1xuICAgIGlmIChyZWdFeHBzKSB7XG4gICAgICAgIGxldCByZWdzID0gcmVnRXhwcy5zcGxpdCgnXFxuJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVncy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICBpZiAocmVnTnVsbC50ZXN0KHJlZ3NbaV0pKSBjb250aW51ZTtcblxuICAgICAgICAgICAgaWYgKCghcmVnU1JlcXVpcmUudGVzdChyZWdzW2ldKSkgfHwgcmVnc1tpXS5sZW5ndGggPD0gMykge1xuICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoXCJFYXN5VHlwaW5nOiBcdTdCMkNcIiArIFN0cmluZyhpKSArIFwiXHU4ODRDXHU4MUVBXHU1QjlBXHU0RTQ5XHU2QjYzXHU1MjE5XHU0RTBEXHU3QjI2XHU1NDA4XHU4OUM0XHU4MzAzXFxuXCIrcmVnc1tpXSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgcmVnSXRlbSA9IHJlZ3NbaV0uc3Vic3RyaW5nKDAsIHJlZ3NbaV0ubGVuZ3RoIC0gMyk7XG4gICAgICAgICAgICBsZXQgc3BhY2VSZXFTdHJpbmcgPSByZWdzW2ldLnN1YnN0cmluZyhyZWdzW2ldLmxlbmd0aCAtIDMpO1xuXG4gICAgICAgICAgICBsZXQgaXNWYWxpZFJlZyA9IHRydWU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCByZWdUZW1wID0gbmV3IFJlZ0V4cChyZWdJdGVtLCAnZycpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBpc1ZhbGlkUmVnID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaWYodGhpcy5zZXR0aW5ncy5kZWJ1Zyl7XG4gICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoXCJFYXN1VHlwaW5nOiBCYWQgUmVnRXhwOlxcblwiICsgcmVnSXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNWYWxpZFJlZykge1xuICAgICAgICAgICAgICAgIHJlZ0V4cExpc3QucHVzaChuZXcgUmVnRXhwKHJlZ0l0ZW0sICdnJykpO1xuICAgICAgICAgICAgICAgIGxlZnRTUmVxdWlyZUxpc3QucHVzaChzdHIyU3BhY2VTdGF0ZShzcGFjZVJlcVN0cmluZy5jaGFyQXQoMSkpKTtcbiAgICAgICAgICAgICAgICByaWdodFNSZXF1aXJlTGlzdC5wdXNoKHN0cjJTcGFjZVN0YXRlKHNwYWNlUmVxU3RyaW5nLmNoYXJBdCgyKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCByZWdMZW4gPSByZWdFeHBMaXN0Lmxlbmd0aDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlZ0xlbjsgaSsrKSB7XG4gICAgICAgICAgICByZXRBcnJheSA9IG1hdGNoV2l0aFJlZyh0ZXh0LCByZWdFeHBMaXN0W2ldLCBJbmxpbmVUeXBlLnVzZXIsIHJldEFycmF5LCB0cnVlLCBsZWZ0U1JlcXVpcmVMaXN0W2ldLCByaWdodFNSZXF1aXJlTGlzdFtpXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBcdTUzMzlcdTkxNERcdTY1RjZcdTk1RjRcdTYyMzNcbiAgICByZXRBcnJheSA9IG1hdGNoV2l0aFJlZyh0ZXh0LCAvXFxkezEsMn06XFxkezEsMn0oOlxcZHswLDJ9KXswLDF9L2csIElubGluZVR5cGUudXNlciwgcmV0QXJyYXksIHRydWUsIFNwYWNlU3RhdGUubm9uZSwgU3BhY2VTdGF0ZS5ub25lKTtcblxuICAgIC8vIDQuIFx1NTMzOVx1OTE0RFx1N0YyOVx1NTE5OVx1NTk4MiBhLm0uXG4gICAgcmV0QXJyYXkgPSBtYXRjaFdpdGhBYmJyKHRleHQsIElubGluZVR5cGUudXNlciwgcmV0QXJyYXksIHRydWUpO1xuXG4gICAgLy8gNS4gXHU1Rjk3XHU1MjMwXHU1MjY5XHU0RjU5XHU3Njg0XHU2NTg3XHU2NzJDXHU5MEU4XHU1MjA2XG4gICAgcmV0QXJyYXkgPSByZXRBcnJheS5zb3J0KChhLCBiKTogbnVtYmVyID0+IGEuYmVnaW4gLSBiLmJlZ2luKTtcblxuICAgIGxldCB0ZXh0QXJyYXk6IElubGluZVBhcnRbXSA9IFtdO1xuICAgIGxldCB0ZXh0QmVnaW4gPSAwO1xuICAgIGxldCB0ZXh0RW5kID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJldEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0ZXh0QmVnaW4gPCByZXRBcnJheVtpXS5iZWdpbikge1xuICAgICAgICAgICAgdGV4dEVuZCA9IHJldEFycmF5W2ldLmJlZ2luO1xuICAgICAgICAgICAgdGV4dEFycmF5LnB1c2goXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiB0ZXh0LnN1YnN0cmluZyh0ZXh0QmVnaW4sIHRleHRFbmQpLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBJbmxpbmVUeXBlLnRleHQsXG4gICAgICAgICAgICAgICAgICAgIGJlZ2luOiB0ZXh0QmVnaW4sXG4gICAgICAgICAgICAgICAgICAgIGVuZDogdGV4dEVuZCxcbiAgICAgICAgICAgICAgICAgICAgbGVmdFNwYWNlUmVxdWlyZTogU3BhY2VTdGF0ZS5ub25lLFxuICAgICAgICAgICAgICAgICAgICByaWdodFNwYWNlUmVxdWlyZTogU3BhY2VTdGF0ZS5ub25lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0ZXh0QmVnaW4gPSByZXRBcnJheVtpXS5lbmQ7XG4gICAgfVxuXG4gICAgaWYgKHRleHRCZWdpbiAhPSB0ZXh0Lmxlbmd0aCkge1xuICAgICAgICB0ZXh0QXJyYXkucHVzaChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiB0ZXh0LnN1YnN0cmluZyh0ZXh0QmVnaW4sIHRleHQubGVuZ3RoKSxcbiAgICAgICAgICAgICAgICB0eXBlOiBJbmxpbmVUeXBlLnRleHQsXG4gICAgICAgICAgICAgICAgYmVnaW46IHRleHRCZWdpbixcbiAgICAgICAgICAgICAgICBlbmQ6IHRleHQubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGxlZnRTcGFjZVJlcXVpcmU6IFNwYWNlU3RhdGUubm9uZSxcbiAgICAgICAgICAgICAgICByaWdodFNwYWNlUmVxdWlyZTogU3BhY2VTdGF0ZS5ub25lXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gNi4gXHU1NDA4XHU1RTc2XHU2NTg3XHU2NzJDXHU5MEU4XHU1MjA2XHU1NDhDXHU1MTc2XHU0RUQ2XHU5MEU4XHU1MjA2XG4gICAgcmV0QXJyYXkgPSByZXRBcnJheS5jb25jYXQodGV4dEFycmF5KTtcbiAgICByZXRBcnJheSA9IHJldEFycmF5LnNvcnQoKGEsIGIpOiBudW1iZXIgPT4gYS5iZWdpbiAtIGIuYmVnaW4pO1xuICAgIHJldHVybiByZXRBcnJheVxufVxuXG4vLyBcdTVCNTdcdTdCMjZcdThGNkNcdTUzMTZcdTYyMTBcdTdBN0FcdTY4M0NcdTcyQjZcdTYwMDFcdTg5ODFcdTZDNDJcbmZ1bmN0aW9uIHN0cjJTcGFjZVN0YXRlKHM6IHN0cmluZyk6IFNwYWNlU3RhdGUge1xuICAgIHN3aXRjaCAocykge1xuICAgICAgICBjYXNlIFwiK1wiOlxuICAgICAgICAgICAgcmV0dXJuIFNwYWNlU3RhdGUuc3RyaWN0O1xuICAgICAgICBjYXNlICc9JzpcbiAgICAgICAgICAgIHJldHVybiBTcGFjZVN0YXRlLnNvZnQ7XG4gICAgICAgIGNhc2UgJy0nOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIFNwYWNlU3RhdGUubm9uZTtcbiAgICB9XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZzJTcGFjZVN0YXRlKHM6c3RyaW5nKTpTcGFjZVN0YXRlXG57XG4gICAgaWYoTnVtYmVyKHMpPT1TcGFjZVN0YXRlLm5vbmUpIHJldHVybiBTcGFjZVN0YXRlLm5vbmU7XG4gICAgaWYoTnVtYmVyKHMpPT1TcGFjZVN0YXRlLnNvZnQpIHJldHVybiBTcGFjZVN0YXRlLnNvZnQ7XG4gICAgaWYoTnVtYmVyKHMpPT1TcGFjZVN0YXRlLnN0cmljdCkgcmV0dXJuIFNwYWNlU3RhdGUuc3RyaWN0O1xuICAgIHJldHVybiBTcGFjZVN0YXRlLm5vbmU7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvc0xpbmVUeXBlKHN0YXRlOiBFZGl0b3JTdGF0ZSwgcG9zOiBudW1iZXIpOkxpbmVUeXBlIHtcbiAgICBjb25zdCBsaW5lID0gc3RhdGUuZG9jLmxpbmVBdChwb3MpXG4gICAgbGV0IGxpbmVfbnVtYmVyID0gbGluZS5udW1iZXJcbiAgICAvLyBjb25zdCB0cmVlID0gc3ludGF4VHJlZShzdGF0ZSk7XG4gICAgY29uc3QgdHJlZSA9IGVuc3VyZVN5bnRheFRyZWUoc3RhdGUsIGxpbmUudG8pO1xuICAgIGNvbnN0IHRva2VuID0gdHJlZS5yZXNvbHZlKGxpbmUuZnJvbSwgMSkubmFtZVxuXG4gICAgLy8gZm9yIChsZXQgcD1saW5lLmZyb207IHA8bGluZS50bzsgcCs9MSl7XG4gICAgLy8gICAgIGNvbnNvbGUubG9nKHAtbGluZS5mcm9tLCB0cmVlLnJlc29sdmUocCwgMSkubmFtZSlcbiAgICAvLyB9XG5cbiAgICBpZiAodG9rZW4uY29udGFpbnMoJ3RhYmxlJykpe1xuICAgICAgICByZXR1cm4gTGluZVR5cGUudGFibGU7XG4gICAgfVxuXG4gICAgaWYgKHRva2VuLmNvbnRhaW5zKCdobWQtZnJvbnRtYXR0ZXInKSl7XG4gICAgICAgIHJldHVybiBMaW5lVHlwZS5mcm9udG1hdHRlcjtcbiAgICB9XG5cbiAgICBpZih0b2tlbi5jb250YWlucygnbWF0aCcpKXtcbiAgICAgICAgZm9yKGxldCBwPWxpbmUuZnJvbSsxO3A8bGluZS50bztwKz0xKXtcbiAgICAgICAgICAgIGlmKCF0cmVlLnJlc29sdmUocCwgMSkubmFtZS5jb250YWlucygnbWF0aCcpKXtcbiAgICAgICAgICAgICAgICByZXR1cm4gTGluZVR5cGUudGV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTGluZVR5cGUuZm9ybXVsYVxuICAgIH1cbiAgICBlbHNlIGlmKHRva2VuLmNvbnRhaW5zKCdjb2RlJykgJiYgdG9rZW4uY29udGFpbnMoJ2Jsb2NrJykpe1xuICAgICAgICBmb3IobGV0IHA9bGluZS5mcm9tKzE7cDxsaW5lLnRvO3ArPTEpe1xuICAgICAgICAgICAgbGV0IHQgPSB0cmVlLnJlc29sdmUocCwgMSkubmFtZVxuICAgICAgICAgICAgaWYoISh0LmNvbnRhaW5zKCdjb2RlJykgJiYgdC5jb250YWlucygnYmxvY2snKSkpe1xuICAgICAgICAgICAgICAgIHJldHVybiBMaW5lVHlwZS50ZXh0XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIExpbmVUeXBlLmNvZGVibG9ja1xuICAgIH1cbiAgICBlbHNlIGlmKHRva2VuLmNvbnRhaW5zKCdxdW90ZScpICYmICF0b2tlbi5jb250YWlucygnY2FsbG91dCcpKXtcbiAgICAgICAgLy8gXHU2M0E1XHU0RTBCXHU2NzY1XHU1MjI0XHU2NUFEXHU4QkU1XHU4ODRDXHU2NjJGXHU1NDI2XHU0RTNBY2FsbG91dFx1NTc1N1x1NTE4NVx1NzY4NFx1NEVFM1x1NzgwMVx1NTc1N1xuICAgICAgICAvLyBcdTk5OTZcdTUxNDhcdTUyMjRcdTY1QURcdTY2MkZcdTU0MjZcdTRFM0FjYWxsb3V0XG4gICAgICAgIGxldCBjYWxsb3V0X3N0YXJ0X2xpbmUgPSAtMTtcbiAgICAgICAgZm9yKGxldCBsPWxpbmVfbnVtYmVyLTE7IGw+PTE7IGwtPTEpe1xuICAgICAgICAgICAgbGV0IGxfbGluZSA9IHN0YXRlLmRvYy5saW5lKGwpXG4gICAgICAgICAgICBsZXQgbF90b2tlbiA9IHRyZWUucmVzb2x2ZShsX2xpbmUuZnJvbSwgMSkubmFtZVxuICAgICAgICAgICAgaWYoIWxfdG9rZW4uY29udGFpbnMoJ3F1b3RlJykpe1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxfdG9rZW4uY29udGFpbnMoJ2NhbGxvdXQnKSl7XG4gICAgICAgICAgICAgICAgY2FsbG91dF9zdGFydF9saW5lID0gbDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsbG91dF9zdGFydF9saW5lPT0tMSkgcmV0dXJuIExpbmVUeXBlLnRleHQ7XG4gICAgICAgIFxuICAgICAgICAvLyBcdTcxMzZcdTU0MEVcdTUyMjRcdTY1QURcdTY2MkZcdTU0MjZcdTRFM0FcdTRFRTNcdTc4MDFcdTU3NTdcbiAgICAgICAgbGV0IGlzX2NvZGVfYmxvY2s6Ym9vbGVhbiA9IGZhbHNlO1xuICAgICAgICBsZXQgcmVzZXQ6Ym9vbGVhbiA9IGZhbHNlO1xuICAgICAgICBsZXQgcmVnX2NvZGVfYmVnaW4gPSAvXj4rIGBgYC87XG4gICAgICAgIGxldCByZWdfY29kZV9lbmQgPSAvXj4rIGBgYCQvO1xuICAgICAgICBmb3IgKGxldCBsPWNhbGxvdXRfc3RhcnRfbGluZSsxOyBsPD1saW5lX251bWJlcjsgbCs9MSl7XG4gICAgICAgICAgICBsZXQgbF9saW5lID0gc3RhdGUuZG9jLmxpbmUobClcbiAgICAgICAgICAgIGlmIChyZXNldCl7XG4gICAgICAgICAgICAgICAgaXNfY29kZV9ibG9jayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlc2V0ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZihpc19jb2RlX2Jsb2NrICYmIHJlZ19jb2RlX2VuZC50ZXN0KGxfbGluZS50ZXh0KSl7XG4gICAgICAgICAgICAgICAgaXNfY29kZV9ibG9jayA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmVzZXQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZighaXNfY29kZV9ibG9jayAmJiByZWdfY29kZV9iZWdpbi50ZXN0KGxfbGluZS50ZXh0KSl7XG4gICAgICAgICAgICAgICAgaXNfY29kZV9ibG9jayA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzX2NvZGVfYmxvY2spIHtcbiAgICAgICAgICAgIHJldHVybiBMaW5lVHlwZS5jb2RlYmxvY2s7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSByZXR1cm4gTGluZVR5cGUudGV4dDtcbiAgICB9XG4gICAgZWxzZSBpZih0b2tlbi5jb250YWlucygnbGlzdCcpKXtcbiAgICAgICAgZm9yKGxldCBwPWxpbmUuZnJvbSsxO3A8bGluZS50bztwKz0xKXtcbiAgICAgICAgICAgIGxldCB0ID0gdHJlZS5yZXNvbHZlKHAsIDEpLm5hbWVcbiAgICAgICAgICAgIGlmKCh0LmNvbnRhaW5zKCdjb2RlJykgJiYgdC5jb250YWlucygnYmxvY2snKSkpe1xuICAgICAgICAgICAgICAgIHJldHVybiBMaW5lVHlwZS5jb2RlYmxvY2tcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gTGluZVR5cGUudGV4dFxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb3NMaW5lVHlwZTIoc3RhdGU6IEVkaXRvclN0YXRlLCBwb3M6IG51bWJlcik6TGluZVR5cGUge1xuICAgIGNvbnN0IGxpbmUgPSBzdGF0ZS5kb2MubGluZUF0KHBvcylcbiAgICBjb25zdCB0cmVlID0gc3ludGF4VHJlZShzdGF0ZSk7XG4gICAgY29uc3QgdG9rZW4gPSB0cmVlLnJlc29sdmUobGluZS5mcm9tLCAxKS5uYW1lXG4gICAgaWYgKHRva2VuLmNvbnRhaW5zKCdobWQtZnJvbnRtYXR0ZXInKSl7XG4gICAgICAgIHJldHVybiBMaW5lVHlwZS5mcm9udG1hdHRlclxuICAgIH1cblxuICAgIGlmKHRva2VuLmNvbnRhaW5zKCdtYXRoJykpe1xuICAgICAgICBmb3IobGV0IHA9bGluZS5mcm9tKzE7cDxsaW5lLnRvO3ArPTEpe1xuICAgICAgICAgICAgaWYoIXRyZWUucmVzb2x2ZShwLCAxKS5uYW1lLmNvbnRhaW5zKCdtYXRoJykpe1xuICAgICAgICAgICAgICAgIHJldHVybiBMaW5lVHlwZS50ZXh0XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIExpbmVUeXBlLmZvcm11bGFcbiAgICB9XG4gICAgZWxzZSBpZih0b2tlbi5jb250YWlucygnY29kZScpICYmIHRva2VuLmNvbnRhaW5zKCdibG9jaycpKXtcbiAgICAgICAgZm9yKGxldCBwPWxpbmUuZnJvbSsxO3A8bGluZS50bztwKz0xKXtcbiAgICAgICAgICAgIGxldCB0ID0gdHJlZS5yZXNvbHZlKHAsIDEpLm5hbWVcbiAgICAgICAgICAgIGlmKCEodC5jb250YWlucygnY29kZScpICYmIHQuY29udGFpbnMoJ2Jsb2NrJykpKXtcbiAgICAgICAgICAgICAgICByZXR1cm4gTGluZVR5cGUudGV4dFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBMaW5lVHlwZS5jb2RlYmxvY2tcbiAgICB9XG5cbiAgICBmb3IobGV0IHA9bGluZS5mcm9tO3A8bGluZS50bztwKz0xKXtcbiAgICAgICAgaWYodHJlZS5yZXNvbHZlKHAsIDEpLm5hbWUuY29udGFpbnMoJ2xpc3QnKSl7XG4gICAgICAgICAgICByZXR1cm4gTGluZVR5cGUubGlzdFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYodHJlZS5yZXNvbHZlKHAsIDEpLm5hbWUuY29udGFpbnMoJ2NhbGxvdXQnKSl7XG4gICAgICAgICAgICByZXR1cm4gTGluZVR5cGUuY2FsbG91dF90aXRsZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmKHRva2VuLmNvbnRhaW5zKCdxdW90ZScpKXtcbiAgICAgICAgcmV0dXJuIExpbmVUeXBlLnF1b3RlO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gTGluZVR5cGUudGV4dFxufSIsICJpbXBvcnQgeyBBbm5vdGF0aW9uLCBFZGl0b3JTdGF0ZSwgRXh0ZW5zaW9uLCBTdGF0ZUZpZWxkLCBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25TcGVjLCBUZXh0fSBmcm9tICdAY29kZW1pcnJvci9zdGF0ZSc7XG5pbXBvcnQgeyBFYXN5VHlwaW5nU2V0dGluZ1RhYiwgRWFzeVR5cGluZ1NldHRpbmdzLCBQYWlyU3RyaW5nLCBDb252ZXJ0UnVsZX0gZnJvbSBcIi4vc2V0dGluZ3NcIlxuaW1wb3J0IHsgQXBwLCBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbidcblxubGV0IERFQlVHID0gdHJ1ZTtcblxuZXhwb3J0IGNvbnN0IHByaW50PShtZXNzYWdlPzogYW55LCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pID0+e1xuICAgIGlmIChERUJVRykge1xuICAgICAgICBjb25zb2xlLmxvZyhtZXNzYWdlLCAuLi5vcHRpb25hbFBhcmFtcyk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcG9zVG9PZmZzZXQoZG9jOlRleHQsIHBvczp7bGluZTpudW1iZXIsIGNoOm51bWJlcn0pIHtcblx0cmV0dXJuIGRvYy5saW5lKHBvcy5saW5lICsgMSkuZnJvbSArIHBvcy5jaFxufVxuZXhwb3J0IGZ1bmN0aW9uIG9mZnNldFRvUG9zKGRvYzpUZXh0LCBvZmZzZXQ6bnVtYmVyKSB7XG5cdGxldCBsaW5lID0gZG9jLmxpbmVBdChvZmZzZXQpXG5cdHJldHVybiB7bGluZTogbGluZS5udW1iZXIgLSAxLCBjaDogb2Zmc2V0IC0gbGluZS5mcm9tfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHlwZVN0ck9mVHJhbnNhYyh0cjogVHJhbnNhY3Rpb24pOiBzdHJpbmcge1xuXHRsZXQgVHJhbnNhY1R5cGVBcnJheTpzdHJpbmdbXSA9IFtcIkVhc3lUeXBpbmcuY2hhbmdlXCIsIFwiRWFzeVR5cGluZy5wYXN0ZVwiLFxuXHRcdFx0XHRcdFx0XHRcImlucHV0LnR5cGUuY29tcG9zZVwiLCBcImlucHV0LnR5cGVcIiwgXCJpbnB1dC5wYXN0ZVwiLCBcImlucHV0LmRyb3BcIiwgXCJpbnB1dC5jb21wbGV0ZVwiLCBcImlucHV0XCIsXG5cdFx0XHRcdFx0XHRcdFwiZGVsZXRlLnNlbGVjdGlvblwiLCBcImRlbGV0ZS5mb3J3YXJkXCIsIFwiZGVsZXRlLmJhY2t3YXJkXCIsIFwiZGVsZXRlLmN1dFwiLCBcImRlbGV0ZVwiLFxuXHRcdFx0XHRcdFx0XHRcIm1vdmUuZHJvcFwiLFxuXHRcdFx0XHRcdFx0XHRcInVuZG9cIiwgXCJyZWRvXCIsXG5cdFx0XHRcdFx0XHRcdFwic2VsZWN0LnBvaW50ZXJcIl07XG5cdGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCBUcmFuc2FjVHlwZUFycmF5Lmxlbmd0aDsgaSsrKVxuXHR7XG5cdFx0aWYgKHRyLmlzVXNlckV2ZW50KFRyYW5zYWNUeXBlQXJyYXlbaV0pKVxuXHRcdFx0cmV0dXJuIFRyYW5zYWNUeXBlQXJyYXlbaV07XG5cdH1cblx0cmV0dXJuIFwibm9uZVwiXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmcycGFpcnN0cmluZyhzOiBzdHJpbmcpOlBhaXJTdHJpbmd7XG5cdGxldCBjdXJzb3JJZHggPSBzLmluZGV4T2YoXCJ8XCIpO1xuXHRsZXQgbGVmdCA9IHMuc3Vic3RyaW5nKDAsIGN1cnNvcklkeCk7XG5cdGxldCByaWdodCA9IHMuc3Vic3RyaW5nKGN1cnNvcklkeCsxKTtcblx0cmV0dXJuIHtsZWZ0OmxlZnQsIHJpZ2h0OnJpZ2h0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bGVTdHJpbmdMaXN0MlJ1bGVMaXN0KGxpc3Q6IEFycmF5PFtzdHJpbmcsIHN0cmluZ10+KTpDb252ZXJ0UnVsZVtdIHtcblx0bGV0IHJlczpDb252ZXJ0UnVsZVtdID0gW107XG5cdGZvciAobGV0IGkgaW4gbGlzdCl7XG5cdFx0cmVzW2ldID0ge2JlZm9yZTogc3RyaW5nMnBhaXJzdHJpbmcobGlzdFtpXVswXSksIGFmdGVyOiBzdHJpbmcycGFpcnN0cmluZyhsaXN0W2ldWzFdKX1cblx0fVxuXHRyZXR1cm4gcmVzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nRGVsZXRlQXQoc3RyOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpOnN0cmluZ1xue1xuICAgIHJldHVybiBzdHIuc3Vic3RyaW5nKDAsIGluZGV4KStzdHIuc3Vic3RyaW5nKGluZGV4KzEpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nSW5zZXJ0QXQoc3RyOnN0cmluZywgaW5kZXg6IG51bWJlciwgczogc3RyaW5nKTpzdHJpbmdcbntcbiAgICByZXR1cm4gc3RyLnN1YnN0cmluZygwLCBpbmRleCkrcytzdHIuc3Vic3RyaW5nKGluZGV4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGFyYW1EZWZpbmVkKHBhcmFtOiBhbnkpOmJvb2xlYW5cbntcblx0cmV0dXJuIHR5cGVvZiBwYXJhbSE9PVwidW5kZWZpbmVkXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaG93U3RyaW5nKHM6IHN0cmluZyk6c3RyaW5ne1xuXHRyZXR1cm4gcy5yZXBsYWNlKC9cXG4vZywgJ1xcXFxuJyk7XG59IiwgImltcG9ydCB7IFNwYWNlU3RhdGUsIHN0cmluZzJTcGFjZVN0YXRlIH0gZnJvbSAnc3JjL2NvcmUnO1xuaW1wb3J0IHsgQXBwLCBUZXh0Q29tcG9uZW50LCBNYXJrZG93blZpZXcsIE1vZGFsLCBOb3RpY2UsIFBsdWdpbiwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZywgV29ya3NwYWNlLCBXb3Jrc3BhY2VMZWFmLCBUZXh0QXJlYUNvbXBvbmVudCB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCBFYXN5VHlwaW5nUGx1Z2luIGZyb20gJy4vbWFpbic7XG5pbXBvcnQgeyBzaG93U3RyaW5nIH0gZnJvbSAnLi91dGlscyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFpclN0cmluZyB7XG5cdGxlZnQ6IHN0cmluZztcblx0cmlnaHQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb252ZXJ0UnVsZSB7XG5cdGJlZm9yZTogUGFpclN0cmluZztcblx0YWZ0ZXI6IFBhaXJTdHJpbmc7XG59XG5cbmV4cG9ydCBlbnVtIFJ1bGVUeXBlIHtkZWxldGU9IFwiRGVsZXRlIFJ1bGVcIiwgY29udmVydD0nQ29udmVydCBSdWxlJ31cbmV4cG9ydCBlbnVtIFdvcmtNb2RlIHsgT25seVdoZW5UeXBpbmcgPSBcInR5cGluZ1wiLCBHbG9iYWxseSA9IFwiZ2xvYmFsXCIgfVxuXG5leHBvcnQgaW50ZXJmYWNlIEVhc3lUeXBpbmdTZXR0aW5ncyB7XG5cdFRhYm91dDogYm9vbGVhbjtcblx0U2VsZWN0aW9uRW5oYW5jZTogYm9vbGVhbjtcblx0SW50cmluc2ljU3ltYm9sUGFpcnM6IGJvb2xlYW47XG5cdEJhc2VPYkVkaXRFbmhhbmNlOiBib29sZWFuO1xuXHRGVzJIV0VuaGFuY2U6IGJvb2xlYW47XG5cdEJldHRlckNvZGVFZGl0OiBib29sZWFuO1xuXHRBdXRvRm9ybWF0OiBib29sZWFuO1xuXHRFeGNsdWRlRmlsZXM6IHN0cmluZztcblx0QXV0b0NhcGl0YWw6IGJvb2xlYW47XG5cdEF1dG9DYXBpdGFsTW9kZTogV29ya01vZGU7XG5cdENoaW5lc2VFbmdsaXNoU3BhY2U6IGJvb2xlYW47XG5cdEVuZ2xpc2hOdW1iZXJTcGFjZTogYm9vbGVhbjtcblx0Q2hpbmVzZU5vU3BhY2U6IGJvb2xlYW47XG5cdENoaW5lc2VOdW1iZXJTcGFjZTogYm9vbGVhbjtcblx0UHVuY3R1YXRpb25TcGFjZTogYm9vbGVhbjtcblx0UHVuY3R1YXRpb25TcGFjZU1vZGU6IFdvcmtNb2RlO1xuXHRJbmxpbmVDb2RlU3BhY2VNb2RlOiBTcGFjZVN0YXRlO1xuXHRJbmxpbmVGb3JtdWxhU3BhY2VNb2RlOiBTcGFjZVN0YXRlO1xuXHRJbmxpbmVMaW5rU3BhY2VNb2RlOiBTcGFjZVN0YXRlO1xuXHRJbmxpbmVMaW5rU21hcnRTcGFjZTogYm9vbGVhbjtcblx0VXNlckRlZmluZWRSZWdTd2l0Y2g6IGJvb2xlYW47XG5cdFVzZXJEZWZpbmVkUmVnRXhwOiBzdHJpbmc7XG5cdGRlYnVnOiBib29sZWFuO1xuXG5cdHVzZXJTZWxSZXBSdWxlVHJpZ2dlcjogc3RyaW5nW107XG5cdHVzZXJTZWxSZXBSdWxlVmFsdWU6IFBhaXJTdHJpbmdbXTtcblx0dXNlckRlbGV0ZVJ1bGVzU3RyTGlzdDogW3N0cmluZywgc3RyaW5nXVtdO1xuXHR1c2VyQ29udmVydFJ1bGVzU3RyTGlzdDogW3N0cmluZywgc3RyaW5nXVtdO1xuXHR1c2VyU2VsUnVsZVNldHRpbmdzT3BlbjogYm9vbGVhbjtcblx0dXNlckRlbFJ1bGVTZXR0aW5nc09wZW46IGJvb2xlYW47XG5cdHVzZXJDdnRSdWxlU2V0dGluZ3NPcGVuOiBib29sZWFuO1xuXG5cdEVudGVyVHdpY2U6IGJvb2xlYW47XG5cdFB1bmNSZWN0aWZ5OiBib29sZWFuO1xuXHRUcnlGaXhDaGluZXNlSU06IGJvb2xlYW47XG5cdEZpeE1hY09TQ29udGV4dE1lbnU6IGJvb2xlYW47XG5cdFRyeUZpeE1TSU1FOiBib29sZWFuO1xufVxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogRWFzeVR5cGluZ1NldHRpbmdzID0ge1xuXHRUYWJvdXQ6IHRydWUsXG5cdFNlbGVjdGlvbkVuaGFuY2U6IHRydWUsXG5cdEludHJpbnNpY1N5bWJvbFBhaXJzOiB0cnVlLFxuXHRCYXNlT2JFZGl0RW5oYW5jZTogdHJ1ZSxcblx0RlcySFdFbmhhbmNlOiB0cnVlLFxuXHRCZXR0ZXJDb2RlRWRpdDogdHJ1ZSxcblxuXHRBdXRvRm9ybWF0OiB0cnVlLFxuXHRFeGNsdWRlRmlsZXM6IFwiXCIsXG5cdENoaW5lc2VFbmdsaXNoU3BhY2U6IHRydWUsXG5cdENoaW5lc2VOdW1iZXJTcGFjZTogdHJ1ZSxcblx0RW5nbGlzaE51bWJlclNwYWNlOiB0cnVlLFxuXHRDaGluZXNlTm9TcGFjZTogdHJ1ZSxcblx0UHVuY3R1YXRpb25TcGFjZTogdHJ1ZSxcblx0QXV0b0NhcGl0YWw6IHRydWUsXG5cdEF1dG9DYXBpdGFsTW9kZTogV29ya01vZGUuT25seVdoZW5UeXBpbmcsXG5cdFB1bmN0dWF0aW9uU3BhY2VNb2RlOiBXb3JrTW9kZS5Pbmx5V2hlblR5cGluZyxcblx0SW5saW5lQ29kZVNwYWNlTW9kZTogU3BhY2VTdGF0ZS5zb2Z0LFxuXHRJbmxpbmVGb3JtdWxhU3BhY2VNb2RlOiBTcGFjZVN0YXRlLnNvZnQsXG5cdElubGluZUxpbmtTcGFjZU1vZGU6IFNwYWNlU3RhdGUuc29mdCxcblx0SW5saW5lTGlua1NtYXJ0U3BhY2U6IHRydWUsXG5cdFVzZXJEZWZpbmVkUmVnU3dpdGNoOiB0cnVlLFxuXHRVc2VyRGVmaW5lZFJlZ0V4cDogXCJ7ey4qP319fCsrXFxuXCIrXG5cdFx0XCI8Lio/PnwtLVxcblwiICtcblx0XHRcIlxcXFxbXFxcXCEuKj9cXFxcXVstK117MCwxfXwtK1xcblwiK1xuXHRcdFwiKGZpbGU6Ly8vfGh0dHBzPzovL3xmdHA6Ly98b2JzaWRpYW46Ly98em90ZXJvOi8vfHd3dy4pW15cXFxcc1x1RkYwOFx1RkYwOVx1MzAwQVx1MzAwQlx1MzAwMixcdUZGMENcdUZGMDFcdUZGMUY7XHVGRjFCXHVGRjFBXHUyMDFDXHUyMDFEXHUyMDE4XHUyMDE5XFxcXClcXFxcKFxcXFxbXFxcXF1cXFxce1xcXFx9J10rfC0tXFxuXCIrXG5cdFx0XCJcXG5bYS16QS1aMC05X1xcXFwtLl0rQFthLXpBLVowLTlfXFxcXC0uXSt8KytcXG5cIitcblx0XHRcIig/PCEjKSNbXFxcXHU0ZTAwLVxcXFx1OWZhNVxcXFx3LVxcXFwvXSt8KytcIixcblx0ZGVidWc6IGZhbHNlLFxuXHR1c2VyU2VsUmVwUnVsZVRyaWdnZXI6IFtcIi1cIiwgXCIjXCJdLFxuXHR1c2VyU2VsUmVwUnVsZVZhbHVlOiBbe2xlZnQ6XCJ+flwiLCByaWdodDpcIn5+XCJ9LCB7bGVmdDpcIiNcIiwgcmlnaHQ6XCIgXCJ9XSxcblx0dXNlckRlbGV0ZVJ1bGVzU3RyTGlzdDogW1tcImRlbW98XCIsIFwifFwiXV0sXG5cdHVzZXJDb252ZXJ0UnVsZXNTdHJMaXN0OiBbW1wiOil8XCIsXCJcdUQ4M0RcdURFMDB8XCJdXSxcblx0dXNlclNlbFJ1bGVTZXR0aW5nc09wZW46IHRydWUsXG5cdHVzZXJEZWxSdWxlU2V0dGluZ3NPcGVuOiB0cnVlLFxuXHR1c2VyQ3Z0UnVsZVNldHRpbmdzT3BlbjogdHJ1ZSxcblxuXHRFbnRlclR3aWNlOiBmYWxzZSxcblx0VHJ5Rml4Q2hpbmVzZUlNOiB0cnVlLFxuXHRQdW5jUmVjdGlmeTogZmFsc2UsXG5cdEZpeE1hY09TQ29udGV4dE1lbnU6IGZhbHNlLFxuXHRUcnlGaXhNU0lNRTogZmFsc2UsXG59XG5cbmV4cG9ydCBjbGFzcyBFYXN5VHlwaW5nU2V0dGluZ1RhYiBleHRlbmRzIFBsdWdpblNldHRpbmdUYWIge1xuXHRwbHVnaW46IEVhc3lUeXBpbmdQbHVnaW47XG5cblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogRWFzeVR5cGluZ1BsdWdpbikge1xuXHRcdHN1cGVyKGFwcCwgcGx1Z2luKTtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblx0fVxuXG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcblxuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbChcImgxXCIsIHsgdGV4dDogXCJPYnNpZGlhbiBFYXN5VHlwaW5nIFBsdWdpblwiIH0pO1xuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwicFwiLCB7IHRleHQ6IFwiTW9yZSBkZXRhaWwgaXMgaW4gR2l0aHViOiBcIiB9KS5jcmVhdGVFbChcImFcIiwge1xuXHRcdFx0dGV4dDogXCJlYXN5LXR5cGluZy1vYnNpZGlhblwiLFxuXHRcdFx0aHJlZjogXCJodHRwczovL2dpdGh1Yi5jb20vWWFvemh1d2EvZWFzeS10eXBpbmctb2JzaWRpYW5cIixcblx0XHR9KTtcblxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ1x1NTg5RVx1NUYzQVx1N0YxNlx1OEY5MVx1OEJCRVx1N0Y2RSAoRW5oYW5jZWQgRWRpdGluZyBTZXR0aW5nKScgfSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiU3ltYm9sIGF1dG8gcGFpciBhbmQgZGVsZXRlIHdpdGggcGFpclwiKVxuXHRcdFx0LnNldERlc2MoXCJcdTU4OUVcdTUyQTBcdTU5MUFcdTc5Q0RcdTdCMjZcdTUzRjdcdTkxNERcdTVCRjlcdThGOTNcdTUxNjVcdUZGMENcdTkxNERcdTVCRjlcdTUyMjBcdTk2NjRcdUZGMENcdTU5ODJcdTMwMEFcdTMwMEIsIFx1MjAxQ1x1MjAxRCwgXHUzMDBDXHUzMDBELCBcdTMwMEVcdTMwMEYsXHUzMDEwXHUzMDExXHU3QjQ5XCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkludHJpbnNpY1N5bWJvbFBhaXJzKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkludHJpbnNpY1N5bWJvbFBhaXJzID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIlNlbGVjdGlvbiBSZXBsYWNlIEVuaGFuY2VtZW50XCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1OTAwOVx1NEUyRFx1NjU4N1x1NjcyQ1x1NjBDNVx1NTFCNVx1NEUwQlx1NzY4NFx1N0YxNlx1OEY5MVx1NTg5RVx1NUYzQVx1RkYwQ1x1NjMwOVx1RkZFNVx1MjE5MiRcdTkwMDlcdTRFMkRcdTc2ODRcdTY1ODdcdTY3MkMkLCBcdTYzMDlcdTAwQjdcdTIxOTJgXHU5MDA5XHU0RTJEXHU3Njg0XHU2NTg3XHU2NzJDYFx1RkYwQ1x1MzAwQSBcdTIxOTIgXHUzMDBBXHU5MDA5XHU0RTJEXHU3Njg0XHU2NTg3XHU2NzJDXHUzMDBCXHU3QjQ5XHU3QjQ5XCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLlNlbGVjdGlvbkVuaGFuY2UpXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuU2VsZWN0aW9uRW5oYW5jZSA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJDb252ZXJ0IHN1Y2Nlc3NpdmUgZnVsbCB3aWR0aCBzeW1ib2wgdG8gaGFsZiB3aWR0aCBzeW1ib2xcIilcblx0XHRcdC5zZXREZXNjKFwiXHU4RkRFXHU3RUVEXHU4RjkzXHU1MTY1XHU1MTY4XHU4OUQyXHU3QjI2XHU1M0Y3XHU4RjZDXHU1MzRBXHU4OUQyXHVGRjBDXHUzMDAyXHUzMDAyXHUyMTkyIC5cdUZGMENcdUZGMDFcdUZGMDFcdTIxOTIgIVx1RkYwQyBcdTMwMEJcdTMwMEJcdTIxOTIgPlwiKVxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5GVzJIV0VuaGFuY2UpXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuRlcySFdFbmhhbmNlID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIkJhc2ljIHN5bWJvbCBpbnB1dCBlbmhhbmNlIGZvciBvYnNpZGlhblwiKVxuXHRcdFx0LnNldERlc2MoXCJPYnNpZGlhbiBcdTc2ODRcdTU3RkFcdTc4NDBcdThGOTNcdTUxNjVcdTU4OUVcdTVGM0FcdUZGMENcdTU5ODJcdTMwMTBcdTMwMTB8IFx1MjE5MiBbW3xdXVx1RkYwQ1x1NTNFNVx1OTk5Nlx1NzY4NFx1MzAwMVx1MjE5MiAvXHVGRjBDXHU1M0U1XHU5OTk2XHU3Njg0XHUzMDBCXHUyMTkyID5cdUZGMENcdTAwQjdcdTAwQjd8IFx1MjE5MiBgfGBcdUZGMEMgYFx1MDBCN3xgIFx1NTNEOFx1NjIxMFx1NEVFM1x0XHU3ODAxXHU1NzU3XHVGRjBDXHVGRkU1XHVGRkU1fCBcdTIxOTIgJHwkXCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkJhc2VPYkVkaXRFbmhhbmNlKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkJhc2VPYkVkaXRFbmhhbmNlID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIkVuaGFuY2UgY29kZWJsb2NrIGVkaXRcIilcblx0XHRcdC5zZXREZXNjKFwiSW1wcm92ZSBlZGl0aW5nIGluIGNvZGVibG9jayhUYWIsIGRlbGV0ZSwgcGFzdGUsIGNtZC9jdHJsK0Egc2VsZWN0KS4gXHU1ODlFXHU1RjNBXHU0RUUzXHU3ODAxXHU1NzU3XHU1MTg1XHU3Njg0XHU3RjE2XHU4RjkxXHVGRjA4Q21kL0N0cmwrQSBcdTkwMDlcdTRFMkRcdTMwMDFUYWJcdTMwMDFcdTUyMjBcdTk2NjRcdTMwMDFcdTdDOThcdThEMzRcdUZGMDlcIilcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQmV0dGVyQ29kZUVkaXQpXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQmV0dGVyQ29kZUVkaXQgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiVGFib3V0XCIpXG5cdFx0XHQuc2V0RGVzYyhcIlRhYm91dCBpbmxpbmUgY29kZSBvciBwYWlyZWQgc3ltYm9scyh3aGVuIHNlbGVjdGVkKS4gVGFiIFx1OERGM1x1NTFGQVx1ODg0Q1x1NTE4NVx1NEVFM1x1NzgwMVx1NTc1N1x1NjIxNlx1OTE0RFx1NUJGOVx1N0IyNlx1NTNGN1x1NTc1NyhcdTkwMDlcdTRFMkRcdTY1RjYpXCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLlRhYm91dClcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5UYWJvdXQgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdcdTgxRUFcdTVCOUFcdTRFNDlcdTdGMTZcdThGOTFcdThGNkNcdTYzNjJcdTg5QzRcdTUyMTkgKEN1c3RvbWl6ZSBFZGl0IENvbnZlcnRpb24gUnVsZSknIH0pO1xuXHRcdHRoaXMuYnVpbGRVc2VyU2VsUmVwUnVsZVNldHRpbmcodGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImRldGFpbHNcIiwge1xuXHRcdFx0Y2xzOiBcImVhc3l0eXBpbmctbmVzdGVkLXNldHRpbmdzXCIsXG5cdFx0XHRhdHRyOiB7XG5cdFx0XHRcdC4uLih0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyU2VsUnVsZVNldHRpbmdzT3Blbj97IG9wZW46IHRydWUgfTp7fSlcblx0XHRcdH1cblx0XHR9KSlcblxuXHRcdHRoaXMuYnVpbGRVc2VyRGVsZXRlUnVsZVNldHRpbmcodGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImRldGFpbHNcIiwge1xuXHRcdFx0Y2xzOiBcImVhc3l0eXBpbmctbmVzdGVkLXNldHRpbmdzXCIsXG5cdFx0XHRhdHRyOiB7XG5cdFx0XHRcdC4uLih0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyRGVsUnVsZVNldHRpbmdzT3Blbj97IG9wZW46IHRydWUgfTp7fSlcblx0XHRcdH1cblx0XHR9KSlcblxuXHRcdHRoaXMuYnVpbGRVc2VyQ29udmVydFJ1bGVTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJkZXRhaWxzXCIsIHtcblx0XHRcdGNsczogXCJlYXN5dHlwaW5nLW5lc3RlZC1zZXR0aW5nc1wiLFxuXHRcdFx0YXR0cjoge1xuXHRcdFx0XHQuLi4odGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlckN2dFJ1bGVTZXR0aW5nc09wZW4/eyBvcGVuOiB0cnVlIH06e30pXG5cdFx0XHR9XG5cdFx0fSkpXG5cdFx0XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdcdTgxRUFcdTUyQThcdTY4M0NcdTVGMEZcdTUzMTZcdThCQkVcdTdGNkUgKEF1dG9mb3JtYXQgU2V0dGluZyknIH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIkF1dG8gZm9ybWF0dGluZyB3aGVuIHR5cGluZ1wiKVxuXHRcdFx0LnNldERlc2MoXCJcdTY2MkZcdTU0MjZcdTU3MjhcdTdGMTZcdThGOTFcdTY1ODdcdTY4NjNcdTY1RjZcdTgxRUFcdTUyQThcdTY4M0NcdTVGMEZcdTUzMTZcdTY1ODdcdTY3MkNcdUZGMENcdTgxRUFcdTUyQThcdTY4M0NcdTVGMEZcdTUzMTZcdTc2ODRcdTYwM0JcdTVGMDBcdTUxNzNcIilcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQXV0b0Zvcm1hdClcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BdXRvRm9ybWF0ID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnRGV0YWlsZWQgU2V0dGluZyBCZWxvdycgfSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiU3BhY2UgYmV0d2VlbiBDaGluZXNlIGFuZCBFbmdsaXNoXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1NTcyOFx1NEUyRFx1NjU4N1x1NTQ4Q1x1ODJGMVx1NjU4N1x1OTVGNFx1N0E3QVx1NjgzQ1wiKVxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5DaGluZXNlRW5nbGlzaFNwYWNlKS5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5DaGluZXNlRW5nbGlzaFNwYWNlID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiU3BhY2UgYmV0d2VlbiBDaGluZXNlIGFuZCBOdW1iZXJcIilcblx0XHRcdC5zZXREZXNjKFwiXHU1NzI4XHU0RTJEXHU2NTg3XHU1NDhDXHU2NTcwXHU1QjU3XHU5NUY0XHU3QTdBXHU2ODNDXCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkNoaW5lc2VOdW1iZXJTcGFjZSkub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQ2hpbmVzZU51bWJlclNwYWNlID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0XG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIlNwYWNlIGJldHdlZW4gRW5naWxzaCBhbmQgTnVtYmVyXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1NTcyOFx1ODJGMVx1NjU4N1x1NTQ4Q1x1NjU3MFx1NUI1N1x1OTVGNFx1N0E3QVx1NjgzQ1wiKVxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5FbmdsaXNoTnVtYmVyU3BhY2UpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkVuZ2xpc2hOdW1iZXJTcGFjZSA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIkRlbGV0ZSB0aGUgU3BhY2UgYmV0d2VlbiBDaGluZXNlIGNoYXJhY3RlcnNcIilcblx0XHRcdC5zZXREZXNjKFwiXHU1NzI4XHU0RTJEXHU2NTg3XHU1QjU3XHU3QjI2XHU5NUY0XHU1M0JCXHU5NjY0XHU3QTdBXHU2ODNDXCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkNoaW5lc2VOb1NwYWNlKS5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5DaGluZXNlTm9TcGFjZSA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZShcIkNhcGl0YWxpemUgdGhlIGZpcnN0IGxldHRlciBvZiBldmVyeSBzZW50ZW5jZVwiKVxuXHRcdFx0LnNldERlc2MoXCJcdTgyRjFcdTY1ODdcdTZCQ0ZcdTRFMkFcdTUzRTVcdTk5OTZcdTVCNTdcdTZCQ0RcdTU5MjdcdTUxOTlcIilcblx0XHRcdC5hZGREcm9wZG93bigoZHJvcGRvd24pID0+IHtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFdvcmtNb2RlLk9ubHlXaGVuVHlwaW5nLCBcIlx1OEY5M1x1NTE2NVx1NjVGNlx1NzUxRlx1NjU0OChPbmx5IFdoZW4gVHlwaW5nKVwiKTtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFdvcmtNb2RlLkdsb2JhbGx5LCBcIlx1NTE2OFx1NUM0MFx1NzUxRlx1NjU0OChXb3JrIEdsb2JhbGx5KVwiKTtcblx0XHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQXV0b0NhcGl0YWxNb2RlKTtcblx0XHRcdFx0ZHJvcGRvd24ub25DaGFuZ2UoYXN5bmMgKHY6IFdvcmtNb2RlLk9ubHlXaGVuVHlwaW5nIHwgV29ya01vZGUuR2xvYmFsbHkpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BdXRvQ2FwaXRhbE1vZGUgPSB2O1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0fSlcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuXHRcdFx0XHR0b2dnbGUuc2V0VG9vbHRpcChcIlx1NTI5Rlx1ODBGRFx1NUYwMFx1NTE3MyhTd2l0Y2gpXCIpO1xuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQXV0b0NhcGl0YWwpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkF1dG9DYXBpdGFsID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiU21hcnRseSBpbnNlcnQgc3BhY2UgYmV0d2VlbiB0ZXh0IGFuZCBwdW5jdHVhdGlvblwiKVxuXHRcdFx0LnNldERlc2MoXCJcdTU3MjhcdTY1ODdcdTY3MkNcdTU0OENcdTY4MDdcdTcwQjlcdTk1RjRcdTZERkJcdTUyQTBcdTdBN0FcdTY4M0NcIilcblx0XHRcdC5hZGREcm9wZG93bigoZHJvcGRvd24pID0+IHtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFdvcmtNb2RlLk9ubHlXaGVuVHlwaW5nLCBcIlx1OEY5M1x1NTE2NVx1NjVGNlx1NzUxRlx1NjU0OChPbmx5IFdoZW4gVHlwaW5nKVwiKTtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFdvcmtNb2RlLkdsb2JhbGx5LCBcIlx1NTE2OFx1NUM0MFx1NzUxRlx1NjU0OChXb3JrIEdsb2JhbGx5KVwiKTtcblx0XHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuUHVuY3R1YXRpb25TcGFjZU1vZGUpO1xuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodjogV29ya01vZGUuT25seVdoZW5UeXBpbmcgfCBXb3JrTW9kZS5HbG9iYWxseSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLlB1bmN0dWF0aW9uU3BhY2VNb2RlID0gdjtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdH0pXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLlB1bmN0dWF0aW9uU3BhY2UpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLlB1bmN0dWF0aW9uU3BhY2UgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJTcGFjZSBzdGF0ZWd5IGJldHdlZW4gaW5saW5lIGNvZGUgYW5kIHRleHRcIilcblx0XHRcdC5zZXREZXNjKFwiXHU1NzI4IGBcdTg4NENcdTUxODVcdTRFRTNcdTc4MDFgIFx1NTQ4Q1x1NjU4N1x1NjcyQ1x1OTVGNFx1NzY4NFx1N0E3QVx1NjgzQ1x1N0I1Nlx1NzU2NVx1MzAwMlwiICtcblx0XHRcdFx0XCJcdTY1RTBcdTg5ODFcdTZDNDJcdUZGMUFcdTVCRjlcdTY3MkNcdTdDN0JcdTUyMkJcdTU3NTdcdTRFMEVcdTVERTZcdTUzRjNcdTY1ODdcdTY3MkNcdTZDQTFcdTY3MDlcdTdBN0FcdTY4M0NcdTc2ODRcdTg5ODFcdTZDNDJcdUZGMENcIiArXG5cdFx0XHRcdFwiXHU4RjZGXHU3QTdBXHU2ODNDXHVGRjFBXHU1QkY5XHU2NzJDXHU3QzdCXHU1MjJCXHU1NzU3XHU0RTBFXHU1NDY4XHU1NkY0XHU1MzNBXHU1NzU3XHU1M0VBXHU4OTgxXHU2QzQyXHU2NzA5XHU4RjZGXHU3QTdBXHU2ODNDXHVGRjBDXHU4RjZGXHU3QTdBXHU2ODNDXHU1OTgyXHU1RjUzXHU1MjREXHU1NzU3XHU1REU2XHU4RkI5XHU3Njg0XHU0RTM0XHU4RkQxXHU2NTg3XHU2NzJDXHU0RTNBXHUzMDAyXHVGRjBDXHVGRjFCXHVGRjFGXHU3QjQ5XHU1MTY4XHU4OUQyXHU2ODA3XHU3MEI5XHVGRjBDXHU1RjUzXHU1MjREXHU1NzU3XHU1M0YzXHU4RkI5XHU3Njg0XHU0RTM0XHU4RkQxXHU2NTg3XHU2NzJDXHU0RTNBXHU2MjQwXHU2NzA5XHU1MTY4XHU1MzRBXHU4OUQyXHU2ODA3XHU3MEI5XHVGRjBDXCIgK1xuXHRcdFx0XHRcIlx1NEUyNVx1NjgzQ1x1N0E3QVx1NjgzQ1x1RkYxQVx1NUY1M1x1NTI0RFx1NTc1N1x1NEUwRVx1NEUzNFx1OEZEMVx1NjU4N1x1NjcyQ1x1NEU0Qlx1OTVGNFx1NEUyNVx1NjgzQ1x1NkRGQlx1NTJBMFx1N0E3QVx1NjgzQ1x1MzAwMlwiXG5cdFx0XHQpXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PiB7XG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihTdHJpbmcoU3BhY2VTdGF0ZS5ub25lKSwgXCJcdTY1RTBcdTg5ODFcdTZDNDIoTm8gUmVxdWlyZSlcIik7XG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihTdHJpbmcoU3BhY2VTdGF0ZS5zb2Z0KSwgXCJcdThGNkZcdTdBN0FcdTY4M0MoU29mdCBTcGFjZSlcIik7XG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihTdHJpbmcoU3BhY2VTdGF0ZS5zdHJpY3QpLCBcIlx1NEUyNVx1NjgzQ1x1N0E3QVx1NjgzQyhTdHJpY3QgU3BhY2UpXCIpO1xuXHRcdFx0XHRkcm9wZG93bi5zZXRWYWx1ZShTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3MuSW5saW5lQ29kZVNwYWNlTW9kZSkpO1xuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodjogc3RyaW5nKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuSW5saW5lQ29kZVNwYWNlTW9kZSA9IHN0cmluZzJTcGFjZVN0YXRlKHYpO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiU3BhY2Ugc3RhdGVneSBiZXR3ZWVuIGlubGluZSBmb3JtdWxhIGFuZCB0ZXh0XCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1NTcyOCAkXHU4ODRDXHU1MTg1XHU1MTZDXHU1RjBGJCBcdTU0OENcdTY1ODdcdTY3MkNcdTk1RjRcdTc2ODRcdTdBN0FcdTY4M0NcdTdCNTZcdTc1NjVcIilcblx0XHRcdC5hZGREcm9wZG93bigoZHJvcGRvd24pID0+IHtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFN0cmluZyhTcGFjZVN0YXRlLm5vbmUpLCBcIlx1NjVFMFx1ODk4MVx1NkM0MihObyBSZXF1aXJlKVwiKTtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFN0cmluZyhTcGFjZVN0YXRlLnNvZnQpLCBcIlx1OEY2Rlx1N0E3QVx1NjgzQyhTb2Z0IFNwYWNlKVwiKTtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFN0cmluZyhTcGFjZVN0YXRlLnN0cmljdCksIFwiXHU0RTI1XHU2ODNDXHU3QTdBXHU2ODNDKFN0cmljdCBTcGFjZSlcIik7XG5cdFx0XHRcdGRyb3Bkb3duLnNldFZhbHVlKFN0cmluZyh0aGlzLnBsdWdpbi5zZXR0aW5ncy5JbmxpbmVGb3JtdWxhU3BhY2VNb2RlKSk7XG5cdFx0XHRcdGRyb3Bkb3duLm9uQ2hhbmdlKGFzeW5jICh2OiBzdHJpbmcpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5JbmxpbmVGb3JtdWxhU3BhY2VNb2RlID0gc3RyaW5nMlNwYWNlU3RhdGUodik7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHR9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJTcGFjZSBzdHJhdGVneSBiZXR3ZWVuIGxpbmsgYW5kIHRleHRcIilcblx0XHRcdC5zZXREZXNjKFwiXHU1NzI4IFtbd2lraWxpbmtdXSBbbWRsaW5rXSguLi4pIFx1NTQ4Q1x1NjU4N1x1NjcyQ1x1OTVGNFx1N0E3QVx1NjgzQ1x1N0I1Nlx1NzU2NVx1MzAwMlx1NjY3QVx1ODBGRFx1N0E3QVx1NjgzQ1x1NkEyMVx1NUYwRlx1NEUwQlx1NTIxOVx1NEYxQVx1ODAwM1x1ODY1MVx1OEJFNVx1OTRGRVx1NjNBNVx1NTc1N1x1NzY4NFx1NjYzRVx1NzkzQVx1NTE4NVx1NUJCOVx1RkYwOFx1NTk4Mndpa2lcdTk0RkVcdTYzQTVcdTc2ODRcdTUyMkJcdTU0MERcdUZGMDlcdTY3NjVcdTRFMEVcdTRFMzRcdThGRDFcdTY1ODdcdTY3MkNcdThGREJcdTg4NENcdTdBN0FcdTY4M0NcdTMwMDJcIilcblx0XHRcdC5hZGREcm9wZG93bigoZHJvcGRvd24pID0+IHtcblx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFwiZHVtbXlcIiwgXCJcdTU0NDZcdTdBN0FcdTY4M0MoZHVtbXkpXCIpO1xuXHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24oXCJzbWFydFwiLCBcIlx1NjY3QVx1ODBGRFx1N0E3QVx1NjgzQyhTbWFydClcIik7XG5cdFx0XHRcdGRyb3Bkb3duLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLklubGluZUxpbmtTbWFydFNwYWNlID8gXCJzbWFydFwiIDogXCJkdW1teVwiKTtcblx0XHRcdFx0ZHJvcGRvd24ub25DaGFuZ2UoYXN5bmMgKHY6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLklubGluZUxpbmtTbWFydFNwYWNlID0gdiA9PSBcInNtYXJ0XCIgPyB0cnVlIDogZmFsc2U7XG5cdFx0XHRcdFx0Ly8gbmV3IE5vdGljZShTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3MuSW5saW5lTGlua1NtYXJ0U3BhY2UpKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdH0pXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PiB7XG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihTdHJpbmcoU3BhY2VTdGF0ZS5ub25lKSwgXCJcdTY1RTBcdTg5ODFcdTZDNDIoTm8gUmVxdWlyZSlcIik7XG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihTdHJpbmcoU3BhY2VTdGF0ZS5zb2Z0KSwgXCJcdThGNkZcdTdBN0FcdTY4M0MoU29mdCBTcGFjZSlcIik7XG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihTdHJpbmcoU3BhY2VTdGF0ZS5zdHJpY3QpLCBcIlx1NEUyNVx1NjgzQ1x1N0E3QVx1NjgzQyhTdHJpY3QgU3BhY2UpXCIpO1xuXHRcdFx0XHRkcm9wZG93bi5zZXRWYWx1ZShTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZSkpO1xuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodjogc3RyaW5nKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuSW5saW5lTGlua1NwYWNlTW9kZSA9IHN0cmluZzJTcGFjZVN0YXRlKHYpO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0fSlcblxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ1x1ODFFQVx1NUI5QVx1NEU0OVx1NkI2M1x1NTIxOVx1NTMzQVx1NTc1NyAoQ3VzdG9tIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYmxvY2spJyB9KTtcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiVXNlciBEZWZpbmVkIFJlZ0V4cCBTd2l0Y2hcIilcblx0XHRcdC5zZXREZXNjKFwiXHU4MUVBXHU1QjlBXHU0RTQ5XHU2QjYzXHU1MjE5XHU4ODY4XHU4RkJFXHU1RjBGXHU1RjAwXHU1MTczXHVGRjBDXHU1MzM5XHU5MTREXHU1MjMwXHU3Njg0XHU1MTg1XHU1QkI5XHU0RTBEXHU4RkRCXHU4ODRDXHU2ODNDXHU1RjBGXHU1MzE2XHVGRjBDXHU0RTE0XHU1M0VGXHU0RUU1XHU4QkJFXHU3RjZFXHU1MzM5XHU5MTREXHU1MjMwXHU3Njg0XHU1MTg1XHU1QkI5XHU1NzU3XHU0RTBFXHU1MTc2XHU0RUQ2XHU1MTg1XHU1QkI5XHU0RTRCXHU5NUY0XHU3Njg0XHU3QTdBXHU2ODNDXHU3QjU2XHU3NTY1XCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLlVzZXJEZWZpbmVkUmVnU3dpdGNoKS5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5Vc2VyRGVmaW5lZFJlZ1N3aXRjaCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0Y29udGFpbmVyRWwuY3JlYXRlRWwoXCJwXCIsIHsgdGV4dDogXCJcdTZCNjNcdTUyMTlcdTg4NjhcdThGQkVcdTVGMEZcdTc2RjhcdTUxNzNcdTc3RTVcdThCQzZcdUZGMENcdTg5QzEgXCIgfSkuY3JlYXRlRWwoXCJhXCIsIHtcblx0XHRcdHRleHQ6IFwiXHUzMDBBXHU5NjJFXHU0RTAwXHU1Q0YwXHVGRjFBXHU2QjYzXHU1MjE5XHU4ODY4XHU4RkJFXHU1RjBGXHU3QjgwXHU2NjBFXHU2NTU5XHU3QTBCXHUzMDBCXCIsXG5cdFx0XHRocmVmOiBcImh0dHBzOi8vamF2YXNjcmlwdC5ydWFueWlmZW5nLmNvbS9zdGRsaWIvcmVnZXhwLmh0bWwjXCIsXG5cdFx0fSk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBcIlx1NkI2M1x1NTIxOVx1ODg2OFx1OEZCRVx1NUYwRlx1ODlDNFx1NTIxOVx1NEY3Rlx1NzUyOFx1OEJGNFx1NjYwRVx1NEUwRVx1NzkzQVx1NEY4Qlx1RkYxQVwiIH0pLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHR0ZXh0OiBcIlx1ODFFQVx1NUI5QVx1NEU0OVx1NkI2M1x1NTIxOVx1ODg2OFx1OEZCRVx1NUYwRlx1ODlDNFx1NTIxOVwiLFxuXHRcdFx0aHJlZjogXCJodHRwczovL2dpdGh1Yi5jb20vWWFvemh1d2EvZWFzeS10eXBpbmctb2JzaWRpYW4vYmxvYi9tYXN0ZXIvVXNlckRlZmluZWRSZWdFeHAubWRcIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IHJlZ0NvbnRlbnRBcmVhU2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcblx0XHRyZWdDb250ZW50QXJlYVNldHRpbmcuc2V0dGluZ0VsLnNldEF0dHJpYnV0ZShcblx0XHRcdFwic3R5bGVcIixcblx0XHRcdFwiZGlzcGxheTogZ3JpZDsgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnI7XCJcblx0XHQpO1xuXHRcdHJlZ0NvbnRlbnRBcmVhU2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoXCJVc2VyLWRlZmluZWQgUmVndWxhciBFeHByZXNzaW9uLCBvbmUgZXhwcmVzc2lvbiBwZXIgbGluZVwiKVxuXHRcdFx0LnNldERlc2MoXG5cdFx0XHRcdFwiXHU3NTI4XHU2MjM3XHU4MUVBXHU1QjlBXHU0RTQ5XHU2QjYzXHU1MjE5XHU4ODY4XHU4RkJFXHU1RjBGXHVGRjBDXHU1MzM5XHU5MTREXHU1MjMwXHU3Njg0XHU1MTg1XHU1QkI5XHU0RTBEXHU4RkRCXHU4ODRDXHU2ODNDXHU1RjBGXHU1MzE2XHVGRjBDXHU2QkNGXHU4ODRDXHU0RTAwXHU0RTJBXHU4ODY4XHU4RkJFXHU1RjBGXHVGRjBDXHU4ODRDXHU1QzNFXHU0RTBEXHU4OTgxXHU5NjhGXHU2MTBGXHU1MkEwXHU3QTdBXHU2ODNDXHUzMDAyXCIgK1xuXHRcdFx0XHRcIlx1NkJDRlx1ODg0Q1x1NjcyQlx1NUMzRTNcdTRFMkFcdTVCNTdcdTdCMjZcdTc2ODRcdTU2RkFcdTVCOUFcdTRFM0F8XHU1NDhDXHU0RTI0XHU0RTJBXHU3QTdBXHU2ODNDXHU3QjU2XHU3NTY1XHU3QjI2XHU1M0Y3XHVGRjBDXHU3QTdBXHU2ODNDXHU3QjU2XHU3NTY1XHU3QjI2XHU1M0Y3XHU0RTNBLT0rXHVGRjBDXHU1MjA2XHU1MjJCXHU0RUUzXHU4ODY4XHU0RTBEXHU4OTgxXHU2QzQyXHU3QTdBXHU2ODNDKC0pXHVGRjBDXHU4RjZGXHU3QTdBXHU2ODNDKD0pXHVGRjBDXHU0RTI1XHU2ODNDXHU3QTdBXHU2ODNDKCspXHUzMDAyXCIgK1xuXHRcdFx0XHRcIlx1OEZEOVx1NEUyNFx1NEUyQVx1N0E3QVx1NjgzQ1x1N0I1Nlx1NzU2NVx1N0IyNlx1NTNGN1x1NTIwNlx1NTIyQlx1NEUzQVx1NTMzOVx1OTE0RFx1NTMzQVx1NTc1N1x1NzY4NFx1NURFNlx1NTNGM1x1NEUyNFx1OEZCOVx1NzY4NFx1N0E3QVx1NjgzQ1x1N0I1Nlx1NzU2NVwiXG5cdFx0XHQpO1xuXHRcdGNvbnN0IHJlZ0NvbnRlbnRBcmVhID0gbmV3IFRleHRBcmVhQ29tcG9uZW50KFxuXHRcdFx0cmVnQ29udGVudEFyZWFTZXR0aW5nLmNvbnRyb2xFbFxuXHRcdCk7XG5cblx0XHRzZXRBdHRyaWJ1dGVzKHJlZ0NvbnRlbnRBcmVhLmlucHV0RWwsIHtcblx0XHRcdHN0eWxlOiBcIm1hcmdpbi10b3A6IDEycHg7IHdpZHRoOiAxMDAlOyAgaGVpZ2h0OiAzMHZoO1wiLFxuXHRcdFx0Ly8gY2xhc3M6IFwibXMtY3NzLWVkaXRvclwiLFxuXHRcdH0pO1xuXHRcdHJlZ0NvbnRlbnRBcmVhXG5cdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuVXNlckRlZmluZWRSZWdFeHApXG5cdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLlVzZXJEZWZpbmVkUmVnRXhwID0gdmFsdWU7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0fSk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdcdTYzMDdcdTVCOUFcdTY1ODdcdTRFRjZcdTRFMERcdTgxRUFcdTUyQThcdTY4M0NcdTVGMEZcdTUzMTYgKEV4Y2x1ZGUgRm9sZGVycy9GaWxlcyknIH0pO1xuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJFeGNsdWRlIEZvbGRlcnMvRmlsZXNcIilcblx0XHRcdC5zZXREZXNjKFwiVGhpcyBwbHVnaW4gd2lsbCBwYXJzZSBlYWNoIGxpbmUgYXMgYSBleGx1ZGUgZm9sZGVyIG9yIGZpbGUuIEZvciBleGFtcGxlOiBEYWlseU5vdGUvLCBEYWlseU5vdGUvV2Vla05vdGVzLywgRGFpbHlOb3RlL3Rlc3QubWRcIilcblx0XHRcdC5hZGRUZXh0QXJlYSgodGV4dCkgPT5cblx0XHRcdFx0dGV4dFxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5FeGNsdWRlRmlsZXMpXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuRXhjbHVkZUZpbGVzID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHRcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdFeHBlcmltZW50YWwgRmVhdHVyZXMnIH0pO1xuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJGaXggTWFjT1MgY29udGV4dC1tZW51IGN1cnNvciBwb3NpdGlvbihOZWVkIHRvIHJlc3RhcnQgT2JzaWRpYW4pXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1NEZFRVx1NTkwRCBNYWNPUyBcdTlGMjBcdTY4MDdcdTUzRjNcdTk1MkVcdTU0N0NcdTUxRkFcdTgzRENcdTUzNTVcdTY1RjZcdTUxNDlcdTY4MDdcdThERjNcdTUyMzBcdTRFMEJcdTRFMDBcdTg4NENcdTc2ODRcdTk1RUVcdTk4OTgoXHU5NzAwXHU4OTgxXHU5MUNEXHU1NDJGT2JzaWRpYW5cdTc1MUZcdTY1NDgpXCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkZpeE1hY09TQ29udGV4dE1lbnUpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkZpeE1hY09TQ29udGV4dE1lbnUgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJGaXggTWljcm9Tb2Z0IElucHV0IE1ldGhvZCBJc3N1ZVwiKVxuXHRcdFx0LnNldERlc2MoXCJcdTkwMDJcdTkxNERcdTY1RTdcdTcyNDhcdTVGQUVcdThGNkZcdThGOTNcdTUxNjVcdTZDRDVcIilcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuVHJ5Rml4TVNJTUUpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLlRyeUZpeE1TSU1FID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiU3RyaWN0IExpbmUgYnJlYWtzIE1vZGUgRW50ZXIgVHdpY2VcIilcblx0XHRcdC5zZXREZXNjKFwiXHU0RTI1XHU2ODNDXHU2MzYyXHU4ODRDXHU3Njg0XHU4QkJFXHU3RjZFXHU0RTBCXHVGRjBDXHU1NzI4XHU2NjZFXHU5MDFBXHU2NTg3XHU2NzJDXHU4ODRDXHU4RkRCXHU4ODRDXHU0RTAwXHU2QjIxXHU1NkRFXHU4RjY2XHU0RjFBXHU0RUE3XHU3NTFGXHU0RTI0XHU0RTJBXHU2MzYyXHU4ODRDXHU3QjI2XCIpXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkVudGVyVHdpY2UpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkVudGVyVHdpY2UgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHRcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiUHVuYyByZWN0aWZ5XCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1NEVDNVx1NTcyOFx1OEY5M1x1NTE2NVx1OEZDN1x1N0EwQlx1NEUyRFx1RkYwQ1x1NEUyRFx1NjU4N1x1OTVGNFx1NzY4NFx1ODJGMVx1NjU4N1x1NjgwN1x1NzBCOVx1RkYwOCwuPyFcdUZGMDlcdTgxRUFcdTUyQThcdThGNkNcdTYzNjJcdTRFM0FcdTUxNjhcdTg5RDJcdUZGMDhcdTUzRUZcdTY0QTRcdTk1MDBcdUZGMDlcIilcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuUHVuY1JlY3RpZnkpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLlB1bmNSZWN0aWZ5ID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiUHJpbnQgZGVidWcgaW5mbyBpbiBjb25zb2xlXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1NTcyOFx1NjNBN1x1NTIzNlx1NTNGMFx1OEY5M1x1NTFGQVx1OEMwM1x1OEJENVx1NEZFMVx1NjA2RlwiKVxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWJ1Zykub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVidWcgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0fVxuXG5cdGJ1aWxkVXNlclNlbFJlcFJ1bGVTZXR0aW5nKGNvbnRhaW5lckVsOiBIVE1MRGV0YWlsc0VsZW1lbnQpe1xuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG4gICAgICAgIGNvbnRhaW5lckVsLm9udG9nZ2xlID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlclNlbFJ1bGVTZXR0aW5nc09wZW4gPSBjb250YWluZXJFbC5vcGVuO1xuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgIH07XG5cdFx0Y29uc3Qgc3VtbWFyeSA9IGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwic3VtbWFyeVwiLCB7Y2xzOiBcImVhc3l0eXBpbmctbmVzdGVkLXNldHRpbmdzXCJ9KTtcblx0XHRzdW1tYXJ5LnNldFRleHQoXCJcdTgxRUFcdTVCOUFcdTRFNDlcdTkwMDlcdTRFMkRcdTY1ODdcdTY3MkNcdTdGMTZcdThGOTFcdTU4OUVcdTVGM0FcdTg5QzRcdTUyMTkgKEN1c3RvbWl6ZSBTZWxlY3Rpb24gUmVwbGFjZSBSdWxlKVwiKVxuXG4gICAgICAgIC8vIHN1bW1hcnkuc2V0SGVhZGluZygpLnNldE5hbWUoXCJVc2VyIGRlZmluZWQgU2VsZWN0aW9uIFJlcGxhY2UgUnVsZVwiKTtcbiAgICAgICAgLy8gc3VtbWFyeS5jcmVhdGVEaXYoXCJjb2xsYXBzZXJcIikuY3JlYXRlRGl2KFwiaGFuZGxlXCIpO1xuXG5cdFx0Y29uc3Qgc2VsZWN0aW9uUnVsZVNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XG5cdFx0c2VsZWN0aW9uUnVsZVNldHRpbmdcblx0XHRcdC5zZXROYW1lKFwiU2VsZWN0aW9uIFJlcGxlY2UgUnVsZVwiKVxuXG5cdFx0Y29uc3QgcmVwbGFjZVJ1bGVUcmlnZ2VyID0gbmV3IFRleHRDb21wb25lbnQoc2VsZWN0aW9uUnVsZVNldHRpbmcuY29udHJvbEVsKTtcblx0XHRyZXBsYWNlUnVsZVRyaWdnZXIuc2V0UGxhY2Vob2xkZXIoXCJUcmlnZ3IgU3ltYm9sXCIpO1xuXG5cdFx0Y29uc3QgcmVwbGFjZUxlZnRTdHJpbmcgPSBuZXcgVGV4dEFyZWFDb21wb25lbnQoc2VsZWN0aW9uUnVsZVNldHRpbmcuY29udHJvbEVsKTtcblx0XHRyZXBsYWNlTGVmdFN0cmluZy5zZXRQbGFjZWhvbGRlcihcIk5ldyBMZWZ0IFNpZGUgU3RyaW5nXCIpO1xuXG5cdFx0Y29uc3QgcmVwbGFjZVJpZ2h0U3RyaW5nID0gbmV3IFRleHRBcmVhQ29tcG9uZW50KHNlbGVjdGlvblJ1bGVTZXR0aW5nLmNvbnRyb2xFbCk7XG5cdFx0cmVwbGFjZVJpZ2h0U3RyaW5nLnNldFBsYWNlaG9sZGVyKFwiTmV3IFJpZ2h0IFNpZGUgU3RyaW5nXCIpO1xuXG5cdFx0c2VsZWN0aW9uUnVsZVNldHRpbmdcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT4ge1xuXHRcdFx0XHRidXR0b25cblx0XHRcdFx0XHQuc2V0QnV0dG9uVGV4dChcIitcIilcblx0XHRcdFx0XHQuc2V0VG9vbHRpcChcIkFkZCBSdWxlXCIpXG5cdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKGJ1dHRvbkVsOiBhbnkpID0+IHtcblx0XHRcdFx0XHRcdGxldCB0cmlnZ2VyID0gcmVwbGFjZVJ1bGVUcmlnZ2VyLmlucHV0RWwudmFsdWU7XG5cdFx0XHRcdFx0XHRsZXQgbGVmdCA9IHJlcGxhY2VMZWZ0U3RyaW5nLmlucHV0RWwudmFsdWU7XG5cdFx0XHRcdFx0XHRsZXQgcmlnaHQgPSByZXBsYWNlUmlnaHRTdHJpbmcuaW5wdXRFbC52YWx1ZTtcblx0XHRcdFx0XHRcdGlmICh0cmlnZ2VyICYmIChsZWZ0IHx8IHJpZ2h0KSkge1xuXHRcdFx0XHRcdFx0XHRpZih0cmlnZ2VyLmxlbmd0aCE9MSAmJiB0cmlnZ2VyIT1cIlx1MjAxNFx1MjAxNFwiICYmIHRyaWdnZXIhPVwiXHUyMDI2XHUyMDI2XCIpe1xuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJJbmx2YWxpZCB0cmlnZ2VyLCB0cmlnZ2VyIG11c3QgYmUgYSBzeW1ib2wgb2YgbGVuZ3RoIDEgb3Igc3ltYm9sIFx1MjAxNFx1MjAxNCwgXHUyMDI2XHUyMDI2XCIpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZiAodGhpcy5wbHVnaW4uYWRkVXNlclNlbGVjdGlvblJlcFJ1bGUodHJpZ2dlciwgbGVmdCwgcmlnaHQpKXtcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRlbHNle1xuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJ3YXJuaW5nISBUcmlnZ2VyIFwiICsgdHJpZ2dlciArIFwiIGlzIGFscmVhZHkgZXhpc3QhXCIpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwibWlzc2luZyBpbnB1dFwiKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0Ly8gY29uc3Qgc2VsUmVwUnVsZUNvbnRhaW5lciA9IGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlclNlbFJlcFJ1bGVUcmlnZ2VyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRsZXQgdHJpZ2dlciA9IHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVHJpZ2dlcltpXTtcblx0XHRcdGxldCBsZWZ0X3MgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyU2VsUmVwUnVsZVZhbHVlW2ldLmxlZnQ7XG5cdFx0XHRsZXQgcmlnaHRfcyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZXJTZWxSZXBSdWxlVmFsdWVbaV0ucmlnaHQ7XG5cdFx0XHRsZXQgc2hvd1N0ciA9IFwiVHJpZ2dlcjogXCIgKyB0cmlnZ2VyICsgXCIgXHUyMTkyIFwiICsgc2hvd1N0cmluZyhsZWZ0X3MpICsgXCJzZWxlY3RlZFwiICsgc2hvd1N0cmluZyhyaWdodF9zKTtcblx0XHRcdC8vIGNvbnN0IHNldHRpbmdJdGVtID0gc2VsUmVwUnVsZUNvbnRhaW5lci5jcmVhdGVFbChcImRpdlwiKTtcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHQuc2V0TmFtZShzaG93U3RyKVxuXHRcdFx0XHQuYWRkRXh0cmFCdXR0b24oYnV0dG9uID0+IHtcblx0XHRcdFx0XHRidXR0b24uc2V0SWNvbihcImdlYXJcIilcblx0XHRcdFx0XHRcdC5zZXRUb29sdGlwKFwiRWRpdCBydWxlXCIpXG5cdFx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdG5ldyBTZWxlY3RSdWxlRWRpdE1vZGFsKHRoaXMuYXBwLCB0cmlnZ2VyLGxlZnRfcywgcmlnaHRfcywgYXN5bmMgKG5ld19sZWZ0LCBuZXdfcmlnaHQpID0+IHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi51cGRhdGVVc2VyU2VsZWN0aW9uUmVwUnVsZShpLCBuZXdfbGVmdCwgbmV3X3JpZ2h0KTtcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdFx0fSkub3BlbigpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ1dHRvbiA9PiB7XG5cdFx0XHRcdFx0YnV0dG9uLnNldEljb24oXCJ0cmFzaFwiKVxuXHRcdFx0XHRcdFx0LnNldFRvb2x0aXAoXCJSZW1vdmUgcnVsZVwiKVxuXHRcdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5kZWxldGVVc2VyU2VsZWN0aW9uUmVwUnVsZShpKTtcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSk7XG5cdFx0fVxuXG5cblx0fVxuXG5cdGJ1aWxkVXNlckRlbGV0ZVJ1bGVTZXR0aW5nKGNvbnRhaW5lckVsOiBIVE1MRGV0YWlsc0VsZW1lbnQpe1xuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG4gICAgICAgIGNvbnRhaW5lckVsLm9udG9nZ2xlID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlckRlbFJ1bGVTZXR0aW5nc09wZW4gPSBjb250YWluZXJFbC5vcGVuO1xuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgIH07XG5cdFx0Y29uc3Qgc3VtbWFyeSA9IGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwic3VtbWFyeVwiLCB7Y2xzOiBcImVhc3l0eXBpbmctbmVzdGVkLXNldHRpbmdzXCJ9KTtcblx0XHRzdW1tYXJ5LnNldFRleHQoXCJcdTgxRUFcdTVCOUFcdTRFNDlcdTUyMjBcdTk2NjRcdTdGMTZcdThGOTFcdTU4OUVcdTVGM0FcdTg5QzRcdTUyMTkgKEN1c3RvbWl6ZSBEZWxldGUgUnVsZSlcIilcblxuXHRcdGNvbnN0IGRlbGV0ZVJ1bGVTZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpO1xuXHRcdGRlbGV0ZVJ1bGVTZXR0aW5nXG5cdFx0XHQuc2V0TmFtZShcIkRlbGV0ZSBSdWxlXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlx1ODlDNFx1NTIxOVx1RkYxQVx1NzUyOHxcdTRFRTNcdTg4NjhcdTUxNDlcdTY4MDdcdTRGNERcdTdGNkVcdUZGMENcdTVGQzVcdTk4N0JcdTUzMDVcdTU0MkJcdTUxNDlcdTY4MDdcdTMwMDIgVGlwczogVXNpbmcgfCB0byBpbmRpY2F0ZSB0aGUgY3Vyc29yIHBvc2l0aW9uLlwiKVxuXG5cdFx0Y29uc3QgcGF0dGVybkJlZm9yZSA9IG5ldyBUZXh0QXJlYUNvbXBvbmVudChkZWxldGVSdWxlU2V0dGluZy5jb250cm9sRWwpO1xuXHRcdHBhdHRlcm5CZWZvcmUuc2V0UGxhY2Vob2xkZXIoXCJCZWZvcmUgRGVsZXRlXCIpO1xuXG5cdFx0Y29uc3QgcGF0dGVybkFmdGVyID0gbmV3IFRleHRBcmVhQ29tcG9uZW50KGRlbGV0ZVJ1bGVTZXR0aW5nLmNvbnRyb2xFbCk7XG5cdFx0cGF0dGVybkFmdGVyLnNldFBsYWNlaG9sZGVyKFwiTmV3IFBhdHRlcm5cIik7XG5cblx0XHRkZWxldGVSdWxlU2V0dGluZ1xuXHRcdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PiB7XG5cdFx0XHRcdGJ1dHRvblxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KFwiK1wiKVxuXHRcdFx0XHRcdC5zZXRUb29sdGlwKFwiQWRkIFJ1bGVcIilcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoYnV0dG9uRWw6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0bGV0IGJlZm9yZSA9IHBhdHRlcm5CZWZvcmUuaW5wdXRFbC52YWx1ZTtcblx0XHRcdFx0XHRcdGxldCBhZnRlciA9IHBhdHRlcm5BZnRlci5pbnB1dEVsLnZhbHVlO1xuXHRcdFx0XHRcdFx0aWYgKGJlZm9yZSAmJiBhZnRlcikge1xuXHRcdFx0XHRcdFx0XHRsZXQgcmVnUnVsZSA9IC9cXHwvZztcblx0XHRcdFx0XHRcdFx0aWYoYmVmb3JlLnNlYXJjaChyZWdSdWxlKT09LTF8fGFmdGVyLnNlYXJjaChyZWdSdWxlKT09LTEpe1xuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJJbmx2YWxpZCB0cmlnZ2VyLCBwYXR0ZXJuIG11c3QgY29udGFpbiBzeW1ib2wgXFx8IHdoaWNoIGluZGljYXRlIGN1cnNvciBwb3NpdGlvblwiKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWxzZXtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hZGRVc2VyRGVsZXRlUnVsZShiZWZvcmUsIGFmdGVyKTtcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJtaXNzaW5nIGlucHV0XCIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZXJEZWxldGVSdWxlc1N0ckxpc3QubGVuZ3RoOyBpKyspe1xuXHRcdFx0bGV0IGJlZm9yZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZXJEZWxldGVSdWxlc1N0ckxpc3RbaV1bMF07XG5cdFx0XHRsZXQgYWZ0ZXIgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyRGVsZXRlUnVsZXNTdHJMaXN0W2ldWzFdO1xuXHRcdFx0bGV0IHNob3dTdHIgPSBcIlxcXCJcIiArIHNob3dTdHJpbmcoYmVmb3JlKSArIFwiXFxcIiAgZGVsZXRlLmJhY2t3YXJkcyAgXHUyMTkyIFxcXCJcIisgc2hvd1N0cmluZyhhZnRlcikrXCJcXFwiXCI7IFxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHRcdC5zZXROYW1lKHNob3dTdHIpXG5cdFx0XHRcdC5hZGRFeHRyYUJ1dHRvbihidXR0b24gPT4ge1xuXHRcdFx0XHRcdGJ1dHRvbi5zZXRJY29uKFwiZ2VhclwiKVxuXHRcdFx0XHRcdFx0LnNldFRvb2x0aXAoXCJFZGl0IHJ1bGVcIilcblx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHRcdFx0bmV3IEVkaXRDb252ZXJ0UnVsZU1vZGFsKHRoaXMuYXBwLCBSdWxlVHlwZS5kZWxldGUsIGJlZm9yZSwgYWZ0ZXIsIGFzeW5jIChuZXdfYmVmb3JlLCBuZXdfYWZ0ZXIpID0+IHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi51cGRhdGVVc2VyRGVsZXRlUnVsZShpLCBuZXdfYmVmb3JlLCBuZXdfYWZ0ZXIpO1xuXHRcdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdFx0XHR9KS5vcGVuKCk7XG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYWRkRXh0cmFCdXR0b24oYnV0dG9uID0+IHtcblx0XHRcdFx0XHRidXR0b24uc2V0SWNvbihcInRyYXNoXCIpXG5cdFx0XHRcdFx0XHQuc2V0VG9vbHRpcChcIlJlbW92ZSBydWxlXCIpXG5cdFx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmRlbGV0ZVVzZXJEZWxldGVSdWxlKGkpO1xuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9KTtcblx0XHR9XG5cblx0fVxuXG5cdGJ1aWxkVXNlckNvbnZlcnRSdWxlU2V0dGluZyhjb250YWluZXJFbDogSFRNTERldGFpbHNFbGVtZW50KXtcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xuICAgICAgICBjb250YWluZXJFbC5vbnRvZ2dsZSA9IGFzeW5jICgpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnVzZXJDdnRSdWxlU2V0dGluZ3NPcGVuID0gY29udGFpbmVyRWwub3Blbjtcblx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICB9O1xuXHRcdGNvbnN0IHN1bW1hcnkgPSBjb250YWluZXJFbC5jcmVhdGVFbChcInN1bW1hcnlcIiwge2NsczogXCJlYXN5dHlwaW5nLW5lc3RlZC1zZXR0aW5nc1wifSk7XG5cdFx0c3VtbWFyeS5zZXRUZXh0KFwiXHU4MUVBXHU1QjlBXHU0RTQ5XHU3RjE2XHU4RjkxXHU4RjZDXHU2MzYyXHU4OUM0XHU1MjE5IChDdXN0b21pemUgQ29udmVydCBSdWxlKVwiKVxuXG5cdFx0Y29uc3QgY29udmVydFJ1bGVTZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpO1xuXHRcdGNvbnZlcnRSdWxlU2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoXCJDb252ZXJ0IFJ1bGVcIilcblx0XHRcdC5zZXREZXNjKFwiXHU4OUM0XHU1MjE5XHVGRjFBXHU3NTI4fFx1NEVFM1x1ODg2OFx1NTE0OVx1NjgwN1x1NEY0RFx1N0Y2RVx1RkYwQ1x1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlx1NTE0OVx1NjgwN1x1MzAwMiBUaXBzOiBVc2luZyB8IHRvIGluZGljYXRlIHRoZSBjdXJzb3IgcG9zaXRpb24uXCIpXG5cblx0XHRjb25zdCBwYXR0ZXJuQmVmb3JlID0gbmV3IFRleHRBcmVhQ29tcG9uZW50KGNvbnZlcnRSdWxlU2V0dGluZy5jb250cm9sRWwpO1xuXHRcdHBhdHRlcm5CZWZvcmUuc2V0UGxhY2Vob2xkZXIoXCJCZWZvcmUgQ29udmVydFwiKTtcblxuXHRcdGNvbnN0IHBhdHRlcm5BZnRlciA9IG5ldyBUZXh0QXJlYUNvbXBvbmVudChjb252ZXJ0UnVsZVNldHRpbmcuY29udHJvbEVsKTtcblx0XHRwYXR0ZXJuQWZ0ZXIuc2V0UGxhY2Vob2xkZXIoXCJOZXcgUGF0dGVyblwiKTtcblxuXHRcdGNvbnZlcnRSdWxlU2V0dGluZ1xuXHRcdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PiB7XG5cdFx0XHRcdGJ1dHRvblxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KFwiK1wiKVxuXHRcdFx0XHRcdC5zZXRUb29sdGlwKFwiQWRkIFJ1bGVcIilcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoYnV0dG9uRWw6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0bGV0IGJlZm9yZSA9IHBhdHRlcm5CZWZvcmUuaW5wdXRFbC52YWx1ZTtcblx0XHRcdFx0XHRcdGxldCBhZnRlciA9IHBhdHRlcm5BZnRlci5pbnB1dEVsLnZhbHVlO1xuXHRcdFx0XHRcdFx0aWYgKGJlZm9yZSAmJiBhZnRlcikge1xuXHRcdFx0XHRcdFx0XHRsZXQgcmVnUnVsZSA9IC9cXHwvZztcblx0XHRcdFx0XHRcdFx0aWYoYmVmb3JlLnNlYXJjaChyZWdSdWxlKT09LTF8fGFmdGVyLnNlYXJjaChyZWdSdWxlKT09LTEpe1xuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJJbmx2YWxpZCB0cmlnZ2VyLCBwYXR0ZXJuIG11c3QgY29udGFpbiBzeW1ib2wgXFx8IHdoaWNoIGluZGljYXRlIGN1cnNvciBwb3NpdGlvblwiKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWxzZXtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hZGRVc2VyQ29udmVydFJ1bGUoYmVmb3JlLCBhZnRlcik7XG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwibWlzc2luZyBpbnB1dFwiKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyQ29udmVydFJ1bGVzU3RyTGlzdC5sZW5ndGg7IGkrKyl7XG5cdFx0XHRsZXQgYmVmb3JlID0gdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlckNvbnZlcnRSdWxlc1N0ckxpc3RbaV1bMF07XG5cdFx0XHRsZXQgYWZ0ZXIgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyQ29udmVydFJ1bGVzU3RyTGlzdFtpXVsxXTtcblx0XHRcdGxldCBzaG93U3RyID0gXCJcXFwiXCIgKyBzaG93U3RyaW5nKGJlZm9yZSkgKyBcIlxcXCIgIGF1dG8gY29udmVydCB0byBcXFwiXCIrIHNob3dTdHJpbmcoYWZ0ZXIpK1wiXFxcIlwiOyBcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHQuc2V0TmFtZShzaG93U3RyKVxuXHRcdFx0XHQuYWRkRXh0cmFCdXR0b24oYnV0dG9uID0+IHtcblx0XHRcdFx0XHRidXR0b24uc2V0SWNvbihcImdlYXJcIilcblx0XHRcdFx0XHRcdC5zZXRUb29sdGlwKFwiRWRpdCBydWxlXCIpXG5cdFx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdG5ldyBFZGl0Q29udmVydFJ1bGVNb2RhbCh0aGlzLmFwcCwgUnVsZVR5cGUuY29udmVydCwgYmVmb3JlLCBhZnRlciwgYXN5bmMgKG5ld19iZWZvcmUsIG5ld19hZnRlcikgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnVwZGF0ZVVzZXJDb252ZXJ0UnVsZShpLCBuZXdfYmVmb3JlLCBuZXdfYWZ0ZXIpO1xuXHRcdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdFx0XHR9KS5vcGVuKCk7XG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYWRkRXh0cmFCdXR0b24oYnV0dG9uID0+IHtcblx0XHRcdFx0XHRidXR0b24uc2V0SWNvbihcInRyYXNoXCIpXG5cdFx0XHRcdFx0XHQuc2V0VG9vbHRpcChcIlJlbW92ZSBydWxlXCIpXG5cdFx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmRlbGV0ZVVzZXJDb252ZXJ0UnVsZShpKTtcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cbn1cblxuXG5mdW5jdGlvbiBzZXRBdHRyaWJ1dGVzKGVsZW1lbnQ6IGFueSwgYXR0cmlidXRlczogYW55KSB7XG5cdGZvciAobGV0IGtleSBpbiBhdHRyaWJ1dGVzKSB7XG5cdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCBhdHRyaWJ1dGVzW2tleV0pO1xuXHR9XG59XG5cblxuZXhwb3J0IGNsYXNzIFNlbGVjdFJ1bGVFZGl0TW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdHRyaWdnZXI6IHN0cmluZztcblx0b2xkX2xlZnQ6IHN0cmluZztcblx0b2xkX3JpZ2h0OiBzdHJpbmc7XG5cdG5ld19sZWZ0OiBzdHJpbmc7XG5cdG5ld19yaWdodDogc3RyaW5nO1xuXHRvblN1Ym1pdDogKG5ld19sZWZ0OiBzdHJpbmcsIG5ld19yaWdodDpzdHJpbmcpID0+IHZvaWQ7XG5cblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHRyaWdnZXI6IHN0cmluZywgbGVmdDogc3RyaW5nLCByaWdodDogc3RyaW5nLCBvblN1Ym1pdDogKG5ld19sZWZ0OiBzdHJpbmcsIG5ld19yaWdodDpzdHJpbmcpID0+IHZvaWQpIHtcblx0XHRzdXBlcihhcHApO1xuXHRcdHRoaXMudHJpZ2dlciA9IHRyaWdnZXI7XG5cdFx0dGhpcy5vbGRfbGVmdCA9IGxlZnQ7XG5cdFx0dGhpcy5vbGRfcmlnaHQgPSByaWdodDtcblx0XHR0aGlzLm5ld19sZWZ0ID0gbGVmdDtcblx0XHR0aGlzLm5ld19yaWdodCA9IHJpZ2h0O1xuXG5cdFx0dGhpcy5vblN1Ym1pdCA9IG9uU3VibWl0O1xuXHR9XG5cblx0b25PcGVuKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwiaDFcIiwgeyB0ZXh0OiBcIkVkaXQgU2VsZWN0aW9uIFJlcGxhY2UgUnVsZVwiIH0pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxuXHRcdFx0LnNldE5hbWUoXCJUcmlnZ2VyXCIpXG5cdFx0XHQuYWRkVGV4dCgodGV4dCkgPT4ge1xuXHRcdFx0XHR0ZXh0LnNldFZhbHVlKHRoaXMudHJpZ2dlcik7XG5cdFx0XHRcdHRleHQuc2V0RGlzYWJsZWQodHJ1ZSk7XG5cdFx0XHR9KVxuXHRcdFxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcblx0XHRcdC5zZXROYW1lKFwiTGVmdFwiKVxuXHRcdFx0LmFkZFRleHRBcmVhKCh0ZXh0KSA9PiB7XG5cdFx0XHRcdHRleHQuc2V0VmFsdWUodGhpcy5vbGRfbGVmdCk7XG5cdFx0XHRcdHRleHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5uZXdfbGVmdCA9IHZhbHVlXG5cdFx0XHRcdH0pXG5cdFx0XHR9KVxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcblx0XHRcdC5zZXROYW1lKFwiUmlnaHRcIilcblx0XHRcdC5hZGRUZXh0QXJlYSgodGV4dCkgPT4ge1xuXHRcdFx0XHR0ZXh0LnNldFZhbHVlKHRoaXMub2xkX3JpZ2h0KTtcblx0XHRcdFx0dGV4dC5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLm5ld19yaWdodCA9IHZhbHVlXG5cdFx0XHRcdH0pXG5cdFx0XHR9KTtcblxuXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxuXHRcdFx0LmFkZEJ1dHRvbigoYnRuKSA9PlxuXHRcdFx0XHRidG5cblx0XHRcdFx0XHQuc2V0QnV0dG9uVGV4dChcIlVwZGF0ZVwiKVxuXHRcdFx0XHRcdC5zZXRDdGEoKVxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMuY2xvc2UoKTtcblx0XHRcdFx0XHRcdHRoaXMub25TdWJtaXQodGhpcy5uZXdfbGVmdCwgdGhpcy5uZXdfcmlnaHQpO1xuXHRcdFx0XHRcdH0pKTtcblx0fVxuXG5cdG9uQ2xvc2UoKSB7XG5cdFx0bGV0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xuXHR9XG59XG5cblxuXG5leHBvcnQgY2xhc3MgRWRpdENvbnZlcnRSdWxlTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdHR5cGU6IFJ1bGVUeXBlO1xuXHRvbGRfYmVmb3JlOiBzdHJpbmc7XG5cdG9sZF9hZnRlcjogc3RyaW5nO1xuXHRuZXdfYmVmb3JlOiBzdHJpbmc7XG5cdG5ld19hZnRlcjogc3RyaW5nO1xuXHRvblN1Ym1pdDogKG5ld19iZWZvcmU6IHN0cmluZywgbmV3X2FmdGVyOnN0cmluZykgPT4gdm9pZDtcblxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgdHlwZTogUnVsZVR5cGUsIGJlZm9yZTogc3RyaW5nLCBhZnRlcjogc3RyaW5nLCBvblN1Ym1pdDogKG5ld19iZWZvcmU6IHN0cmluZywgbmV3X2FmdGVyOnN0cmluZykgPT4gdm9pZCkge1xuXHRcdHN1cGVyKGFwcCk7XG5cdFx0dGhpcy50eXBlID0gdHlwZTtcblx0XHR0aGlzLm9sZF9iZWZvcmUgPSBiZWZvcmU7XG5cdFx0dGhpcy5vbGRfYWZ0ZXIgPSBhZnRlcjtcblx0XHR0aGlzLm5ld19iZWZvcmUgPSBiZWZvcmU7XG5cdFx0dGhpcy5uZXdfYWZ0ZXIgPSBhZnRlcjtcblxuXHRcdHRoaXMub25TdWJtaXQgPSBvblN1Ym1pdDtcblx0fVxuXG5cdG9uT3BlbigpIHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcImgxXCIsIHsgdGV4dDogXCJFZGl0IFwiICsgdGhpcy50eXBlfSk7XG5cdFx0XG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxuXHRcdFx0LnNldE5hbWUoXCJPbGQgUGF0dGVyblwiKVxuXHRcdFx0LmFkZFRleHRBcmVhKCh0ZXh0KSA9PiB7XG5cdFx0XHRcdHRleHQuc2V0VmFsdWUodGhpcy5vbGRfYmVmb3JlKTtcblx0XHRcdFx0dGV4dC5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLm5ld19iZWZvcmUgPSB2YWx1ZVxuXHRcdFx0XHR9KVxuXHRcdFx0fSlcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXG5cdFx0XHQuc2V0TmFtZShcIk5ldyBQYXR0ZXJuXCIpXG5cdFx0XHQuYWRkVGV4dEFyZWEoKHRleHQpID0+IHtcblx0XHRcdFx0dGV4dC5zZXRWYWx1ZSh0aGlzLm9sZF9hZnRlcik7XG5cdFx0XHRcdHRleHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5uZXdfYWZ0ZXIgPSB2YWx1ZVxuXHRcdFx0XHR9KVxuXHRcdFx0fSk7XG5cblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcblx0XHRcdC5hZGRCdXR0b24oKGJ0bikgPT5cblx0XHRcdFx0YnRuXG5cdFx0XHRcdFx0LnNldEJ1dHRvblRleHQoXCJVcGRhdGVcIilcblx0XHRcdFx0XHQuc2V0Q3RhKClcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0XHRpZiAodGhpcy5jaGVja0NvbnZlcnRQYXR0ZXJuU3RyaW5nKHRoaXMubmV3X2JlZm9yZSwgdGhpcy5uZXdfYWZ0ZXIpKVxuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRcdHRoaXMub25TdWJtaXQodGhpcy5uZXdfYmVmb3JlLCB0aGlzLm5ld19hZnRlcik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRlbHNle1xuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwiSW52YWxpZCBwYXR0ZXJuIHN0cmluZyFcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcblx0XHRcdFx0XHR9KSk7XG5cdH1cblxuXHRjaGVja0NvbnZlcnRQYXR0ZXJuU3RyaW5nKGJlZm9yZTogc3RyaW5nLCBhZnRlcjpzdHJpbmcpOmJvb2xlYW57XG5cdFx0bGV0IHJlZ1J1bGUgPSAvXFx8L2c7XG5cdFx0aWYoYmVmb3JlLnNlYXJjaChyZWdSdWxlKT09LTEgfHwgYWZ0ZXIuc2VhcmNoKHJlZ1J1bGUpPT0tMSkgcmV0dXJuIGZhbHNlO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0b25DbG9zZSgpIHtcblx0XHRsZXQgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XG5cdH1cbn1cblxuIiwgImltcG9ydCB7IGVuc3VyZVN5bnRheFRyZWUsIHN5bnRheFRyZWUgfSBmcm9tIFwiQGNvZGVtaXJyb3IvbGFuZ3VhZ2VcIjtcbmltcG9ydCB7IEVkaXRvclZpZXcgfSBmcm9tICdAY29kZW1pcnJvci92aWV3JztcbmltcG9ydCB7IEVkaXRvclN0YXRlIH0gZnJvbSAnQGNvZGVtaXJyb3Ivc3RhdGUnO1xuZXhwb3J0IGludGVyZmFjZSBDb2RlQmxvY2tJbmZvIHtcbiAgICBzdGFydF9wb3M6IG51bWJlcjtcbiAgICBlbmRfcG9zOiBudW1iZXI7XG4gICAgY29kZV9zdGFydF9wb3M6IG51bWJlcjtcbiAgICBjb2RlX2VuZF9wb3M6IG51bWJlcjtcbiAgICBsYW5ndWFnZTogc3RyaW5nO1xuICAgIGluZGVudDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNDb2RlQmxvY2tJblBvcyhzdGF0ZTogRWRpdG9yU3RhdGUsIHBvczogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgbGV0IGNvZGVCbG9ja0luZm9zID0gZ2V0Q29kZUJsb2Nrc0luZm9zKHN0YXRlKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvZGVCbG9ja0luZm9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwb3MgPj0gY29kZUJsb2NrSW5mb3NbaV0uc3RhcnRfcG9zICYmIHBvcyA8PSBjb2RlQmxvY2tJbmZvc1tpXS5lbmRfcG9zKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2RlQmxvY2tJbmZvSW5Qb3Moc3RhdGU6IEVkaXRvclN0YXRlLCBwb3M6IG51bWJlcik6IENvZGVCbG9ja0luZm8gfCBudWxsIHtcbiAgICBsZXQgY29kZUJsb2NrSW5mb3MgPSBnZXRDb2RlQmxvY2tzSW5mb3Moc3RhdGUpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29kZUJsb2NrSW5mb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBvcyA+PSBjb2RlQmxvY2tJbmZvc1tpXS5zdGFydF9wb3MgJiYgcG9zIDw9IGNvZGVCbG9ja0luZm9zW2ldLmVuZF9wb3MpIHtcbiAgICAgICAgICAgIHJldHVybiBjb2RlQmxvY2tJbmZvc1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdENvZGVCbG9ja0luUG9zKHZpZXc6IEVkaXRvclZpZXcsIHBvczogbnVtYmVyKTpib29sZWFuIHtcbiAgICBsZXQgY29kZUJsb2NrSW5mb3MgPSBnZXRDb2RlQmxvY2tzSW5mb3Modmlldy5zdGF0ZSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2RlQmxvY2tJbmZvcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocG9zID49IGNvZGVCbG9ja0luZm9zW2ldLnN0YXJ0X3BvcyAmJiBwb3MgPD0gY29kZUJsb2NrSW5mb3NbaV0uZW5kX3Bvcykge1xuICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIGFuY2hvcjogY29kZUJsb2NrSW5mb3NbaV0uY29kZV9zdGFydF9wb3MsXG4gICAgICAgICAgICAgICAgICAgIGhlYWQ6IGNvZGVCbG9ja0luZm9zW2ldLmNvZGVfZW5kX3Bvc1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29kZUJsb2Nrc0luZm9zKHN0YXRlOiBFZGl0b3JTdGF0ZSk6IENvZGVCbG9ja0luZm9bXXtcbiAgICBsZXQgaXNDb2RlQmxvY2tCZWdpbiA9IGZhbHNlO1xuICAgIGxldCBjb2RlQmxvY2tJbmZvczogQ29kZUJsb2NrSW5mb1tdID0gW107XG4gICAgbGV0IGN1ckNvZGVCbG9ja0luZm86IENvZGVCbG9ja0luZm8gfCBudWxsID0gbnVsbDtcbiAgICBjb25zdCBkb2MgPSBzdGF0ZS5kb2M7XG5cbiAgICBzeW50YXhUcmVlKHN0YXRlKS5pdGVyYXRlKHtcbiAgICAgICAgZW50ZXIobm9kZSkge1xuICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWUgPSBub2RlLm5hbWU7XG4gICAgICAgICAgICBjb25zdCBub2RlRnJvbSA9IG5vZGUuZnJvbTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVUbyA9IG5vZGUudG87XG4gICAgICAgICAgICBjb25zdCBub2RlVGV4dCA9IHN0YXRlLnNsaWNlRG9jKG5vZGVGcm9tLCBub2RlVG8pO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2cobm9kZU5hbWUsIG5vZGVGcm9tLCBub2RlVG8sIG5vZGVUZXh0KTtcbiAgICAgICAgICAgIGlmIChub2RlTmFtZS5pbmNsdWRlcygnY29kZWJsb2NrLWJlZ2luJykpIHtcbiAgICAgICAgICAgICAgICBpc0NvZGVCbG9ja0JlZ2luID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnRfcG9zID0gbm9kZUZyb20gKyBub2RlVGV4dC5pbmRleE9mKCdgJyk7XG4gICAgICAgICAgICAgICAgbGV0IGluZGVudCA9IHN0YXJ0X3BvcyAtIHN0YXRlLmRvYy5saW5lQXQoc3RhcnRfcG9zKS5mcm9tO1xuICAgICAgICAgICAgICAgIGxldCBsYW5ndWFnZSA9IG5vZGVUZXh0LnRyaW0oKS5zdWJzdHJpbmcoMyk7XG4gICAgICAgICAgICAgICAgY3VyQ29kZUJsb2NrSW5mbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRfcG9zOiBzdGFydF9wb3MsXG4gICAgICAgICAgICAgICAgICAgIGVuZF9wb3M6IC0xLFxuICAgICAgICAgICAgICAgICAgICBjb2RlX3N0YXJ0X3BvczogLTEsXG4gICAgICAgICAgICAgICAgICAgIGNvZGVfZW5kX3BvczogLTEsXG4gICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlOiBsYW5ndWFnZSxcbiAgICAgICAgICAgICAgICAgICAgaW5kZW50OiBpbmRlbnRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGVOYW1lLmluY2x1ZGVzKCdjb2RlYmxvY2stZW5kJykpIHtcbiAgICAgICAgICAgICAgICBpc0NvZGVCbG9ja0JlZ2luID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaWYgKGN1ckNvZGVCbG9ja0luZm8gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBjdXJDb2RlQmxvY2tJbmZvLmVuZF9wb3MgPSBub2RlVG87XG4gICAgICAgICAgICAgICAgICAgIGlmIChkb2MubGluZUF0KGN1ckNvZGVCbG9ja0luZm8uc3RhcnRfcG9zKS5udW1iZXIgPT1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRvYy5saW5lQXQoY3VyQ29kZUJsb2NrSW5mby5lbmRfcG9zKS5udW1iZXIgLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJDb2RlQmxvY2tJbmZvLmNvZGVfc3RhcnRfcG9zID0gZG9jLmxpbmVBdChjdXJDb2RlQmxvY2tJbmZvLnN0YXJ0X3BvcykudG87XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJDb2RlQmxvY2tJbmZvLmNvZGVfZW5kX3BvcyA9IGRvYy5saW5lQXQoY3VyQ29kZUJsb2NrSW5mby5zdGFydF9wb3MpLnRvO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvZGVfc3RhcnRfbGluZSA9IGRvYy5saW5lQXQoY3VyQ29kZUJsb2NrSW5mby5zdGFydF9wb3MpLm51bWJlciArIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29kZV9lbmRfbGluZSA9IGRvYy5saW5lQXQoY3VyQ29kZUJsb2NrSW5mby5lbmRfcG9zKS5udW1iZXIgLSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VyQ29kZUJsb2NrSW5mby5jb2RlX3N0YXJ0X3BvcyA9IGRvYy5saW5lKGNvZGVfc3RhcnRfbGluZSkuZnJvbSArIGN1ckNvZGVCbG9ja0luZm8uaW5kZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VyQ29kZUJsb2NrSW5mby5jb2RlX2VuZF9wb3MgPSBkb2MubGluZShjb2RlX2VuZF9saW5lKS50bztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb2RlQmxvY2tJbmZvcy5wdXNoKGN1ckNvZGVCbG9ja0luZm8pO1xuICAgICAgICAgICAgICAgICAgICBjdXJDb2RlQmxvY2tJbmZvID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChpc0NvZGVCbG9ja0JlZ2luICYmIGN1ckNvZGVCbG9ja0luZm8pIHtcbiAgICAgICAgY3VyQ29kZUJsb2NrSW5mby5lbmRfcG9zID0gZG9jLmxlbmd0aDtcbiAgICAgICAgY3VyQ29kZUJsb2NrSW5mby5jb2RlX2VuZF9wb3MgPSBkb2MubGVuZ3RoO1xuICAgICAgICBpZiAoZG9jLmxpbmVzID4gZG9jLmxpbmVBdChjdXJDb2RlQmxvY2tJbmZvLnN0YXJ0X3BvcykubnVtYmVyKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnRfbGluZSA9IGRvYy5saW5lQXQoY3VyQ29kZUJsb2NrSW5mby5zdGFydF9wb3MpLm51bWJlciArIDE7XG4gICAgICAgICAgICBsZXQgY29kZV9zdGFydF9wb3MgPSBkb2MubGluZShzdGFydF9saW5lKS5mcm9tICsgY3VyQ29kZUJsb2NrSW5mby5pbmRlbnQ7XG4gICAgICAgICAgICBjdXJDb2RlQmxvY2tJbmZvLmNvZGVfc3RhcnRfcG9zID0gY29kZV9zdGFydF9wb3MgPCBkb2MubGVuZ3RoID8gY29kZV9zdGFydF9wb3MgOlxuICAgICAgICAgICAgICAgIGRvYy5saW5lQXQoY3VyQ29kZUJsb2NrSW5mby5zdGFydF9wb3MgKyAxKS5mcm9tIDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGN1ckNvZGVCbG9ja0luZm8uY29kZV9zdGFydF9wb3MgPSBkb2MubGluZUF0KGN1ckNvZGVCbG9ja0luZm8uc3RhcnRfcG9zKS50bztcbiAgICAgICAgfVxuICAgICAgICBjb2RlQmxvY2tJbmZvcy5wdXNoKGN1ckNvZGVCbG9ja0luZm8pO1xuICAgICAgICBjdXJDb2RlQmxvY2tJbmZvID0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNvZGVCbG9ja0luZm9zO1xufVxuXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsdUJBQWtGO0FBQ2xGLG1CQUErRTs7O0FDRC9FLHNCQUFzQjs7O0FDSXRCLElBQUksUUFBUTtBQUVMLElBQU0sUUFBTSxDQUFDLFlBQWtCLG1CQUF5QjtBQUMzRCxNQUFJLE9BQU87QUFDUCxZQUFRLElBQUksU0FBUyxHQUFHLGNBQWM7QUFBQSxFQUMxQztBQUNKO0FBS08scUJBQXFCLEtBQVUsUUFBZTtBQUNwRCxNQUFJLE9BQU8sSUFBSSxPQUFPLE1BQU07QUFDNUIsU0FBTyxFQUFDLE1BQU0sS0FBSyxTQUFTLEdBQUcsSUFBSSxTQUFTLEtBQUssS0FBSTtBQUN0RDtBQUVPLDZCQUE2QixJQUF5QjtBQUM1RCxNQUFJLG1CQUE0QjtBQUFBLElBQUM7QUFBQSxJQUFxQjtBQUFBLElBQ2hEO0FBQUEsSUFBc0I7QUFBQSxJQUFjO0FBQUEsSUFBZTtBQUFBLElBQWM7QUFBQSxJQUFrQjtBQUFBLElBQ25GO0FBQUEsSUFBb0I7QUFBQSxJQUFrQjtBQUFBLElBQW1CO0FBQUEsSUFBYztBQUFBLElBQ3ZFO0FBQUEsSUFDQTtBQUFBLElBQVE7QUFBQSxJQUNSO0FBQUEsRUFBZ0I7QUFDdEIsV0FBUyxJQUFZLEdBQUcsSUFBSSxpQkFBaUIsUUFBUSxLQUNyRDtBQUNDLFFBQUksR0FBRyxZQUFZLGlCQUFpQixFQUFFO0FBQ3JDLGFBQU8saUJBQWlCO0FBQUEsRUFDMUI7QUFDQSxTQUFPO0FBQ1I7QUFFTywyQkFBMkIsR0FBcUI7QUFDdEQsTUFBSSxZQUFZLEVBQUUsUUFBUSxHQUFHO0FBQzdCLE1BQUksT0FBTyxFQUFFLFVBQVUsR0FBRyxTQUFTO0FBQ25DLE1BQUksUUFBUSxFQUFFLFVBQVUsWUFBVSxDQUFDO0FBQ25DLFNBQU8sRUFBQyxNQUFXLE1BQVc7QUFDL0I7QUFFTyxpQ0FBaUMsTUFBNkM7QUFDcEYsTUFBSSxNQUFvQixDQUFDO0FBQ3pCLFdBQVMsS0FBSyxNQUFLO0FBQ2xCLFFBQUksS0FBSyxFQUFDLFFBQVEsa0JBQWtCLEtBQUssR0FBRyxFQUFFLEdBQUcsT0FBTyxrQkFBa0IsS0FBSyxHQUFHLEVBQUUsRUFBQztBQUFBLEVBQ3RGO0FBQ0EsU0FBTztBQUNSO0FBRU8sd0JBQXdCLEtBQWEsT0FDNUM7QUFDSSxTQUFPLElBQUksVUFBVSxHQUFHLEtBQUssSUFBRSxJQUFJLFVBQVUsUUFBTSxDQUFDO0FBQ3hEO0FBRU8sd0JBQXdCLEtBQVksT0FBZSxHQUMxRDtBQUNJLFNBQU8sSUFBSSxVQUFVLEdBQUcsS0FBSyxJQUFFLElBQUUsSUFBSSxVQUFVLEtBQUs7QUFDeEQ7QUFFTyx3QkFBd0IsT0FDL0I7QUFDQyxTQUFPLE9BQU8sVUFBUTtBQUN2QjtBQUVPLG9CQUFvQixHQUFpQjtBQUMzQyxTQUFPLEVBQUUsUUFBUSxPQUFPLEtBQUs7QUFDOUI7OztBRC9EQSxzQkFBNkM7QUEwQ3RDLElBQU0sZUFBTixNQUFtQjtBQUFBLEVBQ3RCLGNBQWM7QUFBQSxFQUFFO0FBQUEsRUFDaEIsdUJBQXVCLE1BQXVCO0FBQzFDLFFBQUcsS0FBSyxTQUFTLE1BQU0sS0FBSyxDQUFDLEtBQUssU0FBUyxNQUFNLEdBQUU7QUFDL0MsYUFBTztBQUFBLElBQ1gsV0FDUSxLQUFLLFNBQVMsTUFBTSxHQUFFO0FBQzFCLGFBQU87QUFBQSxJQUNYLE9BQ0k7QUFDQSxhQUFPO0FBQUEsSUFDWDtBQUFBLEVBQ0o7QUFBQSxFQUdBLHdCQUF3QixPQUFvQixTQUFnQixXQUFtQjtBQUMzRSxRQUFJLDRCQUEwQyxDQUFDO0FBQy9DLFFBQUksT0FBTyxNQUFNLElBQUksS0FBSyxPQUFPO0FBQ2pDLFVBQU0sT0FBTyxnQ0FBVyxLQUFLO0FBQzdCLFFBQUksTUFBTSxLQUFLO0FBQ2YsUUFBSSxlQUEwQjtBQUM5QixRQUFJLGVBQWU7QUFDbkIsV0FBTSxNQUFJLEtBQUssSUFBRztBQUNkLFVBQUksT0FBTyxLQUFLLFFBQVEsS0FBSyxDQUFDO0FBQzlCLFVBQUksY0FBYyxLQUFLLHVCQUF1QixLQUFLLElBQUk7QUFFdkQsVUFBRyxnQkFBYyxtQkFBZ0I7QUFDN0IsdUJBQWE7QUFDYix1QkFBYTtBQUFBLE1BQ2pCLFdBQ1EsZ0JBQWMsYUFBWTtBQUFBLE1BQUMsT0FDL0I7QUFDQSxrQ0FBMEIsS0FBSztBQUFBLFVBQzNCLFNBQVEsS0FBSyxLQUFLLFVBQVUsY0FBYyxNQUFJLEtBQUssSUFBSTtBQUFBLFVBQ3ZELE1BQUs7QUFBQSxVQUNMLE9BQU07QUFBQSxVQUNOLEtBQUksTUFBSSxLQUFLO0FBQUEsVUFDYixrQkFBaUI7QUFBQSxVQUNqQixtQkFBa0I7QUFBQSxRQUN0QixDQUFDO0FBQ0QsdUJBQWU7QUFDZix1QkFBZSxNQUFJLEtBQUs7QUFBQSxNQUM1QjtBQUVBLFVBQUksZUFBZSxtQkFBZ0I7QUFDL0I7QUFBQSxNQUNKLE9BQ0k7QUFDQSxjQUFNLEtBQUs7QUFBQSxNQUNmO0FBRUEsVUFBRyxPQUFLLEtBQUssSUFBRztBQUNaLGtDQUEwQixLQUFLO0FBQUEsVUFDM0IsU0FBUSxLQUFLLEtBQUssVUFBVSxjQUFjLE1BQUksS0FBSyxJQUFJO0FBQUEsVUFDdkQsTUFBSztBQUFBLFVBQ0wsT0FBTTtBQUFBLFVBQ04sS0FBSSxNQUFJLEtBQUs7QUFBQSxVQUNiLGtCQUFpQjtBQUFBLFVBQ2pCLG1CQUFrQjtBQUFBLFFBQ3RCLENBQUM7QUFBQSxNQUNMO0FBQUEsSUFDSjtBQUdBLFFBQUksV0FBeUIsQ0FBQztBQUM5QixhQUFTLElBQUksR0FBRyxJQUFJLDBCQUEwQixRQUFRLEtBQUs7QUFDdkQsVUFBSSwwQkFBMEIsR0FBRyxRQUFRLG1CQUFpQjtBQUN0RCxpQkFBUyxLQUFLLDBCQUEwQixFQUFFO0FBQUEsTUFDOUMsT0FDSztBQUNELFlBQUk7QUFDSixZQUFJLGVBQWUsU0FBUztBQUN4QixzQkFBWSxnQ0FBZ0MsMEJBQTBCLEdBQUcsU0FBUyxTQUFTO0FBQUE7QUFFM0Ysc0JBQVksZ0NBQWdDLDBCQUEwQixHQUFHLE9BQU87QUFFcEYsa0JBQVUsUUFBUSxVQUFRO0FBQ3RCLGVBQUssU0FBUywwQkFBMEIsR0FBRztBQUMzQyxlQUFLLE9BQU8sMEJBQTBCLEdBQUc7QUFDekMsbUJBQVMsS0FBSyxJQUFJO0FBQUEsUUFDdEIsQ0FBQztBQUFBLE1BQ0w7QUFBQSxJQUNKO0FBRUEsV0FBTztBQUFBLEVBQ1g7QUFBQSxFQUVBLGdCQUFnQixPQUFvQixVQUE4QixPQUFlLEtBQWEsYUFBa0U7QUFDNUosUUFBSSxNQUFNLE1BQU07QUFDaEIsUUFBSSxPQUFPLElBQUksT0FBTyxLQUFLLEVBQUU7QUFDN0IsUUFBSSxNQUFNO0FBQ1YsUUFBSSxZQUFZLFNBQVMsSUFBSSxHQUM3QjtBQUVJLFlBQU0sS0FBSyxXQUFXLE9BQU8sSUFBSSxPQUFPLEtBQUssRUFBRSxRQUFRLFVBQVUsWUFBWSxLQUFLLEtBQUssRUFBRSxJQUFJLFlBQVksS0FBSyxLQUFLLEVBQUUsRUFBRTtBQUFBLElBQzNILE9BRUE7QUFDSSxZQUFNLEtBQUssV0FBVyxPQUFPLElBQUksT0FBTyxLQUFLLEVBQUUsUUFBUSxVQUFVLFlBQVksS0FBSyxHQUFHLEVBQUUsSUFBSSxZQUFZLEtBQUssS0FBSyxFQUFFLEVBQUU7QUFBQSxJQUN6SDtBQUNBLFFBQUksUUFBTyxRQUFRLElBQUksR0FBRyxVQUFRO0FBQUcsYUFBTztBQUU1QyxRQUFJLFVBQVUsZUFBZSxJQUFJLElBQUksSUFBSSxJQUFJLEdBQUc7QUFHaEQsUUFBSSxVQUE2QixDQUFDO0FBQ2xDLFFBQUksU0FBUyxJQUFJLE9BQU8sS0FBSyxFQUFFO0FBRS9CLGFBQVEsY0FBYyxJQUFJLElBQzFCO0FBQ0ksY0FBUSxLQUFLO0FBQUEsUUFDVCxTQUFRLEVBQUMsTUFBTSxTQUFPLFdBQVcsT0FBTyxJQUFHLFNBQU8sV0FBVyxLQUFLLFFBQU8sV0FBVyxLQUFJO0FBQUEsUUFBRyxXQUFVO0FBQUEsTUFDekcsQ0FBQztBQUFBLElBQ0w7QUFDQSxRQUFJLFlBQVksU0FBUyxJQUFJLEdBQUU7QUFDM0IsY0FBUSxJQUFJLGFBQWEsV0FBVztBQUNwQyxVQUFJLE1BQUssWUFBWTtBQUFBLElBQ3pCO0FBQ0EsV0FBTyxDQUFDLFNBQVMsRUFBQyxXQUFVLEVBQUMsUUFBTyxTQUFPLElBQUksR0FBRSxHQUFHLFdBQVUsb0JBQW1CLENBQUM7QUFBQSxFQUN0RjtBQUFBLEVBTUEsV0FBVyxPQUFvQixTQUFnQixVQUE4QixPQUFlLFFBQTBEO0FBRWxKLFFBQUksT0FBTyxNQUFNLElBQUksS0FBSyxPQUFPLEVBQUU7QUFDbkMsUUFBSSxVQUFVO0FBQ2QsUUFBSSxRQUFRLEtBQUssSUFBSTtBQUFHLGFBQU8sQ0FBQyxNQUFNLE9BQU8sQ0FBQyxDQUFDO0FBRy9DLFFBQUksWUFBWSxTQUFTLHVCQUN2QixLQUFLLHdCQUF3QixPQUFPLFNBQVMsU0FBUyxpQkFBaUIsSUFDdkUsS0FBSyx3QkFBd0IsT0FBTyxPQUFPO0FBRTdDLFFBQUksU0FBUztBQUFPLGNBQVEsSUFBSSxnQkFBZ0IsU0FBUztBQUd6RCxRQUFJLGtCQUFrQixLQUFLLE1BQU0sS0FBSyxVQUFVLFNBQVMsQ0FBQztBQUMxRCxRQUFJLG1CQUFtQyxDQUFDO0FBRXhDLFFBQUksc0JBQXNCO0FBQzFCLFFBQUksc0JBQXNCO0FBQzFCLFFBQUksaUJBQWlCO0FBR3JCLGFBQVMsSUFBSSxHQUFHLElBQUksVUFBVSxRQUFRLEtBQUs7QUFDdkMsVUFBSSxRQUFRLFVBQVUsR0FBRyxTQUFTLFNBQVMsVUFBVSxHQUFHLEtBQUs7QUFDekQsOEJBQXNCO0FBQ3RCLDhCQUFzQixRQUFRLFVBQVUsR0FBRztBQUMzQyxZQUFJLFVBQVUsR0FBRyxTQUFTLG1CQUFpQjtBQUN2QyxvQkFBVSxHQUFHLFVBQVUsZUFBZSxVQUFVLEdBQUcsU0FBUyxxQkFBcUIsSUFBSTtBQUFBLFFBQ3pGO0FBQ0E7QUFBQSxNQUNKO0FBQUEsSUFDSjtBQUNBLFFBQUksYUFBYTtBQUNqQixRQUFJLFNBQVM7QUFFYixRQUFJLGVBQXVCO0FBQzNCLFFBQUksd0JBQXdCO0FBRzVCLGFBQVMsSUFBSSxHQUFHLElBQUksVUFBVSxRQUFRLEtBQUs7QUFFdkMsVUFBSSxNQUFNLEtBQUssVUFBVSxHQUFHLFNBQVMscUJBQW1CLFNBQVMsYUFBYTtBQUUxRSxZQUFJLGVBQWUsTUFBTSxLQUFLLHVCQUF1QixHQUFHO0FBQUEsUUFBRSxPQUNyRDtBQUNELGNBQUksbUJBQW1CO0FBQ3ZCLGNBQUksb0JBQW9CO0FBQ3hCLGNBQUksV0FBVyxVQUFVLEdBQUc7QUFDNUIsY0FBSSxRQUFRLGlCQUFpQixLQUFLLFFBQVE7QUFDMUMsY0FBSSxjQUFjLGtCQUFrQixLQUFLLFFBQVE7QUFDakQsY0FBSSxlQUFlO0FBQ25CLGNBQUksT0FBTztBQUNQLDJCQUFlLGlCQUFpQixZQUFZO0FBQUEsVUFDaEQsV0FDUyxhQUFhO0FBQ2xCLDJCQUFlLGtCQUFrQixZQUFZO0FBQUEsVUFDakQ7QUFFQSxjQUFJLFNBQVMsbUJBQW1CLDJCQUFzQixlQUFlLE1BQU0sS0FBSyxnQkFBZ0IsVUFBVSxlQUFlLE9BQVE7QUFBQSxVQUFFLE9BQzlIO0FBQ0QsMkJBQWU7QUFBQSxVQUNuQjtBQUVBLGNBQUksZ0JBQWdCLElBQUk7QUFFcEIsc0JBQVUsR0FBRyxVQUFVLFNBQVMsVUFBVSxHQUFHLFlBQVksSUFBSSxTQUFTLE9BQU8sWUFBWSxFQUFFLFlBQVksSUFBSSxTQUFTLFVBQVUsZUFBZSxDQUFDO0FBQUEsVUFDbEo7QUFBQSxRQUNKO0FBQUEsTUFDSjtBQUVBLGNBQVEsVUFBVSxHQUFHO0FBQUEsYUFFWjtBQXVCRCxjQUFTLGNBQVQsU0FBcUIsVUFBaUIsTUFBYSxTQUFnQixRQUFlLFNBQWtDO0FBQ2hILG1CQUFPLE1BQU07QUFDVCxrQkFBSSxRQUFRLEtBQUksS0FBSyxRQUFPO0FBQzVCLGtCQUFJLENBQUM7QUFBTztBQUNaLGtCQUFJLFlBQVksS0FBSSxZQUFZO0FBQ2hDLGtCQUFJLGVBQWUsT0FBTSxLQUFLLGFBQWEsVUFBUyxXQUFVLFlBQVksU0FBUSxTQUFRO0FBQ3RGLDJCQUFVLFNBQVEsVUFBVSxHQUFHLFNBQVMsSUFBSSxNQUFNLFNBQVEsVUFBVSxTQUFTO0FBQzdFLDBCQUFTO0FBQUEsY0FDYjtBQUFBLFlBQ0o7QUFDQSxtQkFBTyxDQUFDLFVBQVMsTUFBSztBQUFBLFVBQzFCO0FBakNBLGNBQUksVUFBVSxVQUFVLEdBQUc7QUFFM0IsY0FBSSxTQUFTLGFBQWE7QUFDdEIsZ0JBQUksTUFBTTtBQUNWLG1CQUFPLE1BQU07QUFDVCxrQkFBSSxRQUFRLElBQUksS0FBSyxPQUFPO0FBQzVCLGtCQUFJLENBQUM7QUFBTztBQUNaLGtCQUFJLFlBQVksSUFBSSxZQUFZO0FBR2hDLGtCQUFJLGFBQWEsWUFBVSxJQUFFLEtBQUssUUFBUSxVQUFVLFlBQVUsR0FBRyxTQUFTLEtBQUc7QUFDN0Usa0JBQUksU0FBUyxtQkFBbUIsMkJBQXFCLENBQUMsWUFBWTtBQUM5RCwwQkFBVSxHQUFHLFVBQVUsUUFBUSxVQUFVLEdBQUcsU0FBUyxJQUFJLFFBQVEsT0FBTyxTQUFTLEVBQUUsWUFBWSxJQUFJLFFBQVEsVUFBVSxJQUFJLFNBQVM7QUFDbEksMEJBQVUsVUFBVSxHQUFHO0FBQUEsY0FDM0IsV0FDUyxlQUFlLE1BQU0sS0FBSyxhQUFhLFNBQVMsVUFBVSxZQUFZLFFBQVEsVUFBVSxDQUFDLFlBQVk7QUFDMUcsMEJBQVUsR0FBRyxVQUFVLFFBQVEsVUFBVSxHQUFHLFNBQVMsSUFBSSxRQUFRLE9BQU8sU0FBUyxFQUFFLFlBQVksSUFBSSxRQUFRLFVBQVUsSUFBSSxTQUFTO0FBQ2xJLDBCQUFVLFVBQVUsR0FBRztBQUFBLGNBQzNCO0FBQUEsWUFDSjtBQUFBLFVBQ0o7QUFnQkEsY0FBSSxTQUFTLHFCQUFxQjtBQUM5QixnQkFBSSxPQUFPO0FBQ1gsZ0JBQUksT0FBTztBQUNYLGFBQUMsU0FBUyxLQUFLLElBQUksWUFBWSxTQUFTLE1BQU0sUUFBUSxPQUFPLE1BQU07QUFDbkUsYUFBQyxTQUFTLEtBQUssSUFBSSxZQUFZLFNBQVMsTUFBTSxRQUFRLE9BQU8sTUFBTTtBQUFBLFVBQ3ZFO0FBRUEsY0FBSSxTQUFTLG9CQUFtQjtBQUM1QixnQkFBSSxPQUFNO0FBQ1YsZ0JBQUksT0FBTztBQUNYLGFBQUMsU0FBUyxLQUFLLElBQUksWUFBWSxTQUFTLE1BQUssUUFBUSxPQUFPLE1BQU07QUFDbEUsYUFBQyxTQUFTLEtBQUssSUFBSSxZQUFZLFNBQVMsTUFBTSxRQUFRLE9BQU8sTUFBTTtBQUFBLFVBQ3ZFO0FBRUEsY0FBSSxTQUFTLG9CQUFtQjtBQUM1QixnQkFBSSxPQUFNO0FBQ1YsZ0JBQUksT0FBTztBQUNYLGFBQUMsU0FBUyxLQUFLLElBQUksWUFBWSxTQUFTLE1BQUssUUFBUSxPQUFPLE1BQU07QUFDbEUsYUFBQyxTQUFTLEtBQUssSUFBSSxZQUFZLFNBQVMsTUFBTSxRQUFRLE9BQU8sTUFBTTtBQUFBLFVBQ3ZFO0FBR0EsY0FBSSxTQUFTLGdCQUFnQjtBQUN6QixnQkFBSSxPQUFNO0FBQ1YsbUJBQU8sS0FBSSxLQUFLLE9BQU8sR0FBRztBQUN0Qix3QkFBVSxHQUFHLFVBQVUsUUFBUSxRQUFRLE1BQUssTUFBTTtBQUNsRCx3QkFBVSxVQUFVLEdBQUc7QUFBQSxZQUMzQjtBQUFBLFVBQ0o7QUFHQSxjQUFJLFNBQVMsa0JBQWtCO0FBRzNCO0FBQ0ksa0JBQUksT0FBTTtBQUNWLHFCQUFPLE1BQU07QUFDVCxvQkFBSSxRQUFRLEtBQUksS0FBSyxPQUFPO0FBQzVCLG9CQUFJLENBQUM7QUFBTztBQUNaLG9CQUFJLFlBQVksS0FBSSxZQUFZO0FBQ2hDLG9CQUFJLGFBQWEsUUFBUSxTQUFTLFFBQVEsT0FBTyxZQUFVLENBQUMsQ0FBQyxLQUFPLGFBQVUsSUFBRSxLQUFLLEtBQUcsS0FBTSxRQUFRLE9BQU8sWUFBVSxDQUFDLEtBQUc7QUFDM0gsb0JBQUksZUFBZSxTQUFTLEtBQUssUUFBUSxVQUFVLFlBQVUsR0FBRyxZQUFVLENBQUMsQ0FBQyxLQUN2RCxhQUFVLElBQUUsS0FBSyxLQUFLLEtBQUssUUFBUSxPQUFPLFlBQVUsQ0FBQyxDQUFDO0FBRTNFLG9CQUFJLFNBQVMsd0JBQXdCLDJCQUFxQixDQUFDLGNBQWMsQ0FBQyxjQUFjO0FBQ3BGLDRCQUFVLFFBQVEsVUFBVSxHQUFHLFNBQVMsSUFBSSxNQUFNLFFBQVEsVUFBVSxTQUFTO0FBQUEsZ0JBQ2pGLFdBQ1MsZUFBZSxNQUFNLEtBQUssYUFBYSxTQUFTLFVBQ3RCLFlBQVksUUFBUSxVQUNwQixDQUFDLGNBQWMsQ0FBQyxjQUFjO0FBQzdELDRCQUFVLFFBQVEsVUFBVSxHQUFHLFNBQVMsSUFBSSxNQUFNLFFBQVEsVUFBVSxTQUFTO0FBQzdFLDJCQUFTO0FBQUEsZ0JBQ2I7QUFBQSxjQUNKO0FBR0Esa0JBQUksUUFBTztBQUNYLHdCQUFVLEdBQUcsVUFBVSxRQUFRLFFBQVEsT0FBTSxPQUFPO0FBQ3BELHdCQUFVLFVBQVUsR0FBRztBQUV2QixrQkFBSSxPQUFPO0FBQ1gsd0JBQVUsR0FBRyxVQUFVLFFBQVEsUUFBUSxNQUFNLE9BQU87QUFDcEQsd0JBQVUsVUFBVSxHQUFHO0FBQUEsWUFDM0I7QUFBQSxVQUNKO0FBR0EsY0FBSSxzQkFBc0I7QUFDMUIsY0FBSSxvQkFBb0I7QUFDeEIsY0FBSSxvQkFBb0I7QUFDeEIsY0FBSSxrQkFBa0I7QUFDdEIsY0FBSSxvQkFBb0I7QUFDeEIsY0FBSSxtQkFBbUI7QUFDdkIsY0FBSSxrQkFBa0IsS0FBSyxPQUFPLEtBQUcsUUFBUSxXQUFXLE1BQU0sR0FBRztBQUM3RCxnQkFBSSxvQkFBb0IsS0FBSyxPQUFPO0FBQ2hDLGtDQUFvQjtBQUFBO0FBRXBCLGtDQUFvQjtBQUFBLFVBQzVCO0FBRUEsY0FBSSxnQkFBZ0IsS0FBSyxPQUFPLEtBQUssUUFBUSxTQUFTLE1BQU0sR0FBRztBQUMzRCxnQkFBSSxrQkFBa0IsS0FBSyxPQUFPO0FBQzlCLGlDQUFtQjtBQUFBO0FBRW5CLGlDQUFtQjtBQUFBLFVBQzNCO0FBR0Esa0JBQVE7QUFBQSxpQkFDQztBQUNEO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxTQUFTLHNCQUFzQixtQkFBbUI7QUFDbEQsMEJBQVUsR0FBRyxVQUFVLE1BQU07QUFDN0IsMEJBQVUsVUFBVSxHQUFHO0FBQUEsY0FDM0I7QUFDQTtBQUFBLGlCQUNDO0FBQ0Qsa0JBQUksU0FBUyx5QkFBeUIsbUJBQW1CO0FBQ3JELDBCQUFVLEdBQUcsVUFBVSxNQUFNO0FBQzdCLDBCQUFVLFVBQVUsR0FBRztBQUFBLGNBQzNCO0FBQ0E7QUFBQSxpQkFDQztBQUFBLGlCQUNBO0FBQ0Qsa0JBQUksQ0FBQyxTQUFTLHdCQUF3QixTQUFTLHNCQUFzQixtQkFBbUI7QUFDcEYsMEJBQVUsR0FBRyxVQUFVLE1BQU07QUFDN0IsMEJBQVUsVUFBVSxHQUFHO0FBQUEsY0FDM0IsV0FDUyxTQUFTLHdCQUF3QixxQkFBcUIsY0FBaUI7QUFDNUUsb0JBQUksa0JBQWtCLFFBQVEsT0FBTyxDQUFDO0FBQ3RDLG9CQUFJLGVBQWU7QUFDbkIsb0JBQUkscUJBQXFCLFVBQVUsSUFBSSxHQUFHLFFBQVEsT0FBTyxZQUFZLElBQUk7QUFDekUsb0JBQUksZ0JBQWdCLFVBQVUsSUFBSSxHQUFHLFFBQVEsT0FBTyxrQkFBa0I7QUFDdEUsb0JBQUksa0JBQWtCO0FBQUs7QUFDM0Isb0JBQUksbUJBQW1CLGdCQUFnQjtBQUN2QyxvQkFBSSxrQkFBa0I7QUFDdEIsb0JBQUksQ0FBQyxnQkFBZ0IsS0FBSyxnQkFBZ0IsR0FBRztBQUN6Qyw0QkFBVSxHQUFHLFVBQVUsTUFBTTtBQUM3Qiw0QkFBVSxVQUFVLEdBQUc7QUFBQSxnQkFDM0I7QUFBQSxjQUNKO0FBQ0E7QUFBQSxpQkFDQztBQUNELGtCQUFJLFVBQVUsSUFBSSxHQUFHLG9CQUFvQixtQkFBbUI7QUFDeEQsMEJBQVUsR0FBRyxVQUFVLE1BQU07QUFDN0IsMEJBQVUsVUFBVSxHQUFHO0FBQUEsY0FDM0I7QUFDQTtBQUFBO0FBSVIsY0FBSSxNQUFNLHFCQUFxQjtBQUMzQixnQkFBSSxPQUFNO0FBQ1YsZ0JBQUksSUFBSSxRQUFRLE9BQU8sSUFBRztBQUMxQiw2QkFBaUIsU0FBUztBQUUxQixzQkFBVSxHQUFHLFVBQVUsZUFBZSxTQUFTLENBQUM7QUFBQSxVQUNwRDtBQUVBLHdCQUFjLFVBQVUsR0FBRztBQUMzQixvQkFBVSxVQUFVLEdBQUcsUUFBUTtBQUMvQix5QkFBZTtBQUNmLGtDQUF3QjtBQUN4QjtBQUFBLGFBR0M7QUFFRCxrQkFBTztBQUFBLGlCQUVFO0FBQ0Q7QUFBQSxpQkFDQztBQUNELGtCQUFJLFNBQVMsc0JBQXNCLHVCQUNuQztBQUNJLDBCQUFVLElBQUUsR0FBRyxXQUFXO0FBQzFCLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUNELGtCQUFJLFNBQVMsc0JBQW9CLGNBQ2pDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxTQUFTLHNCQUFvQixnQkFDN0IsU0FBUyx5QkFBdUIsY0FDcEM7QUFDSSxpQ0FBaUIsS0FDYjtBQUFBLGtCQUNJLE1BQUs7QUFBQSxrQkFDTCxPQUFPLFVBQVUsR0FBRztBQUFBLGtCQUNwQixLQUFLLFVBQVUsR0FBRztBQUFBLGtCQUNsQixRQUFPO0FBQUEsZ0JBQ1gsQ0FDSjtBQUNBLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUFBLGlCQUNBO0FBQ0Qsa0JBQUksU0FBUyxzQkFBb0IsZ0JBQzdCLFNBQVMsc0JBQW9CLGNBQ2pDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxTQUFTLHNCQUFvQixnQkFDN0IsVUFBVSxJQUFFLEdBQUcsb0JBQWtCLGNBQ3JDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUE7QUFHUixjQUFHLE1BQU0scUJBQ1Q7QUFDSSw2QkFBaUIsU0FBUztBQUFBLFVBQzlCO0FBRUEsd0JBQWMsVUFBVSxHQUFHO0FBQzNCLG9CQUFVLFVBQVUsR0FBRyxRQUFRO0FBQy9CLHlCQUFlO0FBQ2Ysa0NBQXdCO0FBQ3hCO0FBQUEsYUFHQztBQUNELGNBQUksVUFBVSxHQUFHLFdBQVcsYUFBYTtBQUNyQywyQkFBZTtBQUNmLG9DQUF3QjtBQUN4QjtBQUFBLFVBQ0o7QUFFQSxrQkFBTztBQUFBLGlCQUVFO0FBQ0Q7QUFBQSxpQkFDQztBQUNELGtCQUFJLFNBQVMseUJBQXVCLHVCQUNwQztBQUNJLDBCQUFVLElBQUUsR0FBRyxXQUFXO0FBQzFCLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUNELGtCQUFJLFNBQVMseUJBQXVCLGdCQUNoQyxTQUFTLHNCQUFvQixjQUNqQztBQUNJLGlDQUFpQixLQUNiO0FBQUEsa0JBQ0ksTUFBSztBQUFBLGtCQUNMLE9BQU8sVUFBVSxHQUFHO0FBQUEsa0JBQ3BCLEtBQUssVUFBVSxHQUFHO0FBQUEsa0JBQ2xCLFFBQU87QUFBQSxnQkFDWCxDQUNKO0FBQ0EsOEJBQWM7QUFDZCwwQkFBVTtBQUFBLGNBQ2Q7QUFDQTtBQUFBLGlCQUNDO0FBQ0Qsa0JBQUksU0FBUyxzQkFBb0IsY0FDakM7QUFDSSxpQ0FBaUIsS0FDYjtBQUFBLGtCQUNJLE1BQUs7QUFBQSxrQkFDTCxPQUFPLFVBQVUsR0FBRztBQUFBLGtCQUNwQixLQUFLLFVBQVUsR0FBRztBQUFBLGtCQUNsQixRQUFPO0FBQUEsZ0JBQ1gsQ0FDSjtBQUNBLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUFBLGlCQUNBO0FBQ0Qsa0JBQUksU0FBUyx5QkFBdUIsZ0JBQ2hDLFNBQVMsc0JBQW9CLGNBQ2pDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxTQUFTLHlCQUF1QixnQkFDaEMsVUFBVSxJQUFFLEdBQUcsb0JBQWtCLGNBQ3JDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUE7QUFHUixjQUFHLE1BQU0scUJBQ1Q7QUFDSSw2QkFBaUIsU0FBUztBQUFBLFVBQzlCO0FBRUEsd0JBQWMsVUFBVSxHQUFHO0FBQzNCLG9CQUFVLFVBQVUsR0FBRyxRQUFRO0FBQy9CLHlCQUFlO0FBQ2Ysa0NBQXdCO0FBQ3hCO0FBQUEsYUFFQztBQUFBLGFBQ0E7QUFDRCxrQkFBTztBQUFBLGlCQUVFO0FBQ0Q7QUFBQSxpQkFDQztBQUNELGtCQUFJLHdCQUFzQixTQUFTO0FBQXFCO0FBQ3hELGtCQUFJLFNBQVMsdUJBQXFCLGtCQUFxQix3QkFBc0IsZ0JBQzdFO0FBQ0ksMEJBQVUsSUFBRSxHQUFHLFdBQVc7QUFDMUIsOEJBQWM7QUFDZCwwQkFBVTtBQUFBLGNBQ2QsV0FDUyxTQUFTLHdCQUF3Qix5QkFBdUIsY0FDakU7QUFDSSxvQkFBSSxpQkFBaUI7QUFDckIsb0JBQUksZ0JBQWdCLFVBQVUsSUFBRSxHQUFHLFFBQVEsT0FBTyxVQUFVLElBQUUsR0FBRyxRQUFRLFNBQU8sQ0FBQztBQUNqRixvQkFBSSxrQkFBeUI7QUFDN0Isb0JBQUksVUFBVSxHQUFHLFFBQU0sMkJBQ3ZCO0FBQ0ksc0JBQUksV0FBVztBQUNmLHNCQUFJLG1CQUFtQixVQUFVLEdBQUcsUUFBUSxPQUFPLFFBQVE7QUFFM0Qsc0JBQUksYUFBYTtBQUNqQixzQkFBRyxVQUFVLEdBQUcsUUFBUSxPQUFPLENBQUMsTUFBSTtBQUFLLGlDQUFXO0FBRXBELHNCQUFJLG9CQUFrQixJQUN0QjtBQUNJLGlDQUFhLG1CQUFpQjtBQUFBLGtCQUNsQyxXQUNRLFVBQVUsR0FBRyxRQUFRLE9BQU8sVUFBVSxLQUFHLEtBQUk7QUFDakQsa0NBQWM7QUFBQSxrQkFDbEI7QUFFQSxvQ0FBa0IsVUFBVSxHQUFHLFFBQVEsT0FBTyxVQUFVO0FBRXhELHNCQUFHLG1CQUFpQjtBQUFLO0FBQUEsZ0JBQzdCLE9BRUE7QUFDSSxzQkFBSSxpQkFBaUI7QUFDckIsc0JBQUksdUJBQXVCLFVBQVUsR0FBRyxRQUFRLE9BQU8sY0FBYyxJQUFFO0FBQ3ZFLG9DQUFrQixVQUFVLEdBQUcsUUFBUSxPQUFPLG9CQUFvQjtBQUNsRSxzQkFBRyxvQkFBa0I7QUFBSztBQUFBLGdCQUM5QjtBQUNBLG9CQUFJLG1CQUFtQixnQkFBYztBQUNyQyxvQkFBRyxDQUFDLGVBQWUsS0FBSyxnQkFBZ0IsR0FDeEM7QUFDSSw0QkFBVSxJQUFFLEdBQUcsV0FBVztBQUMxQixnQ0FBYztBQUNkLDRCQUFVO0FBQUEsZ0JBQ2Q7QUFBQSxjQUNKLFdBQ1EsQ0FBQyxTQUFTLHdCQUF3QixTQUFTLHNCQUFvQix1QkFBc0I7QUFDekYsMEJBQVUsSUFBRSxHQUFHLFdBQVc7QUFDMUIsOEJBQWM7QUFDZCwwQkFBVTtBQUFBLGNBQ2Q7QUFDQTtBQUFBLGlCQUNDO0FBQ0Qsa0JBQUksU0FBUyxzQkFBb0IsZ0JBQzdCLFNBQVMsc0JBQW9CLGNBQ2pDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxTQUFTLHNCQUFvQixnQkFDN0IsU0FBUyx5QkFBdUIsY0FDcEM7QUFDSSxpQ0FBaUIsS0FDYjtBQUFBLGtCQUNJLE1BQUs7QUFBQSxrQkFDTCxPQUFPLFVBQVUsR0FBRztBQUFBLGtCQUNwQixLQUFLLFVBQVUsR0FBRztBQUFBLGtCQUNsQixRQUFPO0FBQUEsZ0JBQ1gsQ0FDSjtBQUNBLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUFBLGlCQUNBO0FBQ0Qsa0JBQUksU0FBUyxzQkFBb0IsY0FDakM7QUFDSSxpQ0FBaUIsS0FDYjtBQUFBLGtCQUNJLE1BQUs7QUFBQSxrQkFDTCxPQUFPLFVBQVUsR0FBRztBQUFBLGtCQUNwQixLQUFLLFVBQVUsR0FBRztBQUFBLGtCQUNsQixRQUFPO0FBQUEsZ0JBQ1gsQ0FDSjtBQUNBLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUNELGtCQUFJLFVBQVUsSUFBRSxHQUFHLG9CQUFrQixnQkFDakMsU0FBUyxzQkFBb0IsY0FDakM7QUFDSSxpQ0FBaUIsS0FDYjtBQUFBLGtCQUNJLE1BQUs7QUFBQSxrQkFDTCxPQUFPLFVBQVUsR0FBRztBQUFBLGtCQUNwQixLQUFLLFVBQVUsR0FBRztBQUFBLGtCQUNsQixRQUFPO0FBQUEsZ0JBQ1gsQ0FDSjtBQUNBLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQUE7QUFHUixjQUFHLE1BQU0scUJBQ1Q7QUFDSSw2QkFBaUIsU0FBUztBQUFBLFVBQzlCO0FBRUEsd0JBQWMsVUFBVSxHQUFHO0FBQzNCLG9CQUFVLFVBQVUsR0FBRyxRQUFRO0FBQy9CLHlCQUFlLFVBQVUsR0FBRztBQUM1QixrQ0FBd0I7QUFDeEI7QUFBQSxhQUdDO0FBRUQsa0JBQU87QUFBQSxpQkFFRTtBQUNEO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxVQUFVLEdBQUcsbUJBQWlCLHVCQUNsQztBQUNJLDBCQUFVLElBQUUsR0FBRyxXQUFXO0FBQzFCLDhCQUFjO0FBQ2QsMEJBQVU7QUFBQSxjQUNkO0FBQ0E7QUFBQSxpQkFDQztBQUNELGtCQUFJLFVBQVUsR0FBRyxtQkFBaUIsZ0JBQzlCLFNBQVMsc0JBQW9CLGNBQ2pDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUEsaUJBQ0M7QUFDRCxrQkFBSSxVQUFVLEdBQUcsbUJBQWlCLGdCQUM5QixTQUFTLHlCQUF1QixjQUNwQztBQUNJLGlDQUFpQixLQUNiO0FBQUEsa0JBQ0ksTUFBSztBQUFBLGtCQUNMLE9BQU8sVUFBVSxHQUFHO0FBQUEsa0JBQ3BCLEtBQUssVUFBVSxHQUFHO0FBQUEsa0JBQ2xCLFFBQU87QUFBQSxnQkFDWCxDQUNKO0FBQ0EsOEJBQWM7QUFDZCwwQkFBVTtBQUFBLGNBQ2Q7QUFDQTtBQUFBLGlCQUNDO0FBQUEsaUJBQ0E7QUFDRCxrQkFBSSxVQUFVLEdBQUcsbUJBQWlCLGdCQUM5QixTQUFTLHNCQUFvQixjQUNqQztBQUNJLGlDQUFpQixLQUNiO0FBQUEsa0JBQ0ksTUFBSztBQUFBLGtCQUNMLE9BQU8sVUFBVSxHQUFHO0FBQUEsa0JBQ3BCLEtBQUssVUFBVSxHQUFHO0FBQUEsa0JBQ2xCLFFBQU87QUFBQSxnQkFDWCxDQUNKO0FBQ0EsOEJBQWM7QUFDZCwwQkFBVTtBQUFBLGNBQ2Q7QUFDQTtBQUFBLGlCQUNDO0FBQ0Qsa0JBQUksVUFBVSxHQUFHLG1CQUFpQixnQkFDOUIsVUFBVSxJQUFFLEdBQUcsb0JBQWtCLGNBQ3JDO0FBQ0ksaUNBQWlCLEtBQ2I7QUFBQSxrQkFDSSxNQUFLO0FBQUEsa0JBQ0wsT0FBTyxVQUFVLEdBQUc7QUFBQSxrQkFDcEIsS0FBSyxVQUFVLEdBQUc7QUFBQSxrQkFDbEIsUUFBTztBQUFBLGdCQUNYLENBQ0o7QUFDQSw4QkFBYztBQUNkLDBCQUFVO0FBQUEsY0FDZDtBQUNBO0FBQUE7QUFHUixjQUFHLE1BQU0scUJBQ1Q7QUFDSSw2QkFBaUIsU0FBUztBQUFBLFVBQzlCO0FBRUEsd0JBQWMsVUFBVSxHQUFHO0FBQzNCLG9CQUFVLFVBQVUsR0FBRyxRQUFRO0FBQy9CLHlCQUFlO0FBQ2Ysa0NBQXdCO0FBQ3hCO0FBQUE7QUFBQSxJQUVaO0FBRUEsYUFBUSxJQUFFLEdBQUUsSUFBRSxVQUFVLFFBQU8sS0FDL0I7QUFDSSxVQUFHLFVBQVUsR0FBRyxTQUFTLHFCQUFtQixVQUFVLEdBQUcsV0FBUyxnQkFBZ0IsR0FBRyxTQUNyRjtBQUNJLHlCQUFpQixLQUNiO0FBQUEsVUFDSSxNQUFNLFVBQVUsR0FBRztBQUFBLFVBQ25CLE9BQU8sZ0JBQWdCLEdBQUc7QUFBQSxVQUMxQixLQUFLLGdCQUFnQixHQUFHO0FBQUEsVUFDeEIsUUFBUSxnQkFBZ0IsR0FBRztBQUFBLFFBQy9CLENBQ0o7QUFBQSxNQUNKO0FBQUEsSUFDSjtBQUVBLHVCQUFtQixpQkFBaUIsS0FBSyxDQUFDLEdBQUcsTUFBVyxFQUFFLFFBQU0sRUFBRSxLQUFLO0FBQ3ZFLFdBQU8sQ0FBQyxZQUFZLGdCQUFnQixnQkFBZ0I7QUFBQSxFQUN4RDtBQUVKO0FBUUEsc0JBQXNCLE1BQWMsUUFBZ0IsTUFBa0IsaUJBQ2xFLGFBQWEsT0FBTyxjQUEwQixjQUFpQixlQUEyQixjQUErQjtBQUN6SCxNQUFJLFdBQVc7QUFDZixNQUFJLGFBQTJCLENBQUM7QUFDaEMsYUFBVyxTQUFTLEtBQUssQ0FBQyxHQUFHLE1BQWMsRUFBRSxRQUFRLEVBQUUsS0FBSztBQUU1RCxTQUFPLE1BQU07QUFDVCxRQUFJLFFBQVEsT0FBTyxLQUFLLElBQUk7QUFDNUIsUUFBSSxDQUFDO0FBQU87QUFDWixRQUFJLFFBQVE7QUFFWixRQUFJLFlBQVk7QUFDWixlQUFTLElBQUksR0FBRyxJQUFJLFNBQVMsUUFBUSxLQUFLO0FBQ3RDLFlBQUcsT0FBTyxZQUFVLFNBQVMsR0FBRyxTQUFTLFNBQVMsR0FBRyxNQUFJLE1BQU0sT0FBTTtBQUNqRSxrQkFBUTtBQUNSO0FBQUEsUUFDSjtBQUFBLE1BQ0o7QUFBQSxJQUNKO0FBQ0EsUUFBSSxDQUFDO0FBQU87QUFDWixlQUFXLEtBQ1A7QUFBQSxNQUNJLFNBQVMsTUFBTTtBQUFBLE1BQ2Y7QUFBQSxNQUNBLE9BQU8sTUFBTTtBQUFBLE1BQ2IsS0FBSyxPQUFPO0FBQUEsTUFDWixrQkFBa0I7QUFBQSxNQUNsQixtQkFBbUI7QUFBQSxJQUN2QixDQUNKO0FBQUEsRUFDSjtBQUNBLGFBQVcsU0FBUyxPQUFPLFVBQVU7QUFFckMsU0FBTztBQUNYO0FBRUEsdUJBQXVCLE1BQWMsTUFBa0IsaUJBQStCLGFBQWEsT0FBTTtBQUNyRyxNQUFJLFdBQVc7QUFDZixNQUFJLGFBQTJCLENBQUM7QUFDaEMsYUFBVyxTQUFTLEtBQUssQ0FBQyxHQUFHLE1BQWMsRUFBRSxRQUFRLEVBQUUsS0FBSztBQUM1RCxNQUFJLFVBQVU7QUFDZCxTQUFPLE1BQU07QUFDVCxRQUFJLFFBQVEsUUFBUSxLQUFLLElBQUk7QUFDN0IsUUFBSSxDQUFDO0FBQU87QUFDWixRQUFJLFFBQVE7QUFDWixRQUFJLGlCQUEwQixNQUFNLFNBQU87QUFFM0MsUUFBSSxZQUFZO0FBQ1osZUFBUyxJQUFJLEdBQUcsSUFBSSxTQUFTLFFBQVEsS0FBSztBQUN0QyxZQUFHLE1BQU0sU0FBUyxTQUFTLEdBQUcsS0FBSTtBQUM5QiwyQkFBaUI7QUFBQSxRQUNyQjtBQUNBLFlBQUcsUUFBUSxZQUFVLFNBQVMsR0FBRyxTQUFTLFNBQVMsR0FBRyxNQUFJLE1BQU0sT0FBTTtBQUNsRSxrQkFBUTtBQUNSO0FBQUEsUUFDSjtBQUFBLE1BQ0o7QUFBQSxJQUNKO0FBQ0EsUUFBRyxDQUFDLGtCQUFrQixPQUN0QjtBQUNJLFVBQUksVUFBVTtBQUNkLFVBQUcsUUFBUSxLQUFLLEtBQUssT0FBTyxNQUFNLFFBQU0sQ0FBQyxDQUFDLEdBQUU7QUFDeEMsZ0JBQVE7QUFBQSxNQUNaO0FBQUEsSUFDSjtBQUVBLFFBQUksQ0FBQztBQUFPO0FBQ1osZUFBVyxLQUNQO0FBQUEsTUFDSSxTQUFTLE1BQU07QUFBQSxNQUNmO0FBQUEsTUFDQSxPQUFPLE1BQU07QUFBQSxNQUNiLEtBQUssUUFBUTtBQUFBLE1BQ2Isa0JBQWtCO0FBQUEsTUFDbEIsbUJBQW1CO0FBQUEsSUFDdkIsQ0FDSjtBQUFBLEVBQ0o7QUFDQSxhQUFXLFNBQVMsT0FBTyxVQUFVO0FBRXJDLFNBQU87QUFDWDtBQUtBLHlDQUF5QyxNQUFjLFNBQWdDO0FBQ25GLE1BQUksV0FBeUIsQ0FBQztBQUM5QixNQUFJLGNBQWM7QUFDbEIsTUFBSSxZQUFZO0FBSWhCLGFBQVcsYUFBYSxNQUFNLGFBQWEsMkJBQXFCLFFBQVE7QUFFeEUsYUFBVyxhQUFhLE1BQU0sV0FBVyx1QkFBbUIsUUFBUTtBQUdwRSxNQUFJLGFBQXVCLENBQUM7QUFDNUIsTUFBSSxtQkFBaUMsQ0FBQztBQUN0QyxNQUFJLG9CQUFrQyxDQUFDO0FBQ3ZDLE1BQUksVUFBVTtBQUNkLE1BQUksY0FBYztBQUNsQixNQUFJLFNBQVM7QUFDVCxRQUFJLE9BQU8sUUFBUSxNQUFNLElBQUk7QUFDN0IsYUFBUyxJQUFJLEdBQUcsSUFBSSxLQUFLLFFBQVEsS0FBSztBQUVsQyxVQUFJLFFBQVEsS0FBSyxLQUFLLEVBQUU7QUFBRztBQUUzQixVQUFLLENBQUMsWUFBWSxLQUFLLEtBQUssRUFBRSxLQUFNLEtBQUssR0FBRyxVQUFVLEdBQUc7QUFDckQsWUFBSSx1QkFBTyx1QkFBa0IsT0FBTyxDQUFDLElBQUkseUVBQWdCLEtBQUssRUFBRTtBQUNoRTtBQUFBLE1BQ0o7QUFDQSxVQUFJLFVBQVUsS0FBSyxHQUFHLFVBQVUsR0FBRyxLQUFLLEdBQUcsU0FBUyxDQUFDO0FBQ3JELFVBQUksaUJBQWlCLEtBQUssR0FBRyxVQUFVLEtBQUssR0FBRyxTQUFTLENBQUM7QUFFekQsVUFBSSxhQUFhO0FBQ2pCLFVBQUk7QUFDQSxZQUFJLFVBQVUsSUFBSSxPQUFPLFNBQVMsR0FBRztBQUFBLE1BQ3pDLFNBQ08sT0FBUDtBQUNJLHFCQUFhO0FBQ2IsWUFBRyxLQUFLLFNBQVMsT0FBTTtBQUNuQixjQUFJLHVCQUFPLDhCQUE4QixPQUFPO0FBQUEsUUFDcEQ7QUFBQSxNQUNKO0FBRUEsVUFBSSxZQUFZO0FBQ1osbUJBQVcsS0FBSyxJQUFJLE9BQU8sU0FBUyxHQUFHLENBQUM7QUFDeEMseUJBQWlCLEtBQUssZUFBZSxlQUFlLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDOUQsMEJBQWtCLEtBQUssZUFBZSxlQUFlLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFBQSxNQUNuRTtBQUFBLElBQ0o7QUFDQSxRQUFJLFNBQVMsV0FBVztBQUV4QixhQUFTLElBQUksR0FBRyxJQUFJLFFBQVEsS0FBSztBQUM3QixpQkFBVyxhQUFhLE1BQU0sV0FBVyxJQUFJLDJCQUFpQixVQUFVLE1BQU0saUJBQWlCLElBQUksa0JBQWtCLEVBQUU7QUFBQSxJQUMzSDtBQUFBLEVBQ0o7QUFHQSxhQUFXLGFBQWEsTUFBTSxtQ0FBbUMsMkJBQWlCLFVBQVUsTUFBTSxjQUFpQixZQUFlO0FBR2xJLGFBQVcsY0FBYyxNQUFNLDJCQUFpQixVQUFVLElBQUk7QUFHOUQsYUFBVyxTQUFTLEtBQUssQ0FBQyxHQUFHLE1BQWMsRUFBRSxRQUFRLEVBQUUsS0FBSztBQUU1RCxNQUFJLFlBQTBCLENBQUM7QUFDL0IsTUFBSSxZQUFZO0FBQ2hCLE1BQUksVUFBVTtBQUNkLFdBQVMsSUFBSSxHQUFHLElBQUksU0FBUyxRQUFRLEtBQUs7QUFDdEMsUUFBSSxZQUFZLFNBQVMsR0FBRyxPQUFPO0FBQy9CLGdCQUFVLFNBQVMsR0FBRztBQUN0QixnQkFBVSxLQUNOO0FBQUEsUUFDSSxTQUFTLEtBQUssVUFBVSxXQUFXLE9BQU87QUFBQSxRQUMxQyxNQUFNO0FBQUEsUUFDTixPQUFPO0FBQUEsUUFDUCxLQUFLO0FBQUEsUUFDTCxrQkFBa0I7QUFBQSxRQUNsQixtQkFBbUI7QUFBQSxNQUN2QixDQUNKO0FBQUEsSUFDSjtBQUNBLGdCQUFZLFNBQVMsR0FBRztBQUFBLEVBQzVCO0FBRUEsTUFBSSxhQUFhLEtBQUssUUFBUTtBQUMxQixjQUFVLEtBQ047QUFBQSxNQUNJLFNBQVMsS0FBSyxVQUFVLFdBQVcsS0FBSyxNQUFNO0FBQUEsTUFDOUMsTUFBTTtBQUFBLE1BQ04sT0FBTztBQUFBLE1BQ1AsS0FBSyxLQUFLO0FBQUEsTUFDVixrQkFBa0I7QUFBQSxNQUNsQixtQkFBbUI7QUFBQSxJQUN2QixDQUNKO0FBQUEsRUFDSjtBQUdBLGFBQVcsU0FBUyxPQUFPLFNBQVM7QUFDcEMsYUFBVyxTQUFTLEtBQUssQ0FBQyxHQUFHLE1BQWMsRUFBRSxRQUFRLEVBQUUsS0FBSztBQUM1RCxTQUFPO0FBQ1g7QUFHQSx3QkFBd0IsR0FBdUI7QUFDM0MsVUFBUTtBQUFBLFNBQ0M7QUFDRCxhQUFPO0FBQUEsU0FDTjtBQUNELGFBQU87QUFBQSxTQUNOO0FBQUE7QUFFRCxhQUFPO0FBQUE7QUFFbkI7QUFHTywyQkFBMkIsR0FDbEM7QUFDSSxNQUFHLE9BQU8sQ0FBQyxLQUFHO0FBQWlCLFdBQU87QUFDdEMsTUFBRyxPQUFPLENBQUMsS0FBRztBQUFpQixXQUFPO0FBQ3RDLE1BQUcsT0FBTyxDQUFDLEtBQUc7QUFBbUIsV0FBTztBQUN4QyxTQUFPO0FBQ1g7QUFHTyx3QkFBd0IsT0FBb0IsS0FBc0I7QUFDckUsUUFBTSxPQUFPLE1BQU0sSUFBSSxPQUFPLEdBQUc7QUFDakMsTUFBSSxjQUFjLEtBQUs7QUFFdkIsUUFBTSxPQUFPLHNDQUFpQixPQUFPLEtBQUssRUFBRTtBQUM1QyxRQUFNLFFBQVEsS0FBSyxRQUFRLEtBQUssTUFBTSxDQUFDLEVBQUU7QUFNekMsTUFBSSxNQUFNLFNBQVMsT0FBTyxHQUFFO0FBQ3hCLFdBQU87QUFBQSxFQUNYO0FBRUEsTUFBSSxNQUFNLFNBQVMsaUJBQWlCLEdBQUU7QUFDbEMsV0FBTztBQUFBLEVBQ1g7QUFFQSxNQUFHLE1BQU0sU0FBUyxNQUFNLEdBQUU7QUFDdEIsYUFBUSxJQUFFLEtBQUssT0FBSyxHQUFFLElBQUUsS0FBSyxJQUFHLEtBQUcsR0FBRTtBQUNqQyxVQUFHLENBQUMsS0FBSyxRQUFRLEdBQUcsQ0FBQyxFQUFFLEtBQUssU0FBUyxNQUFNLEdBQUU7QUFDekMsZUFBTztBQUFBLE1BQ1g7QUFBQSxJQUNKO0FBQ0EsV0FBTztBQUFBLEVBQ1gsV0FDUSxNQUFNLFNBQVMsTUFBTSxLQUFLLE1BQU0sU0FBUyxPQUFPLEdBQUU7QUFDdEQsYUFBUSxJQUFFLEtBQUssT0FBSyxHQUFFLElBQUUsS0FBSyxJQUFHLEtBQUcsR0FBRTtBQUNqQyxVQUFJLElBQUksS0FBSyxRQUFRLEdBQUcsQ0FBQyxFQUFFO0FBQzNCLFVBQUcsQ0FBRSxHQUFFLFNBQVMsTUFBTSxLQUFLLEVBQUUsU0FBUyxPQUFPLElBQUc7QUFDNUMsZUFBTztBQUFBLE1BQ1g7QUFBQSxJQUNKO0FBQ0EsV0FBTztBQUFBLEVBQ1gsV0FDUSxNQUFNLFNBQVMsT0FBTyxLQUFLLENBQUMsTUFBTSxTQUFTLFNBQVMsR0FBRTtBQUcxRCxRQUFJLHFCQUFxQjtBQUN6QixhQUFRLElBQUUsY0FBWSxHQUFHLEtBQUcsR0FBRyxLQUFHLEdBQUU7QUFDaEMsVUFBSSxTQUFTLE1BQU0sSUFBSSxLQUFLLENBQUM7QUFDN0IsVUFBSSxVQUFVLEtBQUssUUFBUSxPQUFPLE1BQU0sQ0FBQyxFQUFFO0FBQzNDLFVBQUcsQ0FBQyxRQUFRLFNBQVMsT0FBTyxHQUFFO0FBQzFCO0FBQUEsTUFDSjtBQUNBLFVBQUksUUFBUSxTQUFTLFNBQVMsR0FBRTtBQUM1Qiw2QkFBcUI7QUFDckI7QUFBQSxNQUNKO0FBQUEsSUFDSjtBQUNBLFFBQUksc0JBQW9CO0FBQUksYUFBTztBQUduQyxRQUFJLGdCQUF3QjtBQUM1QixRQUFJLFFBQWdCO0FBQ3BCLFFBQUksaUJBQWlCO0FBQ3JCLFFBQUksZUFBZTtBQUNuQixhQUFTLElBQUUscUJBQW1CLEdBQUcsS0FBRyxhQUFhLEtBQUcsR0FBRTtBQUNsRCxVQUFJLFNBQVMsTUFBTSxJQUFJLEtBQUssQ0FBQztBQUM3QixVQUFJLE9BQU07QUFDTix3QkFBZ0I7QUFDaEIsZ0JBQVE7QUFBQSxNQUNaO0FBQ0EsVUFBRyxpQkFBaUIsYUFBYSxLQUFLLE9BQU8sSUFBSSxHQUFFO0FBQy9DLHdCQUFnQjtBQUNoQixnQkFBUTtBQUFBLE1BQ1osV0FDUSxDQUFDLGlCQUFpQixlQUFlLEtBQUssT0FBTyxJQUFJLEdBQUU7QUFDdkQsd0JBQWdCO0FBQUEsTUFDcEI7QUFBQSxJQUNKO0FBQ0EsUUFBSSxlQUFlO0FBQ2YsYUFBTztBQUFBLElBQ1g7QUFDSyxhQUFPO0FBQUEsRUFDaEIsV0FDUSxNQUFNLFNBQVMsTUFBTSxHQUFFO0FBQzNCLGFBQVEsSUFBRSxLQUFLLE9BQUssR0FBRSxJQUFFLEtBQUssSUFBRyxLQUFHLEdBQUU7QUFDakMsVUFBSSxJQUFJLEtBQUssUUFBUSxHQUFHLENBQUMsRUFBRTtBQUMzQixVQUFJLEVBQUUsU0FBUyxNQUFNLEtBQUssRUFBRSxTQUFTLE9BQU8sR0FBRztBQUMzQyxlQUFPO0FBQUEsTUFDWDtBQUFBLElBQ0o7QUFBQSxFQUNKO0FBQ0EsU0FBTztBQUNYO0FBR08seUJBQXlCLE9BQW9CLEtBQXNCO0FBQ3RFLFFBQU0sT0FBTyxNQUFNLElBQUksT0FBTyxHQUFHO0FBQ2pDLFFBQU0sT0FBTyxnQ0FBVyxLQUFLO0FBQzdCLFFBQU0sUUFBUSxLQUFLLFFBQVEsS0FBSyxNQUFNLENBQUMsRUFBRTtBQUN6QyxNQUFJLE1BQU0sU0FBUyxpQkFBaUIsR0FBRTtBQUNsQyxXQUFPO0FBQUEsRUFDWDtBQUVBLE1BQUcsTUFBTSxTQUFTLE1BQU0sR0FBRTtBQUN0QixhQUFRLElBQUUsS0FBSyxPQUFLLEdBQUUsSUFBRSxLQUFLLElBQUcsS0FBRyxHQUFFO0FBQ2pDLFVBQUcsQ0FBQyxLQUFLLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxTQUFTLE1BQU0sR0FBRTtBQUN6QyxlQUFPO0FBQUEsTUFDWDtBQUFBLElBQ0o7QUFDQSxXQUFPO0FBQUEsRUFDWCxXQUNRLE1BQU0sU0FBUyxNQUFNLEtBQUssTUFBTSxTQUFTLE9BQU8sR0FBRTtBQUN0RCxhQUFRLElBQUUsS0FBSyxPQUFLLEdBQUUsSUFBRSxLQUFLLElBQUcsS0FBRyxHQUFFO0FBQ2pDLFVBQUksSUFBSSxLQUFLLFFBQVEsR0FBRyxDQUFDLEVBQUU7QUFDM0IsVUFBRyxDQUFFLEdBQUUsU0FBUyxNQUFNLEtBQUssRUFBRSxTQUFTLE9BQU8sSUFBRztBQUM1QyxlQUFPO0FBQUEsTUFDWDtBQUFBLElBQ0o7QUFDQSxXQUFPO0FBQUEsRUFDWDtBQUVBLFdBQVEsSUFBRSxLQUFLLE1BQUssSUFBRSxLQUFLLElBQUcsS0FBRyxHQUFFO0FBQy9CLFFBQUcsS0FBSyxRQUFRLEdBQUcsQ0FBQyxFQUFFLEtBQUssU0FBUyxNQUFNLEdBQUU7QUFDeEMsYUFBTztBQUFBLElBQ1gsV0FDUSxLQUFLLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxTQUFTLFNBQVMsR0FBRTtBQUNoRCxhQUFPO0FBQUEsSUFDWDtBQUFBLEVBQ0o7QUFFQSxNQUFHLE1BQU0sU0FBUyxPQUFPLEdBQUU7QUFDdkIsV0FBTztBQUFBLEVBQ1g7QUFFQSxTQUFPO0FBQ1g7OztBRTVyQ0EsdUJBQWdKO0FBeUR6SSxJQUFNLG1CQUF1QztBQUFBLEVBQ25ELFFBQVE7QUFBQSxFQUNSLGtCQUFrQjtBQUFBLEVBQ2xCLHNCQUFzQjtBQUFBLEVBQ3RCLG1CQUFtQjtBQUFBLEVBQ25CLGNBQWM7QUFBQSxFQUNkLGdCQUFnQjtBQUFBLEVBRWhCLFlBQVk7QUFBQSxFQUNaLGNBQWM7QUFBQSxFQUNkLHFCQUFxQjtBQUFBLEVBQ3JCLG9CQUFvQjtBQUFBLEVBQ3BCLG9CQUFvQjtBQUFBLEVBQ3BCLGdCQUFnQjtBQUFBLEVBQ2hCLGtCQUFrQjtBQUFBLEVBQ2xCLGFBQWE7QUFBQSxFQUNiLGlCQUFpQjtBQUFBLEVBQ2pCLHNCQUFzQjtBQUFBLEVBQ3RCLHFCQUFxQjtBQUFBLEVBQ3JCLHdCQUF3QjtBQUFBLEVBQ3hCLHFCQUFxQjtBQUFBLEVBQ3JCLHNCQUFzQjtBQUFBLEVBQ3RCLHNCQUFzQjtBQUFBLEVBQ3RCLG1CQUFtQjtBQUFBLEVBTW5CLE9BQU87QUFBQSxFQUNQLHVCQUF1QixDQUFDLEtBQUssR0FBRztBQUFBLEVBQ2hDLHFCQUFxQixDQUFDLEVBQUMsTUFBSyxNQUFNLE9BQU0sS0FBSSxHQUFHLEVBQUMsTUFBSyxLQUFLLE9BQU0sSUFBRyxDQUFDO0FBQUEsRUFDcEUsd0JBQXdCLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQztBQUFBLEVBQ3ZDLHlCQUF5QixDQUFDLENBQUMsT0FBTSxZQUFLLENBQUM7QUFBQSxFQUN2Qyx5QkFBeUI7QUFBQSxFQUN6Qix5QkFBeUI7QUFBQSxFQUN6Qix5QkFBeUI7QUFBQSxFQUV6QixZQUFZO0FBQUEsRUFDWixpQkFBaUI7QUFBQSxFQUNqQixhQUFhO0FBQUEsRUFDYixxQkFBcUI7QUFBQSxFQUNyQixhQUFhO0FBQ2Q7QUFFTyxJQUFNLHVCQUFOLGNBQW1DLGtDQUFpQjtBQUFBLEVBRzFELFlBQVksS0FBVSxRQUEwQjtBQUMvQyxVQUFNLEtBQUssTUFBTTtBQUNqQixTQUFLLFNBQVM7QUFBQSxFQUNmO0FBQUEsRUFFQSxVQUFnQjtBQUNmLFVBQU0sRUFBRSxnQkFBZ0I7QUFFeEIsZ0JBQVksTUFBTTtBQUVsQixnQkFBWSxTQUFTLE1BQU0sRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pFLGdCQUFZLFNBQVMsS0FBSyxFQUFFLE1BQU0sNkJBQTZCLENBQUMsRUFBRSxTQUFTLEtBQUs7QUFBQSxNQUMvRSxNQUFNO0FBQUEsTUFDTixNQUFNO0FBQUEsSUFDUCxDQUFDO0FBRUQsZ0JBQVksU0FBUyxNQUFNLEVBQUUsTUFBTSxrRUFBb0MsQ0FBQztBQUV4RSxRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSx1Q0FBdUMsRUFDL0MsUUFBUSxpTEFBcUMsRUFDN0MsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxTQUFTLEtBQUssT0FBTyxTQUFTLG9CQUFvQixFQUN2RCxTQUFTLE9BQU8sVUFBVTtBQUMxQixhQUFLLE9BQU8sU0FBUyx1QkFBdUI7QUFDNUMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNILENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSwrQkFBK0IsRUFDdkMsUUFBUSw4UEFBbUQsRUFDM0QsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxTQUFTLEtBQUssT0FBTyxTQUFTLGdCQUFnQixFQUNuRCxTQUFTLE9BQU8sVUFBVTtBQUMxQixhQUFLLE9BQU8sU0FBUyxtQkFBbUI7QUFDeEMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNILENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSwyREFBMkQsRUFDbkUsUUFBUSxtSkFBZ0MsRUFDeEMsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxTQUFTLEtBQUssT0FBTyxTQUFTLFlBQVksRUFDL0MsU0FBUyxPQUFPLFVBQVU7QUFDMUIsYUFBSyxPQUFPLFNBQVMsZUFBZTtBQUNwQyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsTUFDaEMsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUVGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLHlDQUF5QyxFQUNqRCxRQUFRLDZRQUFnRixFQUN4RixVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsaUJBQWlCLEVBQ3BELFNBQVMsT0FBTyxVQUFVO0FBQzFCLGFBQUssT0FBTyxTQUFTLG9CQUFvQjtBQUN6QyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsTUFDaEMsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUVGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLHdCQUF3QixFQUNoQyxRQUFRLDZNQUF5RyxFQUNqSCxVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsY0FBYyxFQUNqRCxTQUFTLE9BQU8sVUFBVTtBQUMxQixhQUFLLE9BQU8sU0FBUyxpQkFBaUI7QUFDdEMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNILENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxRQUFRLEVBQ2hCLFFBQVEsNkpBQTZFLEVBQ3JGLFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQU8sU0FBUyxLQUFLLE9BQU8sU0FBUyxNQUFNLEVBQ3pDLFNBQVMsT0FBTyxVQUFVO0FBQzFCLGFBQUssT0FBTyxTQUFTLFNBQVM7QUFDOUIsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNILENBQUM7QUFFRixnQkFBWSxTQUFTLE1BQU0sRUFBRSxNQUFNLDBGQUE2QyxDQUFDO0FBQ2pGLFNBQUssMkJBQTJCLEtBQUssWUFBWSxTQUFTLFdBQVc7QUFBQSxNQUNwRSxLQUFLO0FBQUEsTUFDTCxNQUFNO0FBQUEsUUFDTCxHQUFJLEtBQUssT0FBTyxTQUFTLDBCQUF3QixFQUFFLE1BQU0sS0FBSyxJQUFFLENBQUM7QUFBQSxNQUNsRTtBQUFBLElBQ0QsQ0FBQyxDQUFDO0FBRUYsU0FBSywyQkFBMkIsS0FBSyxZQUFZLFNBQVMsV0FBVztBQUFBLE1BQ3BFLEtBQUs7QUFBQSxNQUNMLE1BQU07QUFBQSxRQUNMLEdBQUksS0FBSyxPQUFPLFNBQVMsMEJBQXdCLEVBQUUsTUFBTSxLQUFLLElBQUUsQ0FBQztBQUFBLE1BQ2xFO0FBQUEsSUFDRCxDQUFDLENBQUM7QUFFRixTQUFLLDRCQUE0QixLQUFLLFlBQVksU0FBUyxXQUFXO0FBQUEsTUFDckUsS0FBSztBQUFBLE1BQ0wsTUFBTTtBQUFBLFFBQ0wsR0FBSSxLQUFLLE9BQU8sU0FBUywwQkFBd0IsRUFBRSxNQUFNLEtBQUssSUFBRSxDQUFDO0FBQUEsTUFDbEU7QUFBQSxJQUNELENBQUMsQ0FBQztBQUdGLGdCQUFZLFNBQVMsTUFBTSxFQUFFLE1BQU0sa0VBQStCLENBQUM7QUFFbkUsUUFBSSx5QkFBUSxXQUFXLEVBQ3JCLFFBQVEsNkJBQTZCLEVBQ3JDLFFBQVEsd0pBQTJCLEVBQ25DLFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQU8sU0FBUyxLQUFLLE9BQU8sU0FBUyxVQUFVLEVBQzdDLFNBQVMsT0FBTyxVQUFVO0FBQzFCLGFBQUssT0FBTyxTQUFTLGFBQWE7QUFDbEMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNILENBQUM7QUFDRixnQkFBWSxTQUFTLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRTVELFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLG1DQUFtQyxFQUMzQyxRQUFRLHdEQUFXLEVBQ25CLFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQU8sU0FBUyxLQUFLLE9BQU8sU0FBUyxtQkFBbUIsRUFBRSxTQUFTLE9BQU8sVUFBVTtBQUNuRixhQUFLLE9BQU8sU0FBUyxzQkFBc0I7QUFDM0MsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxrQ0FBa0MsRUFDMUMsUUFBUSx3REFBVyxFQUNuQixVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsa0JBQWtCLEVBQUUsU0FBUyxPQUFPLFVBQVU7QUFDbEYsYUFBSyxPQUFPLFNBQVMscUJBQXFCO0FBQzFDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDRixDQUFDO0FBRUYsUUFBSSx5QkFBUSxXQUFXLEVBQ3JCLFFBQVEsa0NBQWtDLEVBQzFDLFFBQVEsd0RBQVcsRUFDbkIsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxTQUFTLEtBQUssT0FBTyxTQUFTLGtCQUFrQixFQUFFLFNBQVMsT0FBTyxVQUFVO0FBQ2xGLGFBQUssT0FBTyxTQUFTLHFCQUFxQjtBQUMxQyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsTUFDaEMsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUVGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLDZDQUE2QyxFQUNyRCxRQUFRLDhEQUFZLEVBQ3BCLFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQU8sU0FBUyxLQUFLLE9BQU8sU0FBUyxjQUFjLEVBQUUsU0FBUyxPQUFPLFVBQVU7QUFDOUUsYUFBSyxPQUFPLFNBQVMsaUJBQWlCO0FBQ3RDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDRixDQUFDO0FBRUYsUUFBSSx5QkFBUSxXQUFXLEVBQ3JCLFFBQVEsK0NBQStDLEVBQ3ZELFFBQVEsOERBQVksRUFDcEIsWUFBWSxDQUFDLGFBQWE7QUFDMUIsZUFBUyxVQUFVLCtCQUF5QixrREFBeUI7QUFDckUsZUFBUyxVQUFVLHlCQUFtQix5Q0FBcUI7QUFDM0QsZUFBUyxTQUFTLEtBQUssT0FBTyxTQUFTLGVBQWU7QUFDdEQsZUFBUyxTQUFTLE9BQU8sTUFBbUQ7QUFDM0UsYUFBSyxPQUFPLFNBQVMsa0JBQWtCO0FBQ3ZDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDRixDQUFDLEVBQ0EsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxXQUFXLGtDQUFjO0FBQ2hDLGFBQU8sU0FBUyxLQUFLLE9BQU8sU0FBUyxXQUFXLEVBQUUsU0FBUyxPQUFPLFVBQVU7QUFDM0UsYUFBSyxPQUFPLFNBQVMsY0FBYztBQUNuQyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsTUFDaEMsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUVGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLG1EQUFtRCxFQUMzRCxRQUFRLG9FQUFhLEVBQ3JCLFlBQVksQ0FBQyxhQUFhO0FBQzFCLGVBQVMsVUFBVSwrQkFBeUIsa0RBQXlCO0FBQ3JFLGVBQVMsVUFBVSx5QkFBbUIseUNBQXFCO0FBQzNELGVBQVMsU0FBUyxLQUFLLE9BQU8sU0FBUyxvQkFBb0I7QUFDM0QsZUFBUyxTQUFTLE9BQU8sTUFBbUQ7QUFDM0UsYUFBSyxPQUFPLFNBQVMsdUJBQXVCO0FBQzVDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDRixDQUFDLEVBQ0EsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxTQUFTLEtBQUssT0FBTyxTQUFTLGdCQUFnQixFQUFFLFNBQVMsT0FBTyxVQUFVO0FBQ2hGLGFBQUssT0FBTyxTQUFTLG1CQUFtQjtBQUN4QyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsTUFDaEMsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUVGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLDRDQUE0QyxFQUNwRCxRQUFRLG92QkFJVCxFQUNDLFlBQVksQ0FBQyxhQUFhO0FBQzFCLGVBQVMsVUFBVSxPQUFPLFlBQWUsR0FBRyxnQ0FBaUI7QUFDN0QsZUFBUyxVQUFVLE9BQU8sWUFBZSxHQUFHLGdDQUFpQjtBQUM3RCxlQUFTLFVBQVUsT0FBTyxjQUFpQixHQUFHLHdDQUFvQjtBQUNsRSxlQUFTLFNBQVMsT0FBTyxLQUFLLE9BQU8sU0FBUyxtQkFBbUIsQ0FBQztBQUNsRSxlQUFTLFNBQVMsT0FBTyxNQUFjO0FBQ3RDLGFBQUssT0FBTyxTQUFTLHNCQUFzQixrQkFBa0IsQ0FBQztBQUM5RCxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsTUFDaEMsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUVGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLCtDQUErQyxFQUN2RCxRQUFRLDBGQUFvQixFQUM1QixZQUFZLENBQUMsYUFBYTtBQUMxQixlQUFTLFVBQVUsT0FBTyxZQUFlLEdBQUcsZ0NBQWlCO0FBQzdELGVBQVMsVUFBVSxPQUFPLFlBQWUsR0FBRyxnQ0FBaUI7QUFDN0QsZUFBUyxVQUFVLE9BQU8sY0FBaUIsR0FBRyx3Q0FBb0I7QUFDbEUsZUFBUyxTQUFTLE9BQU8sS0FBSyxPQUFPLFNBQVMsc0JBQXNCLENBQUM7QUFDckUsZUFBUyxTQUFTLE9BQU8sTUFBYztBQUN0QyxhQUFLLE9BQU8sU0FBUyx5QkFBeUIsa0JBQWtCLENBQUM7QUFDakUsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxzQ0FBc0MsRUFDOUMsUUFBUSx3VUFBbUYsRUFDM0YsWUFBWSxDQUFDLGFBQWE7QUFDMUIsZUFBUyxVQUFVLFNBQVMsMkJBQVk7QUFDeEMsZUFBUyxVQUFVLFNBQVMsaUNBQWE7QUFDekMsZUFBUyxTQUFTLEtBQUssT0FBTyxTQUFTLHVCQUF1QixVQUFVLE9BQU87QUFDL0UsZUFBUyxTQUFTLE9BQU8sTUFBYztBQUN0QyxhQUFLLE9BQU8sU0FBUyx1QkFBdUIsS0FBSyxVQUFVLE9BQU87QUFFbEUsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUMsRUFDQSxZQUFZLENBQUMsYUFBYTtBQUMxQixlQUFTLFVBQVUsT0FBTyxZQUFlLEdBQUcsZ0NBQWlCO0FBQzdELGVBQVMsVUFBVSxPQUFPLFlBQWUsR0FBRyxnQ0FBaUI7QUFDN0QsZUFBUyxVQUFVLE9BQU8sY0FBaUIsR0FBRyx3Q0FBb0I7QUFDbEUsZUFBUyxTQUFTLE9BQU8sS0FBSyxPQUFPLFNBQVMsbUJBQW1CLENBQUM7QUFDbEUsZUFBUyxTQUFTLE9BQU8sTUFBYztBQUN0QyxhQUFLLE9BQU8sU0FBUyxzQkFBc0Isa0JBQWtCLENBQUM7QUFDOUQsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRixnQkFBWSxTQUFTLE1BQU0sRUFBRSxNQUFNLGdGQUE2QyxDQUFDO0FBQ2pGLFFBQUkseUJBQVEsV0FBVyxFQUNyQixRQUFRLDRCQUE0QixFQUNwQyxRQUFRLGtTQUFrRCxFQUMxRCxVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsb0JBQW9CLEVBQUUsU0FBUyxPQUFPLFVBQVU7QUFDcEYsYUFBSyxPQUFPLFNBQVMsdUJBQXVCO0FBQzVDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDRixDQUFDO0FBRUYsZ0JBQVksU0FBUyxLQUFLLEVBQUUsTUFBTSxzRUFBZSxDQUFDLEVBQUUsU0FBUyxLQUFLO0FBQUEsTUFDakUsTUFBTTtBQUFBLE1BQ04sTUFBTTtBQUFBLElBQ1AsQ0FBQztBQUVELGdCQUFZLFNBQVMsS0FBSyxFQUFFLE1BQU0sNkZBQWtCLENBQUMsRUFBRSxTQUFTLEtBQUs7QUFBQSxNQUNwRSxNQUFNO0FBQUEsTUFDTixNQUFNO0FBQUEsSUFDUCxDQUFDO0FBRUQsVUFBTSx3QkFBd0IsSUFBSSx5QkFBUSxXQUFXO0FBQ3JELDBCQUFzQixVQUFVLGFBQy9CLFNBQ0EsNENBQ0Q7QUFDQSwwQkFDRSxRQUFRLDBEQUEwRCxFQUNsRSxRQUNBLHdzQkFHRDtBQUNELFVBQU0saUJBQWlCLElBQUksbUNBQzFCLHNCQUFzQixTQUN2QjtBQUVBLGtCQUFjLGVBQWUsU0FBUztBQUFBLE1BQ3JDLE9BQU87QUFBQSxJQUVSLENBQUM7QUFDRCxtQkFDRSxTQUFTLEtBQUssT0FBTyxTQUFTLGlCQUFpQixFQUMvQyxTQUFTLE9BQU8sVUFBVTtBQUMxQixXQUFLLE9BQU8sU0FBUyxvQkFBb0I7QUFDekMsV0FBSyxPQUFPLGFBQWE7QUFBQSxJQUMxQixDQUFDO0FBRUYsZ0JBQVksU0FBUyxNQUFNLEVBQUUsTUFBTSx1RkFBcUMsQ0FBQztBQUN6RSxRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSx1QkFBdUIsRUFDL0IsUUFBUSwrSEFBK0gsRUFDdkksWUFBWSxDQUFDLFNBQ2IsS0FDRSxTQUFTLEtBQUssT0FBTyxTQUFTLFlBQVksRUFDMUMsU0FBUyxPQUFPLFVBQVU7QUFDMUIsV0FBSyxPQUFPLFNBQVMsZUFBZTtBQUNwQyxXQUFLLE9BQU8sYUFBYTtBQUFBLElBQzFCLENBQUMsQ0FDSDtBQUVELGdCQUFZLFNBQVMsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsUUFBSSx5QkFBUSxXQUFXLEVBQ3JCLFFBQVEsa0VBQWtFLEVBQzFFLFFBQVEscUxBQThDLEVBQ3RELFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQU8sU0FBUyxLQUFLLE9BQU8sU0FBUyxtQkFBbUIsRUFBRSxTQUFTLE9BQU8sVUFBVTtBQUNuRixhQUFLLE9BQU8sU0FBUyxzQkFBc0I7QUFDM0MsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxrQ0FBa0MsRUFDMUMsUUFBUSx3REFBVyxFQUNuQixVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsV0FBVyxFQUFFLFNBQVMsT0FBTyxVQUFVO0FBQzNFLGFBQUssT0FBTyxTQUFTLGNBQWM7QUFDbkMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxxQ0FBcUMsRUFDN0MsUUFBUSxnTEFBK0IsRUFDdkMsVUFBVSxDQUFDLFdBQVc7QUFDdEIsYUFBTyxTQUFTLEtBQUssT0FBTyxTQUFTLFVBQVUsRUFBRSxTQUFTLE9BQU8sVUFBVTtBQUMxRSxhQUFLLE9BQU8sU0FBUyxhQUFhO0FBQ2xDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDRixDQUFDO0FBRUYsUUFBSSx5QkFBUSxXQUFXLEVBQ3JCLFFBQVEsY0FBYyxFQUN0QixRQUFRLDBMQUFvQyxFQUM1QyxVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsV0FBVyxFQUFFLFNBQVMsT0FBTyxVQUFVO0FBQzNFLGFBQUssT0FBTyxTQUFTLGNBQWM7QUFDbkMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRixRQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSw2QkFBNkIsRUFDckMsUUFBUSw4REFBWSxFQUNwQixVQUFVLENBQUMsV0FBVztBQUN0QixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsS0FBSyxFQUFFLFNBQVMsT0FBTyxVQUFVO0FBQ3JFLGFBQUssT0FBTyxTQUFTLFFBQVE7QUFDN0IsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBQUEsRUFFQSwyQkFBMkIsYUFBZ0M7QUFDMUQsZ0JBQVksTUFBTTtBQUNaLGdCQUFZLFdBQVcsWUFBWTtBQUN4QyxXQUFLLE9BQU8sU0FBUywwQkFBMEIsWUFBWTtBQUMzRCxZQUFNLEtBQUssT0FBTyxhQUFhO0FBQUEsSUFDMUI7QUFDTixVQUFNLFVBQVUsWUFBWSxTQUFTLFdBQVcsRUFBQyxLQUFLLDZCQUE0QixDQUFDO0FBQ25GLFlBQVEsUUFBUSxtSEFBa0Q7QUFLbEUsVUFBTSx1QkFBdUIsSUFBSSx5QkFBUSxXQUFXO0FBQ3BELHlCQUNFLFFBQVEsd0JBQXdCO0FBRWxDLFVBQU0scUJBQXFCLElBQUksK0JBQWMscUJBQXFCLFNBQVM7QUFDM0UsdUJBQW1CLGVBQWUsZUFBZTtBQUVqRCxVQUFNLG9CQUFvQixJQUFJLG1DQUFrQixxQkFBcUIsU0FBUztBQUM5RSxzQkFBa0IsZUFBZSxzQkFBc0I7QUFFdkQsVUFBTSxxQkFBcUIsSUFBSSxtQ0FBa0IscUJBQXFCLFNBQVM7QUFDL0UsdUJBQW1CLGVBQWUsdUJBQXVCO0FBRXpELHlCQUNFLFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQ0UsY0FBYyxHQUFHLEVBQ2pCLFdBQVcsVUFBVSxFQUNyQixRQUFRLE9BQU8sYUFBa0I7QUFDakMsWUFBSSxVQUFVLG1CQUFtQixRQUFRO0FBQ3pDLFlBQUksT0FBTyxrQkFBa0IsUUFBUTtBQUNyQyxZQUFJLFFBQVEsbUJBQW1CLFFBQVE7QUFDdkMsWUFBSSxXQUFZLFNBQVEsUUFBUTtBQUMvQixjQUFHLFFBQVEsVUFBUSxLQUFLLFdBQVMsa0JBQVEsV0FBUyxnQkFBSztBQUN0RCxnQkFBSSx3QkFBTyw2RkFBeUU7QUFDcEY7QUFBQSxVQUNEO0FBQ0EsY0FBSSxLQUFLLE9BQU8sd0JBQXdCLFNBQVMsTUFBTSxLQUFLLEdBQUU7QUFDN0Qsa0JBQU0sS0FBSyxPQUFPLGFBQWE7QUFDL0IsaUJBQUssUUFBUTtBQUFBLFVBQ2QsT0FDSTtBQUNILGdCQUFJLHdCQUFPLHNCQUFzQixVQUFVLG9CQUFvQjtBQUFBLFVBQ2hFO0FBQUEsUUFDRCxPQUNLO0FBQ0osY0FBSSx3QkFBTyxlQUFlO0FBQUEsUUFDM0I7QUFBQSxNQUNELENBQUM7QUFBQSxJQUNILENBQUM7QUFHRixhQUFTLElBQUksR0FBRyxJQUFJLEtBQUssT0FBTyxTQUFTLHNCQUFzQixRQUFRLEtBQUs7QUFDM0UsVUFBSSxVQUFVLEtBQUssT0FBTyxTQUFTLHNCQUFzQjtBQUN6RCxVQUFJLFNBQVMsS0FBSyxPQUFPLFNBQVMsb0JBQW9CLEdBQUc7QUFDekQsVUFBSSxVQUFVLEtBQUssT0FBTyxTQUFTLG9CQUFvQixHQUFHO0FBQzFELFVBQUksVUFBVSxjQUFjLFVBQVUsYUFBUSxXQUFXLE1BQU0sSUFBSSxhQUFhLFdBQVcsT0FBTztBQUVsRyxVQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxPQUFPLEVBQ2YsZUFBZSxZQUFVO0FBQ3pCLGVBQU8sUUFBUSxNQUFNLEVBQ25CLFdBQVcsV0FBVyxFQUN0QixRQUFRLE1BQU07QUFDZCxjQUFJLG9CQUFvQixLQUFLLEtBQUssU0FBUSxRQUFRLFNBQVMsT0FBTyxVQUFVLGNBQWM7QUFDekYsaUJBQUssT0FBTywyQkFBMkIsR0FBRyxVQUFVLFNBQVM7QUFDN0Qsa0JBQU0sS0FBSyxPQUFPLGFBQWE7QUFDL0IsaUJBQUssUUFBUTtBQUFBLFVBQ2QsQ0FBQyxFQUFFLEtBQUs7QUFBQSxRQUNULENBQUM7QUFBQSxNQUNILENBQUMsRUFDQSxlQUFlLFlBQVU7QUFDekIsZUFBTyxRQUFRLE9BQU8sRUFDcEIsV0FBVyxhQUFhLEVBQ3hCLFFBQVEsWUFBWTtBQUNwQixlQUFLLE9BQU8sMkJBQTJCLENBQUM7QUFDeEMsZ0JBQU0sS0FBSyxPQUFPLGFBQWE7QUFDL0IsZUFBSyxRQUFRO0FBQUEsUUFDZCxDQUFDO0FBQUEsTUFDSCxDQUFDO0FBQUEsSUFDSDtBQUFBLEVBR0Q7QUFBQSxFQUVBLDJCQUEyQixhQUFnQztBQUMxRCxnQkFBWSxNQUFNO0FBQ1osZ0JBQVksV0FBVyxZQUFZO0FBQ3hDLFdBQUssT0FBTyxTQUFTLDBCQUEwQixZQUFZO0FBQzNELFlBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxJQUMxQjtBQUNOLFVBQU0sVUFBVSxZQUFZLFNBQVMsV0FBVyxFQUFDLEtBQUssNkJBQTRCLENBQUM7QUFDbkYsWUFBUSxRQUFRLDRGQUFxQztBQUVyRCxVQUFNLG9CQUFvQixJQUFJLHlCQUFRLFdBQVc7QUFDakQsc0JBQ0UsUUFBUSxhQUFhLEVBQ3JCLFFBQVEsOEpBQW9FO0FBRTlFLFVBQU0sZ0JBQWdCLElBQUksbUNBQWtCLGtCQUFrQixTQUFTO0FBQ3ZFLGtCQUFjLGVBQWUsZUFBZTtBQUU1QyxVQUFNLGVBQWUsSUFBSSxtQ0FBa0Isa0JBQWtCLFNBQVM7QUFDdEUsaUJBQWEsZUFBZSxhQUFhO0FBRXpDLHNCQUNFLFVBQVUsQ0FBQyxXQUFXO0FBQ3RCLGFBQ0UsY0FBYyxHQUFHLEVBQ2pCLFdBQVcsVUFBVSxFQUNyQixRQUFRLE9BQU8sYUFBa0I7QUFDakMsWUFBSSxTQUFTLGNBQWMsUUFBUTtBQUNuQyxZQUFJLFFBQVEsYUFBYSxRQUFRO0FBQ2pDLFlBQUksVUFBVSxPQUFPO0FBQ3BCLGNBQUksVUFBVTtBQUNkLGNBQUcsT0FBTyxPQUFPLE9BQU8sS0FBRyxNQUFJLE1BQU0sT0FBTyxPQUFPLEtBQUcsSUFBRztBQUN4RCxnQkFBSSx3QkFBTyxnRkFBaUY7QUFDNUY7QUFBQSxVQUNELE9BQ0k7QUFDSCxpQkFBSyxPQUFPLGtCQUFrQixRQUFRLEtBQUs7QUFDM0Msa0JBQU0sS0FBSyxPQUFPLGFBQWE7QUFDL0IsaUJBQUssUUFBUTtBQUFBLFVBQ2Q7QUFBQSxRQUNELE9BQ0s7QUFDSixjQUFJLHdCQUFPLGVBQWU7QUFBQSxRQUMzQjtBQUFBLE1BQ0QsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUVGLGFBQVMsSUFBSSxHQUFHLElBQUksS0FBSyxPQUFPLFNBQVMsdUJBQXVCLFFBQVEsS0FBSTtBQUMzRSxVQUFJLFNBQVMsS0FBSyxPQUFPLFNBQVMsdUJBQXVCLEdBQUc7QUFDNUQsVUFBSSxRQUFRLEtBQUssT0FBTyxTQUFTLHVCQUF1QixHQUFHO0FBQzNELFVBQUksVUFBVSxNQUFPLFdBQVcsTUFBTSxJQUFJLGtDQUE4QixXQUFXLEtBQUssSUFBRTtBQUMxRixVQUFJLHlCQUFRLFdBQVcsRUFDckIsUUFBUSxPQUFPLEVBQ2YsZUFBZSxZQUFVO0FBQ3pCLGVBQU8sUUFBUSxNQUFNLEVBQ25CLFdBQVcsV0FBVyxFQUN0QixRQUFRLE1BQU07QUFDZCxjQUFJLHFCQUFxQixLQUFLLEtBQUssNEJBQWlCLFFBQVEsT0FBTyxPQUFPLFlBQVksY0FBYztBQUNuRyxpQkFBSyxPQUFPLHFCQUFxQixHQUFHLFlBQVksU0FBUztBQUN6RCxrQkFBTSxLQUFLLE9BQU8sYUFBYTtBQUMvQixpQkFBSyxRQUFRO0FBQUEsVUFDZCxDQUFDLEVBQUUsS0FBSztBQUFBLFFBQ1QsQ0FBQztBQUFBLE1BQ0gsQ0FBQyxFQUNBLGVBQWUsWUFBVTtBQUN6QixlQUFPLFFBQVEsT0FBTyxFQUNwQixXQUFXLGFBQWEsRUFDeEIsUUFBUSxZQUFZO0FBQ3BCLGVBQUssT0FBTyxxQkFBcUIsQ0FBQztBQUNsQyxnQkFBTSxLQUFLLE9BQU8sYUFBYTtBQUMvQixlQUFLLFFBQVE7QUFBQSxRQUNkLENBQUM7QUFBQSxNQUNILENBQUM7QUFBQSxJQUNIO0FBQUEsRUFFRDtBQUFBLEVBRUEsNEJBQTRCLGFBQWdDO0FBQzNELGdCQUFZLE1BQU07QUFDWixnQkFBWSxXQUFXLFlBQVk7QUFDeEMsV0FBSyxPQUFPLFNBQVMsMEJBQTBCLFlBQVk7QUFDM0QsWUFBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLElBQzFCO0FBQ04sVUFBTSxVQUFVLFlBQVksU0FBUyxXQUFXLEVBQUMsS0FBSyw2QkFBNEIsQ0FBQztBQUNuRixZQUFRLFFBQVEsaUZBQW9DO0FBRXBELFVBQU0scUJBQXFCLElBQUkseUJBQVEsV0FBVztBQUNsRCx1QkFDRSxRQUFRLGNBQWMsRUFDdEIsUUFBUSw4SkFBb0U7QUFFOUUsVUFBTSxnQkFBZ0IsSUFBSSxtQ0FBa0IsbUJBQW1CLFNBQVM7QUFDeEUsa0JBQWMsZUFBZSxnQkFBZ0I7QUFFN0MsVUFBTSxlQUFlLElBQUksbUNBQWtCLG1CQUFtQixTQUFTO0FBQ3ZFLGlCQUFhLGVBQWUsYUFBYTtBQUV6Qyx1QkFDRSxVQUFVLENBQUMsV0FBVztBQUN0QixhQUNFLGNBQWMsR0FBRyxFQUNqQixXQUFXLFVBQVUsRUFDckIsUUFBUSxPQUFPLGFBQWtCO0FBQ2pDLFlBQUksU0FBUyxjQUFjLFFBQVE7QUFDbkMsWUFBSSxRQUFRLGFBQWEsUUFBUTtBQUNqQyxZQUFJLFVBQVUsT0FBTztBQUNwQixjQUFJLFVBQVU7QUFDZCxjQUFHLE9BQU8sT0FBTyxPQUFPLEtBQUcsTUFBSSxNQUFNLE9BQU8sT0FBTyxLQUFHLElBQUc7QUFDeEQsZ0JBQUksd0JBQU8sZ0ZBQWlGO0FBQzVGO0FBQUEsVUFDRCxPQUNJO0FBQ0gsaUJBQUssT0FBTyxtQkFBbUIsUUFBUSxLQUFLO0FBQzVDLGtCQUFNLEtBQUssT0FBTyxhQUFhO0FBQy9CLGlCQUFLLFFBQVE7QUFBQSxVQUNkO0FBQUEsUUFDRCxPQUNLO0FBQ0osY0FBSSx3QkFBTyxlQUFlO0FBQUEsUUFDM0I7QUFBQSxNQUNELENBQUM7QUFBQSxJQUNILENBQUM7QUFFRixhQUFTLElBQUksR0FBRyxJQUFJLEtBQUssT0FBTyxTQUFTLHdCQUF3QixRQUFRLEtBQUk7QUFDNUUsVUFBSSxTQUFTLEtBQUssT0FBTyxTQUFTLHdCQUF3QixHQUFHO0FBQzdELFVBQUksUUFBUSxLQUFLLE9BQU8sU0FBUyx3QkFBd0IsR0FBRztBQUM1RCxVQUFJLFVBQVUsTUFBTyxXQUFXLE1BQU0sSUFBSSx5QkFBMEIsV0FBVyxLQUFLLElBQUU7QUFDdEYsVUFBSSx5QkFBUSxXQUFXLEVBQ3JCLFFBQVEsT0FBTyxFQUNmLGVBQWUsWUFBVTtBQUN6QixlQUFPLFFBQVEsTUFBTSxFQUNuQixXQUFXLFdBQVcsRUFDdEIsUUFBUSxNQUFNO0FBQ2QsY0FBSSxxQkFBcUIsS0FBSyxLQUFLLDhCQUFrQixRQUFRLE9BQU8sT0FBTyxZQUFZLGNBQWM7QUFDcEcsaUJBQUssT0FBTyxzQkFBc0IsR0FBRyxZQUFZLFNBQVM7QUFDMUQsa0JBQU0sS0FBSyxPQUFPLGFBQWE7QUFDL0IsaUJBQUssUUFBUTtBQUFBLFVBQ2QsQ0FBQyxFQUFFLEtBQUs7QUFBQSxRQUNULENBQUM7QUFBQSxNQUNILENBQUMsRUFDQSxlQUFlLFlBQVU7QUFDekIsZUFBTyxRQUFRLE9BQU8sRUFDcEIsV0FBVyxhQUFhLEVBQ3hCLFFBQVEsWUFBWTtBQUNwQixlQUFLLE9BQU8sc0JBQXNCLENBQUM7QUFDbkMsZ0JBQU0sS0FBSyxPQUFPLGFBQWE7QUFDL0IsZUFBSyxRQUFRO0FBQUEsUUFDZCxDQUFDO0FBQUEsTUFDSCxDQUFDO0FBQUEsSUFDSDtBQUFBLEVBQ0Q7QUFFRDtBQUdBLHVCQUF1QixTQUFjLFlBQWlCO0FBQ3JELFdBQVMsT0FBTyxZQUFZO0FBQzNCLFlBQVEsYUFBYSxLQUFLLFdBQVcsSUFBSTtBQUFBLEVBQzFDO0FBQ0Q7QUFHTyxJQUFNLHNCQUFOLGNBQWtDLHVCQUFNO0FBQUEsRUFROUMsWUFBWSxLQUFVLFNBQWlCLE1BQWMsT0FBZSxVQUF3RDtBQUMzSCxVQUFNLEdBQUc7QUFDVCxTQUFLLFVBQVU7QUFDZixTQUFLLFdBQVc7QUFDaEIsU0FBSyxZQUFZO0FBQ2pCLFNBQUssV0FBVztBQUNoQixTQUFLLFlBQVk7QUFFakIsU0FBSyxXQUFXO0FBQUEsRUFDakI7QUFBQSxFQUVBLFNBQVM7QUFDUixVQUFNLEVBQUUsY0FBYztBQUV0QixjQUFVLFNBQVMsTUFBTSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFaEUsUUFBSSx5QkFBUSxTQUFTLEVBQ25CLFFBQVEsU0FBUyxFQUNqQixRQUFRLENBQUMsU0FBUztBQUNsQixXQUFLLFNBQVMsS0FBSyxPQUFPO0FBQzFCLFdBQUssWUFBWSxJQUFJO0FBQUEsSUFDdEIsQ0FBQztBQUVGLFFBQUkseUJBQVEsU0FBUyxFQUNuQixRQUFRLE1BQU0sRUFDZCxZQUFZLENBQUMsU0FBUztBQUN0QixXQUFLLFNBQVMsS0FBSyxRQUFRO0FBQzNCLFdBQUssU0FBUyxDQUFDLFVBQVU7QUFDeEIsYUFBSyxXQUFXO0FBQUEsTUFDakIsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUNGLFFBQUkseUJBQVEsU0FBUyxFQUNuQixRQUFRLE9BQU8sRUFDZixZQUFZLENBQUMsU0FBUztBQUN0QixXQUFLLFNBQVMsS0FBSyxTQUFTO0FBQzVCLFdBQUssU0FBUyxDQUFDLFVBQVU7QUFDeEIsYUFBSyxZQUFZO0FBQUEsTUFDbEIsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUdGLFFBQUkseUJBQVEsU0FBUyxFQUNuQixVQUFVLENBQUMsUUFDWCxJQUNFLGNBQWMsUUFBUSxFQUN0QixPQUFPLEVBQ1AsUUFBUSxNQUFNO0FBQ2QsV0FBSyxNQUFNO0FBQ1gsV0FBSyxTQUFTLEtBQUssVUFBVSxLQUFLLFNBQVM7QUFBQSxJQUM1QyxDQUFDLENBQUM7QUFBQSxFQUNOO0FBQUEsRUFFQSxVQUFVO0FBQ1QsUUFBSSxFQUFFLGNBQWM7QUFDcEIsY0FBVSxNQUFNO0FBQUEsRUFDakI7QUFDRDtBQUlPLElBQU0sdUJBQU4sY0FBbUMsdUJBQU07QUFBQSxFQVEvQyxZQUFZLEtBQVUsTUFBZ0IsUUFBZ0IsT0FBZSxVQUEwRDtBQUM5SCxVQUFNLEdBQUc7QUFDVCxTQUFLLE9BQU87QUFDWixTQUFLLGFBQWE7QUFDbEIsU0FBSyxZQUFZO0FBQ2pCLFNBQUssYUFBYTtBQUNsQixTQUFLLFlBQVk7QUFFakIsU0FBSyxXQUFXO0FBQUEsRUFDakI7QUFBQSxFQUVBLFNBQVM7QUFDUixVQUFNLEVBQUUsY0FBYztBQUV0QixjQUFVLFNBQVMsTUFBTSxFQUFFLE1BQU0sVUFBVSxLQUFLLEtBQUksQ0FBQztBQUVyRCxRQUFJLHlCQUFRLFNBQVMsRUFDbkIsUUFBUSxhQUFhLEVBQ3JCLFlBQVksQ0FBQyxTQUFTO0FBQ3RCLFdBQUssU0FBUyxLQUFLLFVBQVU7QUFDN0IsV0FBSyxTQUFTLENBQUMsVUFBVTtBQUN4QixhQUFLLGFBQWE7QUFBQSxNQUNuQixDQUFDO0FBQUEsSUFDRixDQUFDO0FBQ0YsUUFBSSx5QkFBUSxTQUFTLEVBQ25CLFFBQVEsYUFBYSxFQUNyQixZQUFZLENBQUMsU0FBUztBQUN0QixXQUFLLFNBQVMsS0FBSyxTQUFTO0FBQzVCLFdBQUssU0FBUyxDQUFDLFVBQVU7QUFDeEIsYUFBSyxZQUFZO0FBQUEsTUFDbEIsQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUdGLFFBQUkseUJBQVEsU0FBUyxFQUNuQixVQUFVLENBQUMsUUFDWCxJQUNFLGNBQWMsUUFBUSxFQUN0QixPQUFPLEVBQ1AsUUFBUSxNQUFNO0FBQ2QsVUFBSSxLQUFLLDBCQUEwQixLQUFLLFlBQVksS0FBSyxTQUFTLEdBQ2xFO0FBQ0MsYUFBSyxNQUFNO0FBQ1gsYUFBSyxTQUFTLEtBQUssWUFBWSxLQUFLLFNBQVM7QUFBQSxNQUM5QyxPQUNJO0FBQ0gsWUFBSSx3QkFBTyx5QkFBeUI7QUFBQSxNQUNyQztBQUFBLElBRUQsQ0FBQyxDQUFDO0FBQUEsRUFDTjtBQUFBLEVBRUEsMEJBQTBCLFFBQWdCLE9BQXFCO0FBQzlELFFBQUksVUFBVTtBQUNkLFFBQUcsT0FBTyxPQUFPLE9BQU8sS0FBRyxNQUFNLE1BQU0sT0FBTyxPQUFPLEtBQUc7QUFBSSxhQUFPO0FBQ25FLFdBQU87QUFBQSxFQUNSO0FBQUEsRUFFQSxVQUFVO0FBQ1QsUUFBSSxFQUFFLGNBQWM7QUFDcEIsY0FBVSxNQUFNO0FBQUEsRUFDakI7QUFDRDs7O0FIMTFCQSxrQkFBNkM7QUFTN0MsdUJBQTJDOzs7QUlaM0MsdUJBQTZDO0FBWXRDLDBCQUEwQixPQUFvQixLQUFzQjtBQUN2RSxNQUFJLGlCQUFpQixtQkFBbUIsS0FBSztBQUM3QyxXQUFTLElBQUksR0FBRyxJQUFJLGVBQWUsUUFBUSxLQUFLO0FBQzVDLFFBQUksT0FBTyxlQUFlLEdBQUcsYUFBYSxPQUFPLGVBQWUsR0FBRyxTQUFTO0FBQ3hFLGFBQU87QUFBQSxJQUNYO0FBQUEsRUFDSjtBQUNBLFNBQU87QUFDWDtBQVlPLDhCQUE4QixNQUFrQixLQUFxQjtBQUN4RSxNQUFJLGlCQUFpQixtQkFBbUIsS0FBSyxLQUFLO0FBQ2xELFdBQVMsSUFBSSxHQUFHLElBQUksZUFBZSxRQUFRLEtBQUs7QUFDNUMsUUFBSSxPQUFPLGVBQWUsR0FBRyxhQUFhLE9BQU8sZUFBZSxHQUFHLFNBQVM7QUFDeEUsV0FBSyxTQUFTO0FBQUEsUUFDVixXQUFXO0FBQUEsVUFDUCxRQUFRLGVBQWUsR0FBRztBQUFBLFVBQzFCLE1BQU0sZUFBZSxHQUFHO0FBQUEsUUFDNUI7QUFBQSxNQUNKLENBQUM7QUFDRCxhQUFPO0FBQUEsSUFDWDtBQUFBLEVBQ0o7QUFDQSxTQUFPO0FBQ1g7QUFFTyw0QkFBNEIsT0FBb0M7QUFDbkUsTUFBSSxtQkFBbUI7QUFDdkIsTUFBSSxpQkFBa0MsQ0FBQztBQUN2QyxNQUFJLG1CQUF5QztBQUM3QyxRQUFNLE1BQU0sTUFBTTtBQUVsQixtQ0FBVyxLQUFLLEVBQUUsUUFBUTtBQUFBLElBQ3RCLE1BQU0sTUFBTTtBQUNSLFlBQU0sV0FBVyxLQUFLO0FBQ3RCLFlBQU0sV0FBVyxLQUFLO0FBQ3RCLFlBQU0sU0FBUyxLQUFLO0FBQ3BCLFlBQU0sV0FBVyxNQUFNLFNBQVMsVUFBVSxNQUFNO0FBRWhELFVBQUksU0FBUyxTQUFTLGlCQUFpQixHQUFHO0FBQ3RDLDJCQUFtQjtBQUNuQixZQUFJLFlBQVksV0FBVyxTQUFTLFFBQVEsR0FBRztBQUMvQyxZQUFJLFNBQVMsWUFBWSxNQUFNLElBQUksT0FBTyxTQUFTLEVBQUU7QUFDckQsWUFBSSxXQUFXLFNBQVMsS0FBSyxFQUFFLFVBQVUsQ0FBQztBQUMxQywyQkFBbUI7QUFBQSxVQUNmO0FBQUEsVUFDQSxTQUFTO0FBQUEsVUFDVCxnQkFBZ0I7QUFBQSxVQUNoQixjQUFjO0FBQUEsVUFDZDtBQUFBLFVBQ0E7QUFBQSxRQUNKO0FBQUEsTUFDSixXQUFXLFNBQVMsU0FBUyxlQUFlLEdBQUc7QUFDM0MsMkJBQW1CO0FBQ25CLFlBQUksb0JBQW9CLE1BQU07QUFDMUIsMkJBQWlCLFVBQVU7QUFDM0IsY0FBSSxJQUFJLE9BQU8saUJBQWlCLFNBQVMsRUFBRSxVQUN2QyxJQUFJLE9BQU8saUJBQWlCLE9BQU8sRUFBRSxTQUFTLEdBQUc7QUFDakQsNkJBQWlCLGlCQUFpQixJQUFJLE9BQU8saUJBQWlCLFNBQVMsRUFBRTtBQUN6RSw2QkFBaUIsZUFBZSxJQUFJLE9BQU8saUJBQWlCLFNBQVMsRUFBRTtBQUFBLFVBQzNFLE9BQ0s7QUFDRCxnQkFBSSxrQkFBa0IsSUFBSSxPQUFPLGlCQUFpQixTQUFTLEVBQUUsU0FBUztBQUN0RSxnQkFBSSxnQkFBZ0IsSUFBSSxPQUFPLGlCQUFpQixPQUFPLEVBQUUsU0FBUztBQUNsRSw2QkFBaUIsaUJBQWlCLElBQUksS0FBSyxlQUFlLEVBQUUsT0FBTyxpQkFBaUI7QUFDcEYsNkJBQWlCLGVBQWUsSUFBSSxLQUFLLGFBQWEsRUFBRTtBQUFBLFVBQzVEO0FBQ0EseUJBQWUsS0FBSyxnQkFBZ0I7QUFDcEMsNkJBQW1CO0FBQUEsUUFDdkI7QUFBQSxNQUNKO0FBQUEsSUFDSjtBQUFBLEVBQ0osQ0FBQztBQUVELE1BQUksb0JBQW9CLGtCQUFrQjtBQUN0QyxxQkFBaUIsVUFBVSxJQUFJO0FBQy9CLHFCQUFpQixlQUFlLElBQUk7QUFDcEMsUUFBSSxJQUFJLFFBQVEsSUFBSSxPQUFPLGlCQUFpQixTQUFTLEVBQUUsUUFBUTtBQUMzRCxVQUFJLGFBQWEsSUFBSSxPQUFPLGlCQUFpQixTQUFTLEVBQUUsU0FBUztBQUNqRSxVQUFJLGlCQUFpQixJQUFJLEtBQUssVUFBVSxFQUFFLE9BQU8saUJBQWlCO0FBQ2xFLHVCQUFpQixpQkFBaUIsaUJBQWlCLElBQUksU0FBUyxpQkFDNUQsSUFBSSxPQUFPLGlCQUFpQixZQUFZLENBQUMsRUFBRTtBQUFBLElBQ25ELE9BQ0s7QUFDRCx1QkFBaUIsaUJBQWlCLElBQUksT0FBTyxpQkFBaUIsU0FBUyxFQUFFO0FBQUEsSUFDN0U7QUFDQSxtQkFBZSxLQUFLLGdCQUFnQjtBQUNwQyx1QkFBbUI7QUFBQSxFQUN2QjtBQUNBLFNBQU87QUFDWDs7O0FKaEdBLElBQXFCLG1CQUFyQixjQUE4Qyx3QkFBTztBQUFBLEVBQXJEO0FBQUE7QUEyT0MsZ0NBQXVCLE1BQU07QUFDNUIsVUFBSSxpQkFBaUIsS0FBSyxJQUFJLE1BQU0sT0FBTyxTQUFTLE1BQU8sSUFBSSxPQUFPLEtBQUssSUFBSSxNQUFNLE9BQU8sT0FBTztBQUNuRyxhQUFPO0FBQUEsSUFDUjtBQUVBLG1DQUEwQixDQUFDLE9BQWtFO0FBQzVGLFlBQU0sVUFBNkIsQ0FBQztBQUNwQyxVQUFJLENBQUMsR0FBRztBQUFZLGVBQU87QUFDM0IsVUFBSSxXQUFXLEdBQUcsV0FBVyxVQUFVLFNBQVMsRUFBRSxLQUFLLFVBQVUsR0FBRyxXQUFXLFVBQVUsU0FBUyxFQUFFLEtBQUs7QUFFekcsVUFBSSxnQkFBZ0Isb0JBQW9CLEVBQUU7QUFFMUMsU0FBRyxRQUFRLFlBQVksQ0FBQyxPQUFPLEtBQUssT0FBTyxLQUFLLGFBQWE7QUF2US9EO0FBd1FHLFlBQUksYUFBYSxHQUFHLFdBQVcsU0FBUyxPQUFPLEdBQUc7QUFDbEQsWUFBSSxhQUFhLFdBQVcsUUFBUSxPQUFPLEdBQUc7QUFDOUMsWUFBSSxjQUFjLFNBQVMsWUFBWSxDQUFDO0FBQ3hDLFlBQUksS0FBSyxTQUFTLE9BQ2xCO0FBQ0Msa0JBQVEsSUFBSSxxRUFBcUU7QUFDakYsa0JBQVEsSUFBSSxlQUFlLE9BQU8sS0FBSyxZQUFXLE9BQU8sS0FBSyxXQUFXO0FBQUEsUUFDMUU7QUFHQSxZQUFJLGVBQWUsR0FBRyxZQUFZLEtBQUssS0FBRztBQUFnQixpQkFBTztBQUdqRSxZQUFJLEtBQUssU0FBUyxrQkFBa0I7QUFDbkMsY0FBSyxrQkFBaUIsZ0JBQWdCLGlCQUFpQix5QkFBeUIsU0FBUyxPQUFTLFNBQVEsTUFBTSxPQUFNLGVBQWEsa0JBQU0sZUFBYSxpQkFBTztBQUM1SixnQkFBSSxLQUFLLG9CQUFvQixJQUFJLFdBQVcsR0FBRztBQUM5QyxzQkFBUSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sT0FBTyxRQUFRLFdBQUssb0JBQW9CLElBQUksV0FBVyxNQUF4QyxtQkFBMkMsS0FBSyxHQUFHLFdBQVcsb0JBQW9CLENBQUM7QUFDbEksc0JBQVEsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEtBQUssUUFBUSxXQUFLLG9CQUFvQixJQUFJLFdBQVcsTUFBeEMsbUJBQTJDLE1BQU0sR0FBRyxXQUFXLG9CQUFvQixDQUFDO0FBQ2pJLG1CQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxxQkFBTztBQUFBLFlBQ1I7QUFBQSxVQUNEO0FBQUEsUUFDRDtBQUdBLFlBQUksS0FBSyxTQUFTLGtCQUFrQixjQUFjLFNBQVMsT0FBTyxLQUFLLFNBQU8sU0FDNUUsaUJBQWlCLEdBQUcsWUFBWSxLQUFLLEdBQUU7QUFDeEMsZ0JBQU0sOERBQVk7QUFDbEIsY0FBSSxPQUFPLEdBQUcsV0FBVyxJQUFJLE9BQU8sS0FBSyxFQUFFO0FBQzNDLGNBQUksZUFBZSxLQUFLLE1BQU0sTUFBTSxFQUFFLEdBQUc7QUFDekMsY0FBSSxpQkFBaUIsWUFBWSxNQUFNLElBQUk7QUFDM0MsY0FBSSxlQUFlO0FBQ25CLGNBQUcsZUFBZSxTQUFPLEdBQUU7QUFDMUIsZ0JBQUksYUFBYSxlQUFlLEdBQUcsVUFBVTtBQUM3QyxnQkFBSSxXQUFXLFNBQVMsR0FBRyxLQUFLLFdBQVcsU0FBUyxHQUFHLEtBQUssV0FBVyxTQUFTLEdBQUcsR0FBRTtBQUNwRiw2QkFBZSxLQUFLLHFCQUFxQjtBQUFBLFlBQzFDO0FBQ0EsZ0JBQUksYUFBYSxlQUFlLE1BQU0sQ0FBQztBQUV2QyxnQkFBSSxtQkFBbUI7QUFDdkIscUJBQVMsU0FBUSxZQUFXO0FBQzNCLGtCQUFJLFNBQVMsTUFBSyxNQUFNLE1BQU0sRUFBRSxHQUFHO0FBQ25DLGtCQUFJLENBQUMsUUFBUSxLQUFLLEtBQUksS0FBSyxTQUFPO0FBQWtCLG1DQUFtQjtBQUFBLFlBQ3hFO0FBQ0EsZ0JBQUksaUJBQWlCLFdBQVcsSUFBSSxDQUFDLFVBQWMsTUFBSyxVQUFVLGdCQUFnQixDQUFDO0FBRW5GLDZCQUFpQixlQUFlLElBQy9CLENBQUMsVUFBYyxNQUFLLFFBQVEsU0FBUyxLQUFLLHFCQUFxQixDQUFDLENBQUM7QUFDbEUsZ0JBQUksbUJBQW1CLGVBQWUsSUFBSSxDQUFDLFVBQWMsSUFBSSxPQUFPLFlBQVksSUFBRSxlQUFhLEtBQUk7QUFDbkcsZ0JBQUksa0JBQWtCLGFBQVcsT0FBSyxpQkFBaUIsS0FBSyxJQUFJO0FBQ2hFLG9CQUFRLEtBQUs7QUFBQSxjQUNaLFNBQVMsRUFBQyxNQUFNLE9BQU8sSUFBSSxLQUFLLFFBQVEsZ0JBQWU7QUFBQSxjQUN2RCxXQUFXLEVBQUMsUUFBUSxRQUFNLGdCQUFnQixPQUFNO0FBQUEsY0FDaEQsV0FBVztBQUFBLFlBQ1osQ0FBQztBQUNELGlCQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxtQkFBTztBQUFBLFVBQ1I7QUFBQSxRQUNEO0FBRUEsWUFBSTtBQUFVLGlCQUFPO0FBTXJCLFlBQUksS0FBSyxTQUFTLGVBQ2pCLGlCQUFpQix3QkFDakIsY0FBYyxNQUFNLHFCQUFxQixLQUFLLFdBQVcsR0FBRTtBQUMzRCxnQkFBTSw0QkFBNEIsV0FBVztBQUM3QyxlQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxpQkFBTztBQUFBLFFBQ1I7QUFHQSxZQUFJLEtBQUssU0FBUyxrQkFBa0IsaUJBQWlCLHFCQUFxQixDQUFDLFlBQzFFLGVBQWUsR0FBRyxZQUFZLEdBQUcsS0FBSywrQkFDckMsSUFBRyxXQUFXLFNBQVMsT0FBTSxHQUFHLEtBQUcsT0FBTyxlQUFlLEdBQUcsT0FBTyxLQUFLLEtBQUcsOEJBQXFCO0FBQ2pHLGNBQUksY0FBYyxHQUFHLFdBQVcsSUFBSSxPQUFPLEdBQUcsRUFBRTtBQUNoRCxjQUFJLFdBQVcsR0FBRyxXQUFXLElBQUksT0FBTyxHQUFHO0FBQzNDLGNBQUksWUFBWTtBQUNoQixjQUFJLG1CQUFtQjtBQUN2QixtQkFBUyxJQUFJLGNBQWMsR0FBRyxLQUFLLEdBQUcsS0FBSztBQUMxQyxnQkFBSSxPQUFPLEdBQUcsV0FBVyxJQUFJLEtBQUssQ0FBQztBQUNuQyxnQkFBSSxVQUFVLEtBQUssS0FBSyxJQUFJLEdBQUc7QUFDOUIsMEJBQVk7QUFDWixpQ0FBbUIsS0FBSyxLQUFLLE1BQU0sTUFBTSxFQUFFLEdBQUc7QUFDOUM7QUFBQSxZQUNELFdBQ1MsT0FBTyxLQUFLLEtBQUssSUFBSTtBQUFHO0FBQUE7QUFDNUI7QUFBQSxVQUNOO0FBRUEsY0FBSSxXQUFXO0FBQ2Qsa0JBQU0sdUJBQXVCLGdCQUFnQjtBQUM3QyxnQkFBSSxPQUFPLFNBQVMsT0FBTyxrQkFBa0I7QUFDNUMsc0JBQVEsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEdBQUcsV0FBVyxJQUFJLEtBQUssY0FBWSxDQUFDLEVBQUUsSUFBSSxJQUFJLEtBQUssUUFBUSxHQUFHLEdBQUcsV0FBVyxvQkFBb0IsQ0FBQztBQUNqSSxtQkFBSyxHQUFHLFdBQVcsT0FBTyxHQUFHLE9BQU87QUFDcEMscUJBQU87QUFBQSxZQUNSO0FBQ0EsZ0JBQUksU0FBTyxTQUFTLFFBQVEsUUFBUSxTQUFTLE9BQUssb0JBQW9CLE1BQUksU0FBUyxPQUFLLGtCQUFpQjtBQUN4RyxzQkFBUSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxPQUFLLGtCQUFrQixJQUFJLEtBQUssUUFBUSxHQUFHLEdBQUcsV0FBVyxvQkFBb0IsQ0FBQztBQUN2SCxtQkFBSyxHQUFHLFdBQVcsT0FBTyxHQUFHLE9BQU87QUFDcEMscUJBQU87QUFBQSxZQUNSO0FBQUEsVUFDRDtBQUFBLFFBQ0Q7QUFHQSxZQUFJLGlCQUFpQixtQkFBbUI7QUFDdkMsbUJBQVMsUUFBUSxLQUFLLGlCQUFpQjtBQUN0QyxnQkFBSSxPQUFPLEdBQUcsV0FBVyxJQUFJLFlBQVksTUFBTSxLQUFLLE9BQU8sS0FBSyxRQUFRLEdBQUc7QUFDM0UsZ0JBQUksUUFBUSxHQUFHLFdBQVcsSUFBSSxZQUFZLEtBQUssTUFBTSxLQUFLLE9BQU8sTUFBTSxNQUFNO0FBQzdFLGdCQUFJLFNBQVMsS0FBSyxPQUFPLFFBQVEsVUFBVSxLQUFLLE9BQU8sT0FBTztBQUM3RCxzQkFBUSxLQUFLO0FBQUEsZ0JBQ1osU0FBUztBQUFBLGtCQUNSLE1BQU0sTUFBTSxLQUFLLE9BQU8sS0FBSztBQUFBLGtCQUM3QixJQUFJLE1BQU0sS0FBSyxPQUFPLE1BQU07QUFBQSxrQkFDNUIsUUFBUSxLQUFLLE1BQU0sT0FBTyxLQUFLLE1BQU07QUFBQSxnQkFDdEM7QUFBQSxnQkFDQSxXQUFXLEVBQUUsUUFBUSxNQUFNLEtBQUssT0FBTyxLQUFLLFNBQVMsS0FBSyxNQUFNLEtBQUssT0FBTztBQUFBLGdCQUM1RSxXQUFXO0FBQUEsY0FDWixDQUFDO0FBQ0QsbUJBQUssR0FBRyxXQUFXLE9BQU8sR0FBRyxPQUFPO0FBQ3BDLHFCQUFPO0FBQUEsWUFDUjtBQUFBLFVBQ0Q7QUFBQSxRQUNEO0FBR0EsWUFBSSxrQkFBa0IscUJBQXFCLEtBQUssU0FBUyxzQkFBc0I7QUFDOUUsY0FBSSxLQUFLLGVBQWUsSUFBSSxVQUFVLEtBQUssS0FBSyxlQUFlLElBQUksVUFBVSxNQUFNLEdBQUcsV0FBVyxTQUFTLEtBQUssTUFBTSxDQUFDLEdBQUc7QUFDeEgsb0JBQVEsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLE9BQU8sSUFBSSxNQUFNLEVBQUUsR0FBRyxXQUFXLG9CQUFvQixDQUFDO0FBQ3RGLGlCQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxtQkFBTztBQUFBLFVBQ1I7QUFHQSxjQUFJLGVBQWUsR0FBRyxXQUFXLElBQUksT0FBTyxHQUFHLEVBQUU7QUFDakQsY0FBSSxvQkFBb0IsR0FBRyxXQUFXLElBQUksWUFBWSxLQUFLLE1BQU0sYUFBYSxTQUFPLENBQUM7QUFDdEYsY0FBSSxXQUFXLEtBQUssWUFBWSxLQUFLLE9BQUssZ0JBQWMsbUJBQW1CO0FBQzFFLG9CQUFRLEtBQUs7QUFBQSxjQUNaLFNBQVE7QUFBQSxnQkFDUCxNQUFNLE1BQUk7QUFBQSxnQkFDVixJQUFJLE1BQUksYUFBYSxTQUFPO0FBQUEsZ0JBQzVCLFFBQVE7QUFBQSxjQUNUO0FBQUEsY0FDQSxXQUFXLEVBQUUsUUFBUSxNQUFNLEVBQUU7QUFBQSxjQUM3QixXQUFXO0FBQUEsWUFDWixDQUFDO0FBQ0QsaUJBQUssR0FBRyxXQUFXLE9BQU8sR0FBRyxPQUFPO0FBQ3BDLG1CQUFPO0FBQUEsVUFDUjtBQUVBLG1CQUFTLFFBQVEsS0FBSyxzQkFBc0I7QUFDM0MsZ0JBQUksT0FBTyxHQUFHLFdBQVcsSUFBSSxZQUFZLE1BQU0sS0FBSyxPQUFPLEtBQUssUUFBUSxHQUFHO0FBQzNFLGdCQUFJLFFBQVEsR0FBRyxXQUFXLElBQUksWUFBWSxLQUFLLE1BQU0sS0FBSyxPQUFPLE1BQU0sTUFBTTtBQUM3RSxnQkFBSSxTQUFTLEtBQUssT0FBTyxRQUFRLFVBQVUsS0FBSyxPQUFPLE9BQU87QUFDN0Qsc0JBQVEsS0FBSztBQUFBLGdCQUNaLFNBQVM7QUFBQSxrQkFDUixNQUFNLE1BQU0sS0FBSyxPQUFPLEtBQUs7QUFBQSxrQkFDN0IsSUFBSSxNQUFNLEtBQUssT0FBTyxNQUFNO0FBQUEsa0JBQzVCLFFBQVEsS0FBSyxNQUFNLE9BQU8sS0FBSyxNQUFNO0FBQUEsZ0JBQ3RDO0FBQUEsZ0JBQ0EsV0FBVyxFQUFFLFFBQVEsTUFBTSxLQUFLLE9BQU8sS0FBSyxTQUFTLEtBQUssTUFBTSxLQUFLLE9BQU87QUFBQSxnQkFDNUUsV0FBVztBQUFBLGNBQ1osQ0FBQztBQUNELG1CQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxxQkFBTztBQUFBLFlBQ1I7QUFBQSxVQUNEO0FBQUEsUUFDRDtBQUdBLFlBQUksaUJBQWlCLGdCQUFnQixlQUFjLFlBQVksS0FBSyxTQUFTLG1CQUFrQjtBQUM5RixnQkFBTSxlQUFlLEdBQUcsV0FBVyxJQUFJLE9BQU8sS0FBSyxFQUFFO0FBQ3JELGNBQUksVUFBVSxLQUFLLFlBQVksR0FBRTtBQUNoQyxvQkFBUSxLQUFLO0FBQUEsY0FDWixTQUFTLEVBQUMsTUFBTSxPQUFPLElBQUksS0FBSyxRQUFRLFFBQU0sZUFBYSxJQUFHO0FBQUEsY0FDOUQsV0FBVyxFQUFFLFFBQVEsUUFBUSxFQUFFO0FBQUEsY0FDL0IsV0FBVztBQUFBLFlBQ1osQ0FBQztBQUNELGlCQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxtQkFBTztBQUFBLFVBQ1I7QUFBQSxRQUNEO0FBR0EsWUFBSyxrQkFBaUIsZ0JBQWdCLGlCQUFpQix5QkFBeUIsVUFBVSxPQUFPLFFBQVEsTUFBTSxLQUFLO0FBSW5ILGNBQUksS0FBSyxTQUFTLG1CQUFtQjtBQUVwQyxnQkFBSSxnQkFBZ0IsT0FDbkIsTUFBSSxHQUFHLFdBQVcsSUFBSSxPQUFPLEdBQUcsRUFBRSxPQUFLLEtBQ3ZDLEdBQUcsV0FBVyxTQUFTLE1BQUksR0FBRyxHQUFHLE1BQU0sT0FDcEMsR0FBRyxXQUFXLFNBQVMsTUFBSSxHQUFHLE1BQUksQ0FBQyxLQUFLLEtBQUk7QUFDL0Msc0JBQVEsS0FBSztBQUFBLGdCQUNaLFNBQVMsRUFBQyxNQUFLLEtBQUssUUFBTyxJQUFHO0FBQUEsZ0JBQzlCLFdBQVcsRUFBRSxRQUFRLElBQUk7QUFBQSxnQkFBRyxXQUFXO0FBQUEsY0FDeEMsQ0FBQztBQUNELG1CQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyxxQkFBTztBQUFBLFlBQ1I7QUFHQSxnQkFBSSxlQUFlLFFBQUk7QUFDdEIsa0JBQUksZUFBZSxHQUFHLFdBQVcsSUFBSSxPQUFPLEtBQUssRUFBRTtBQUNuRCxrQkFBSSxTQUFTLFFBQVEsR0FBRyxXQUFXLElBQUksT0FBTyxLQUFLLEVBQUU7QUFDckQsa0JBQUksVUFBVSxLQUFLLFlBQVksS0FBSyxVQUFRLGFBQWEsU0FBTyxHQUFFO0FBQ2pFLHdCQUFRLEtBQUs7QUFBQSxrQkFDWixTQUFTLEVBQUMsTUFBTSxRQUFNLEdBQUcsSUFBSSxNQUFJLEdBQUcsUUFBUSxRQUFNLGVBQWEsSUFBRztBQUFBLGtCQUNsRSxXQUFXLEVBQUUsUUFBUSxRQUFRLEVBQUU7QUFBQSxrQkFDL0IsV0FBVztBQUFBLGdCQUNaLENBQUM7QUFDRCxxQkFBSyxHQUFHLFdBQVcsT0FBTyxHQUFHLE9BQU87QUFDcEMsdUJBQU87QUFBQSxjQUNSO0FBQUEsWUFDRDtBQUVBLHFCQUFTLFFBQVEsS0FBSyxnQkFBZ0I7QUFDckMsa0JBQUksZUFBZSxLQUFLLE9BQU8sS0FBSyxPQUFPLEtBQUssT0FBTyxLQUFLLFNBQVMsQ0FBQztBQUFHO0FBRXpFLGtCQUFJLEtBQUssT0FBTyxLQUFLLE9BQU8sQ0FBQyxNQUFNLFFBQVEsWUFBWSxHQUFHLE1BQU0sS0FBSyxLQUFLLEVBQUUsU0FBUyxLQUFLLE1BQU0sS0FBSyxPQUFPLEtBQUssU0FBUyxNQUFNLEdBQUc7QUFDbEksb0JBQUksT0FBTyxHQUFHLE1BQU0sSUFBSSxZQUFZLE1BQU0sS0FBSyxPQUFPLEtBQUssU0FBUyxHQUFHLEdBQUc7QUFDMUUsb0JBQUksUUFBUSxHQUFHLE1BQU0sSUFBSSxZQUFZLEtBQUssTUFBTSxLQUFLLE9BQU8sTUFBTSxNQUFNO0FBQ3hFLG9CQUFJLFNBQVMsS0FBSyxPQUFPLEtBQUssVUFBVSxDQUFDLEtBQUssVUFBVSxLQUFLLE9BQU8sT0FBTztBQUMxRSwwQkFBUSxLQUFLO0FBQUEsb0JBQ1osU0FBUztBQUFBLHNCQUNSLE1BQU0sTUFBTSxLQUFLLE9BQU8sS0FBSyxTQUFTO0FBQUEsc0JBQ3RDLElBQUksTUFBTSxLQUFLLE9BQU8sTUFBTTtBQUFBLHNCQUM1QixRQUFRLEtBQUssTUFBTSxLQUFLLFVBQVUsQ0FBQyxJQUFJLEtBQUssTUFBTTtBQUFBLG9CQUNuRDtBQUFBLG9CQUNBLFdBQVcsRUFBRSxRQUFRLE1BQU0sS0FBSyxPQUFPLEtBQUssU0FBUyxLQUFLLE1BQU0sS0FBSyxTQUFTLEVBQUU7QUFBQSxvQkFDaEYsV0FBVztBQUFBLGtCQUNaLENBQUM7QUFDRCx1QkFBSyxHQUFHLFdBQVcsT0FBTyxHQUFHLE9BQU87QUFDcEMseUJBQU87QUFBQSxnQkFDUjtBQUFBLGNBQ0QsT0FFSztBQUNKLG9CQUFJLE9BQU8sR0FBRyxNQUFNLElBQUksWUFBWSxNQUFNLEtBQUssT0FBTyxLQUFLLFFBQVEsR0FBRztBQUN0RSxvQkFBSSxRQUFRLEdBQUcsTUFBTSxJQUFJLFlBQVksS0FBSyxNQUFNLEtBQUssT0FBTyxNQUFNLE1BQU07QUFDeEUsb0JBQUksU0FBUyxLQUFLLE9BQU8sUUFBUSxVQUFVLEtBQUssT0FBTyxPQUFPO0FBQzdELDBCQUFRLEtBQUs7QUFBQSxvQkFDWixTQUFTO0FBQUEsc0JBQ1IsTUFBTSxNQUFNLEtBQUssT0FBTyxLQUFLLFNBQVM7QUFBQSxzQkFDdEMsSUFBSSxNQUFNLEtBQUssT0FBTyxNQUFNO0FBQUEsc0JBQzVCLFFBQVEsS0FBSyxNQUFNLE9BQU8sS0FBSyxNQUFNO0FBQUEsb0JBQ3RDO0FBQUEsb0JBQ0EsV0FBVyxFQUFFLFFBQVEsTUFBTSxLQUFLLE9BQU8sS0FBSyxTQUFTLEtBQUssTUFBTSxLQUFLLFNBQVMsRUFBRTtBQUFBLG9CQUNoRixXQUFXO0FBQUEsa0JBQ1osQ0FBQztBQUNELHVCQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyx5QkFBTztBQUFBLGdCQUNSO0FBQUEsY0FDRDtBQUFBLFlBQ0Q7QUFBQSxVQUNEO0FBRUEsY0FBSSxLQUFLLFNBQVMsY0FBYztBQUMvQixxQkFBUyxRQUFRLEtBQUssa0JBQWtCO0FBQ3ZDLGtCQUFJLGVBQWUsS0FBSyxPQUFPLEtBQUssT0FBTyxLQUFLLE9BQU8sS0FBSyxTQUFTLENBQUM7QUFBRztBQUN6RSxrQkFBSSxPQUFPLEdBQUcsTUFBTSxJQUFJLFlBQVksTUFBTSxLQUFLLE9BQU8sS0FBSyxRQUFRLEdBQUc7QUFDdEUsa0JBQUksUUFBUSxHQUFHLE1BQU0sSUFBSSxZQUFZLEtBQUssTUFBTSxLQUFLLE9BQU8sTUFBTSxNQUFNO0FBQ3hFLGtCQUFJLFNBQVMsS0FBSyxPQUFPLFFBQVEsVUFBVSxLQUFLLE9BQU8sT0FBTztBQUM3RCx3QkFBUSxLQUFLO0FBQUEsa0JBQ1osU0FBUztBQUFBLG9CQUNSLE1BQU0sTUFBTSxLQUFLLE9BQU8sS0FBSyxTQUFTO0FBQUEsb0JBQ3RDLElBQUksTUFBTSxLQUFLLE9BQU8sTUFBTTtBQUFBLG9CQUM1QixRQUFRLEtBQUssTUFBTSxPQUFPLEtBQUssTUFBTTtBQUFBLGtCQUN0QztBQUFBLGtCQUNBLFdBQVcsRUFBRSxRQUFRLE1BQU0sS0FBSyxPQUFPLEtBQUssU0FBUyxLQUFLLE1BQU0sS0FBSyxTQUFTLEVBQUU7QUFBQSxrQkFDaEYsV0FBVztBQUFBLGdCQUNaLENBQUM7QUFDRCxxQkFBSyxHQUFHLFdBQVcsT0FBTyxHQUFHLE9BQU87QUFDcEMsdUJBQU87QUFBQSxjQUNSO0FBQUEsWUFDRDtBQUFBLFVBQ0Q7QUFLQSxjQUFJLEtBQUssU0FBUyxzQkFBc0I7QUFDdkMscUJBQVMsUUFBUSxLQUFLLDZCQUE2QjtBQUNsRCxrQkFBSSxlQUFlLEtBQUssT0FBTyxLQUFLLE9BQU8sS0FBSyxPQUFPLEtBQUssU0FBUyxDQUFDO0FBQUc7QUFDekUsa0JBQUksT0FBTyxHQUFHLE1BQU0sSUFBSSxZQUFZLE1BQU0sS0FBSyxPQUFPLEtBQUssUUFBUSxHQUFHO0FBQ3RFLGtCQUFJLFFBQVEsR0FBRyxNQUFNLElBQUksWUFBWSxLQUFLLE1BQU0sS0FBSyxPQUFPLE1BQU0sTUFBTTtBQUN4RSxrQkFBSSxTQUFTLEtBQUssT0FBTyxRQUFRLFVBQVUsS0FBSyxPQUFPLE9BQU87QUFDN0Qsd0JBQVEsS0FBSztBQUFBLGtCQUNaLFNBQVM7QUFBQSxvQkFDUixNQUFNLE1BQU0sS0FBSyxPQUFPLEtBQUssU0FBUztBQUFBLG9CQUN0QyxJQUFJLE1BQU0sS0FBSyxPQUFPLE1BQU07QUFBQSxvQkFDNUIsUUFBUSxLQUFLLE1BQU0sT0FBTyxLQUFLLE1BQU07QUFBQSxrQkFDdEM7QUFBQSxrQkFDQSxXQUFXLEVBQUUsUUFBUSxNQUFNLEtBQUssT0FBTyxLQUFLLFNBQVMsS0FBSyxNQUFNLEtBQUssU0FBUyxFQUFFO0FBQUEsa0JBQ2hGLFdBQVc7QUFBQSxnQkFDWixDQUFDO0FBQ0QscUJBQUssR0FBRyxXQUFXLE9BQU8sR0FBRyxPQUFPO0FBQ3BDLHVCQUFPO0FBQUEsY0FDUjtBQUFBLFlBQ0Q7QUFFQSxnQkFBSSxLQUFLLGVBQWUsSUFBSSxXQUFXLEtBQUssZUFBYSxLQUFLO0FBQzdELHNCQUFRLEtBQUs7QUFBQSxnQkFDWixTQUFTLEVBQUUsTUFBTSxPQUFPLElBQUksS0FBSyxRQUFRLGNBQWMsS0FBSyxlQUFlLElBQUksV0FBVyxFQUFFO0FBQUEsZ0JBQzVGLFdBQVcsRUFBRSxRQUFRLFFBQVEsRUFBRTtBQUFBLGdCQUMvQixXQUFXO0FBQUEsY0FDWixDQUFDO0FBQ0QsbUJBQUssR0FBRyxXQUFXLE9BQU8sR0FBRyxPQUFPO0FBQ3BDLHFCQUFPO0FBQUEsWUFDUixXQUNTLGdCQUFnQixLQUFLO0FBQzdCLGtCQUFJLG1CQUFtQixHQUFHLFdBQVcsU0FBUyxRQUFRLEdBQUcsS0FBSztBQUM5RCxrQkFBSSxDQUFDLElBQUksS0FBSyxJQUFJLEVBQUUsU0FBUyxnQkFBZ0IsR0FBRztBQUMvQyx3QkFBUSxLQUFLO0FBQUEsa0JBQ1osU0FBUyxFQUFFLE1BQU0sT0FBTyxJQUFJLEtBQUssUUFBUSxLQUFLO0FBQUEsa0JBQzlDLFdBQVcsRUFBRSxRQUFRLFFBQVEsRUFBRTtBQUFBLGtCQUMvQixXQUFXO0FBQUEsZ0JBQ1osQ0FBQztBQUNELHFCQUFLLEdBQUcsV0FBVyxPQUFPLEdBQUcsT0FBTztBQUNwQyx1QkFBTztBQUFBLGNBQ1I7QUFBQSxZQUNEO0FBR0EsZ0JBQUksZ0JBQWdCLFlBQU8sZ0JBQWdCLFVBQUs7QUFDL0Msa0JBQUksVUFBVSxnQkFBZ0IsV0FBTSxpQkFBTztBQUMzQyxzQkFBUSxLQUFLO0FBQUEsZ0JBQ1osU0FBUyxFQUFFLE1BQU0sT0FBTyxJQUFJLEtBQUssUUFBUSxRQUFRO0FBQUEsZ0JBQ2pELFdBQVcsRUFBRSxRQUFRLFFBQVEsRUFBRTtBQUFBLGdCQUMvQixXQUFXO0FBQUEsY0FDWixDQUFDO0FBQ0QsbUJBQUssR0FBRyxXQUFXLE9BQU8sR0FBRyxPQUFPO0FBQ3BDLHFCQUFPO0FBQUEsWUFDUjtBQUFBLFVBQ0Q7QUFBQSxRQUNEO0FBQUEsTUFDRCxDQUFDO0FBQ0QsYUFBTztBQUFBLElBQ1I7QUFnQkEsNEJBQW1CLENBQUMsV0FBdUI7QUFDMUMsVUFBSSxLQUFLLG9CQUFvQjtBQUFNO0FBRW5DLFVBQUksY0FBYztBQUNsQixVQUFJLGdCQUFnQixPQUFPLEtBQUssTUFBTSxVQUFVLFNBQVMsRUFBRTtBQUMzRCxVQUFJLGNBQWMsVUFBVSxjQUFjO0FBQU0sc0JBQWM7QUFDOUQsVUFBSSxDQUFDLE9BQU87QUFBWTtBQUV4QixVQUFJLGdCQUFnQixLQUFLLHFCQUFxQjtBQUk5QyxVQUFJLEtBQUssT0FBTyxhQUFhO0FBQzdCLFVBQUksYUFBYSxvQkFBb0IsRUFBRTtBQUV2QyxTQUFHLFFBQVEsWUFBWSxDQUFDLE9BQU8sS0FBSyxPQUFPLEtBQUssYUFBYTtBQUM1RCxZQUFJLGNBQWMsU0FBUyxZQUFZLENBQUM7QUFDeEMsWUFBSSxhQUFhLEdBQUcsV0FBVyxJQUFJLFlBQVksT0FBTyxHQUFHO0FBQ3pELFlBQUksS0FBSyxTQUFTLE9BQU07QUFDdkIsa0JBQVEsSUFBSSw4REFBOEQ7QUFDMUUsa0JBQVEsSUFBSSxZQUFZLE9BQU8sS0FBSyxZQUFZLE9BQU8sS0FBSyxXQUFXO0FBQ3ZFLGtCQUFRLElBQUksa0JBQWtCLE9BQU8sS0FBSyxTQUFTO0FBQUEsUUFDcEQ7QUFHQSxZQUFJLGVBQWUsT0FBTyxLQUFLLE9BQU8sS0FBSyxLQUFLLHFCQUFnQjtBQUMvRDtBQUFBLFFBQ0Q7QUFFQSxZQUFJLFNBQVMsT0FBTyxLQUFLLE1BQU0sVUFBVSxTQUFTLEVBQUU7QUFFcEQsWUFBSSxPQUFPLEtBQUssV0FBVTtBQUN6QixjQUFJLEtBQUsscUJBQW9CO0FBQzVCLGlCQUFLLGtCQUFrQixPQUFPO0FBQUEsVUFDL0IsT0FDSTtBQUNILGlCQUFLLHNCQUFzQjtBQUMzQixpQkFBSyxvQkFBb0I7QUFDekIsaUJBQUssa0JBQWtCLE9BQU87QUFBQSxVQUMvQjtBQUNBO0FBQUEsUUFDRDtBQUVBLFlBQUksY0FBYztBQUNsQixZQUFJLFlBQVk7QUFDaEIsWUFBSSxhQUFhO0FBQ2pCLFlBQUksS0FBSyxxQkFBb0I7QUFDNUIsdUJBQWE7QUFDYixlQUFLLHNCQUFzQjtBQUMzQix3QkFBYyxLQUFLO0FBQ25CLHNCQUFZLEtBQUs7QUFBQSxRQUNsQjtBQUVBLFlBQUksV0FBVyxTQUFTLFlBQVksS0FBSyxjQUFZLFVBQVUsY0FBWTtBQUFRO0FBRW5GLFlBQUksY0FBYyxVQUFVLGVBQWUsQ0FBQyxXQUFXLFNBQVMsUUFBUSxHQUFHO0FBRTFFLGNBQUksS0FBSyxtQkFBbUIsT0FBTyxNQUFNLGNBQWMsTUFBTTtBQUFHO0FBQ2hFLGNBQUksY0FBYyxLQUFLLG1CQUFtQixPQUFPLE1BQU0sV0FBVztBQUFHO0FBS3JFLGNBQUksS0FBSyxTQUFTLGNBQWMsZUFBZSxDQUFDLGlCQUM3QyxlQUFjLFVBQVUsZUFBYSxPQUFPO0FBRTlDLGdCQUFJLGVBQWUsT0FBTyxLQUFLLE9BQU8sV0FBVyxLQUFLLHFCQUFpQixlQUFlLE9BQU8sS0FBSyxPQUFPLFdBQVcsS0FBSyxxQkFBZTtBQUN2SSxrQkFBSSxVQUFVLEtBQUssU0FBUyxnQkFBZ0IsT0FBTyxPQUFPLEtBQUssVUFBVSxhQUFhLE9BQU8sUUFBUSxXQUFXO0FBQ2hILGtCQUFJLFdBQVcsTUFBTTtBQUNwQix1QkFBTyxLQUFLLFNBQVMsR0FBRyxRQUFRLEVBQUU7QUFDbEMsdUJBQU8sS0FBSyxTQUFTLFFBQVEsRUFBRTtBQUMvQjtBQUFBLGNBQ0Q7QUFBQSxZQUNEO0FBQUEsVUFDRDtBQUFBLFFBQ0Q7QUFHQSxZQUFJLEtBQUssU0FBUyxjQUFjLENBQUMsaUJBQWlCLGNBQWMsaUJBQWlCLENBQUMsMEJBQVMsVUFBVTtBQUNwRyxjQUFJLGtCQUFrQixPQUFPLE1BQU0sSUFBSSxPQUFPLEtBQUssRUFBRTtBQUNyRCxjQUFJLGdCQUFnQixPQUFPLE1BQU0sSUFBSSxPQUFPLEdBQUcsRUFBRTtBQUNqRCxjQUFJLG1CQUFtQixpQkFBaUIsZUFBZSxPQUFPLEtBQUssT0FBTyxHQUFHLEtBQUssbUJBQWU7QUFDaEcsZ0JBQUksVUFBVSxLQUFLLFNBQVMsZ0JBQWdCLE9BQU8sT0FBTyxLQUFLLFVBQVUsT0FBTyxLQUFLLFdBQVc7QUFDaEcsZ0JBQUksV0FBVyxNQUFNO0FBQ3BCLHFCQUFPLEtBQUssU0FBUyxHQUFHLFFBQVEsRUFBRTtBQUVsQztBQUFBLFlBQ0Q7QUFBQSxVQUNELE9BQ0s7QUFDSixnQkFBSSxjQUFpQyxDQUFDO0FBQ3RDLGdCQUFJLGlCQUFpQixZQUFZLE1BQU0sSUFBSTtBQUMzQyxnQkFBSSxlQUFlO0FBQ25CLHFCQUFTLElBQUksaUJBQWlCLEtBQUssZUFBZSxLQUFLO0FBQ3RELGtCQUFJLGdCQUFnQixlQUFlLElBQUk7QUFHdkMsa0JBQUksVUFBVSxLQUFLLFNBQVMsZ0JBQWdCLE9BQU8sT0FBTyxLQUFLLFVBQVUsY0FBYyxlQUFlLGNBQWMsUUFBUSxhQUFhO0FBRXpJLGtCQUFJLFdBQVcsTUFBTTtBQUNwQiw0QkFBWSxLQUFLLEdBQUcsUUFBUSxFQUFFO0FBQUEsY0FDL0I7QUFDQSw4QkFBZ0IsY0FBYyxTQUFTO0FBQUEsWUFDeEM7QUFDQSxnQkFBSSxZQUFZLFNBQVMsR0FBRztBQUMzQixxQkFBTyxLQUFLLFNBQVMsR0FBRyxXQUFXO0FBQ25DO0FBQUEsWUFDRDtBQUFBLFVBQ0Q7QUFBQSxRQUNEO0FBQUEsTUFDRCxDQUFDO0FBQUEsSUFDRjtBQUVBLFNBQWlCLGdCQUFnQixDQUFDLFNBQXFCO0FBQ3RELFVBQUksQ0FBQyxLQUFLLFNBQVM7QUFBUSxlQUFPO0FBRWxDLFVBQUksUUFBUSxLQUFLO0FBQ2pCLFVBQUksTUFBTSxNQUFNO0FBQ2hCLFlBQU0sT0FBTyxpQ0FBVyxLQUFLO0FBQzdCLFlBQU0sSUFBSSxLQUFLLE1BQU07QUFDckIsVUFBSSxFQUFFLE9BQU8sU0FBUztBQUFHLGVBQU87QUFDaEMsWUFBTSxNQUFNLEVBQUUsS0FBSztBQUNuQixVQUFJLE9BQU8sSUFBSSxPQUFPLEdBQUc7QUFVekIsVUFBSSxFQUFFLEtBQUssUUFBTSxFQUFFLEtBQUssTUFBTSxlQUFlLEtBQUssT0FBTyxFQUFFLEtBQUssSUFBSSxLQUFLLDZCQUFtQjtBQUMzRixhQUFLLFNBQVM7QUFBQSxVQUNiLFNBQVM7QUFBQSxZQUNSLE1BQU0sRUFBRSxLQUFLO0FBQUEsWUFDYixRQUFRLEtBQUsscUJBQXFCO0FBQUEsVUFDbkM7QUFBQSxVQUNBLFdBQVc7QUFBQSxZQUNWLFFBQVEsRUFBRSxLQUFLLE9BQU8sS0FBSyxxQkFBcUIsRUFBRTtBQUFBLFVBQ25EO0FBQUEsUUFDRCxDQUFDO0FBQ0QsZUFBTztBQUFBLE1BQ1I7QUFJQSxVQUFJLEtBQUssU0FBUyxrQkFBa0IsTUFBTSxLQUFLLFFBQVEsS0FBSyxLQUFLLFFBQVEsTUFBTSxHQUFHLENBQUMsRUFBRSxLQUFLLFNBQVMsYUFBYSxHQUFHO0FBQ2xILFlBQUksS0FBSyxRQUFRLEtBQUssQ0FBQyxFQUFFLEtBQUssU0FBUyw2QkFBNkIsR0FBRztBQUN0RSxlQUFLLFNBQVM7QUFBQSxZQUNiLFdBQVcsRUFBRSxRQUFRLE1BQU0sR0FBRyxNQUFNLE1BQU0sRUFBRTtBQUFBLFVBQzdDLENBQUM7QUFDRCxpQkFBTztBQUFBLFFBQ1I7QUFFQSxpQkFBUyxJQUFJLE1BQU0sR0FBRyxJQUFJLEtBQUssTUFBTSxLQUFLLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxTQUFTLGFBQWEsR0FBRyxLQUFLLEdBQUc7QUFFN0YsY0FBSSxLQUFLLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxTQUFTLDZCQUE2QixHQUFHO0FBQ3BFLGlCQUFLLFNBQVM7QUFBQSxjQUNiLFdBQVcsRUFBRSxRQUFRLEdBQUcsTUFBTSxFQUFFO0FBQUEsWUFDakMsQ0FBQztBQUNELG1CQUFPO0FBQUEsVUFDUjtBQUVBLGNBQUksS0FBSyxLQUFLLEtBQUssS0FBSyxLQUFLLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxTQUFTLGFBQWEsR0FBRztBQUN4RSxpQkFBSyxTQUFTO0FBQUEsY0FDYixXQUFXLEVBQUUsUUFBUSxJQUFJLEdBQUcsTUFBTSxJQUFJLEVBQUU7QUFBQSxZQUN6QyxDQUFDO0FBQ0QsbUJBQU87QUFBQSxVQUNSO0FBQUEsUUFDRDtBQUFBLE1BQ0Q7QUFHQSxVQUFJLFlBQVksS0FBSyxNQUFNLFVBQVUsU0FBUyxFQUFFO0FBQ2hELFVBQUksV0FBVyxVQUFVLFVBQVUsVUFBVTtBQUM3QyxVQUFJLFVBQVM7QUFDWixZQUFJLGFBQWEsVUFBVSxTQUFPLFVBQVUsT0FBSyxVQUFVLFNBQU8sVUFBVTtBQUM1RSxZQUFJLFdBQVcsVUFBVSxTQUFPLFVBQVUsT0FBSyxVQUFVLFNBQU8sVUFBVTtBQUcxRSxpQkFBUyxRQUFRLEtBQUssZ0JBQWU7QUFDcEMsY0FBSSxJQUFJLFlBQVksYUFBVyxLQUFLLEtBQUssUUFBUSxVQUFVLEtBQUssS0FBSyxRQUNwRSxJQUFJLFlBQVksVUFBVSxXQUFTLEtBQUssTUFBTSxNQUFNLEtBQUssS0FBSyxPQUFNO0FBQ25FLGlCQUFLLFNBQVM7QUFBQSxjQUNiLFdBQVcsRUFBRSxRQUFRLFdBQVMsS0FBSyxNQUFNLFFBQVEsTUFBTSxXQUFTLEtBQUssTUFBTSxPQUFPO0FBQUEsWUFDbkYsQ0FBQztBQUNELG1CQUFPO0FBQUEsVUFDUjtBQUFBLFFBQ0Y7QUFBQSxNQUNEO0FBR0EsYUFBTztBQUFBLElBQ1I7QUFFQSxTQUFpQixjQUFjLENBQUMsU0FBcUI7QUFFcEQsVUFBSSxDQUFDLEtBQUssU0FBUztBQUFZLGVBQU87QUFFdEMsVUFBSSxtQkFBbUIsS0FBSyxJQUFJLE1BQU0sT0FBTyxvQkFBb0I7QUFDakUsVUFBSSxDQUFDO0FBQWtCLGVBQU87QUFFOUIsVUFBSSxRQUFRLEtBQUs7QUFDakIsVUFBSSxNQUFNLE1BQU07QUFDaEIsWUFBTSxPQUFPLGlDQUFXLEtBQUs7QUFDN0IsWUFBTSxJQUFJLEtBQUssTUFBTTtBQUNyQixVQUFJLEVBQUUsT0FBTyxTQUFTO0FBQUcsZUFBTztBQUNoQyxZQUFNLE1BQU0sRUFBRSxLQUFLO0FBQ25CLFVBQUksT0FBTyxJQUFJLE9BQU8sR0FBRztBQU96QixVQUFJLFFBQVEsS0FBSyxLQUFLLElBQUk7QUFBRyxlQUFPO0FBQUEsZUFDM0IsZ0JBQWdCLE9BQU8sR0FBRyxLQUFLLG1CQUFlO0FBQ3RELGFBQUssU0FBUztBQUFBLFVBQ2IsU0FBUztBQUFBLFlBQ1IsTUFBTTtBQUFBLFlBQ04sSUFBSTtBQUFBLFlBQ0osUUFBUTtBQUFBLFVBQ1Q7QUFBQSxVQUNBLFdBQVcsRUFBRSxRQUFRLE1BQU0sRUFBRTtBQUFBLFVBQzdCLFdBQVc7QUFBQSxRQUNaLENBQUM7QUFDRCxlQUFPO0FBQUEsTUFDUjtBQUVBLGFBQU87QUFBQSxJQUNSO0FBR0EsU0FBaUIsd0JBQXdCLENBQUMsU0FBcUI7QUFDOUQsVUFBSSxDQUFDLEtBQUssU0FBUztBQUFnQixlQUFPO0FBQzFDLFVBQUksV0FBVztBQUNmLFVBQUksZ0JBQWdCLEtBQUssTUFBTSxVQUFVLFNBQVMsRUFBRTtBQUNwRCxVQUFJLGNBQWMsVUFBVSxjQUFjO0FBQU0sbUJBQVc7QUFDM0QsVUFBSTtBQUFVLGVBQU87QUFFckIsVUFBSSxhQUFhLGNBQWM7QUFFL0IsYUFBTyxxQkFBcUIsTUFBTSxVQUFVO0FBQUEsSUFDN0M7QUFFQSxTQUFpQixVQUFVLENBQUMsT0FBc0IsU0FBcUI7QUFDdEUsVUFBSSxLQUFLLFNBQVMsT0FBTztBQUV4QixnQkFBUSxJQUFJLFVBQVUsTUFBTSxHQUFHO0FBQUEsTUFDaEM7QUFDQSxXQUFLLHdCQUF3QixPQUFPLElBQUk7QUFBQSxJQUN6QztBQUVBLDhCQUFxQixDQUFDLE1BQWtCLGVBQStCO0FBQ3RFLGVBQVMsUUFBUSxLQUFLLGtCQUFrQjtBQUV2QyxZQUFJLE9BQU8sS0FBSyxNQUFNLElBQUksWUFBWSxhQUFhLEtBQUssT0FBTyxLQUFLLFFBQVEsVUFBVTtBQUN0RixZQUFJLFFBQVEsS0FBSyxNQUFNLElBQUksWUFBWSxZQUFZLGFBQWEsS0FBSyxPQUFPLE1BQU0sTUFBTTtBQUN4RixZQUFJLFdBQVcsS0FBSyxNQUFNLE9BQU8sS0FBSyxNQUFNO0FBQzVDLFlBQUksU0FBUyxhQUFhLEtBQUssT0FBTyxLQUFLLFNBQVMsS0FBSyxNQUFNLEtBQUs7QUFDcEUsWUFBSSxPQUFPLGFBQWEsS0FBSyxPQUFPLEtBQUs7QUFDekMsWUFBSSxLQUFLLGFBQWEsS0FBSyxPQUFPLE1BQU07QUFFeEMsWUFBSSxLQUFLLE9BQU8sS0FBSyxPQUFPLENBQUMsTUFBTSxRQUFRLEtBQUssTUFBTSxLQUFLLE9BQU8sQ0FBQyxNQUFNLFFBQ3hFLGFBQWEsS0FBSyxPQUFPLEtBQUssU0FBTyxLQUFHLEdBQUc7QUFDM0MsaUJBQU8sT0FBTztBQUNkLHFCQUFXLFNBQVMsVUFBVSxDQUFDO0FBQy9CLGlCQUFPO0FBQUEsUUFDUjtBQUNBLFlBQUksU0FBUyxLQUFLLE9BQU8sUUFBUSxVQUFVLEtBQUssT0FBTyxPQUFPO0FBQzdELGVBQUssU0FBUztBQUFBLFlBQ2IsU0FBUztBQUFBLGNBQ1I7QUFBQSxjQUNBO0FBQUEsY0FDQSxRQUFRO0FBQUEsWUFDVDtBQUFBLFlBQ0EsV0FBVyxFQUFFLE9BQWU7QUFBQSxZQUM1QixXQUFXO0FBQUEsVUFDWixDQUFDO0FBQ0QsaUJBQU87QUFBQSxRQUNSO0FBQUEsTUFDRDtBQUNBLGFBQU87QUFBQSxJQUNSO0FBRUEsOEJBQXFCLENBQUMsTUFBa0Isb0JBQW9DO0FBQzNFLFVBQUksS0FBSyxTQUFTLGVBQ2pCLFNBQVMsS0FBSyxLQUFLLE1BQU0sSUFBSSxZQUFZLGtCQUFrQixHQUFHLGVBQWUsQ0FBQyxHQUFHO0FBQ2pGLFlBQUksT0FBTyxLQUFLLE1BQU0sSUFBSSxZQUFZLGtCQUFrQixHQUFHLGVBQWU7QUFDMUUsWUFBSSxrQkFBa0IsS0FBSyxtQkFBbUIsS0FBSyxLQUFLLE1BQU0sSUFBSSxZQUFZLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDLENBQUMsR0FBRztBQUFBLFFBQUUsT0FDdkg7QUFDSixlQUFLLFNBQVM7QUFBQSxZQUNiLFNBQVM7QUFBQSxjQUNSLE1BQU0sa0JBQWtCO0FBQUEsY0FDeEIsSUFBSTtBQUFBLGNBQ0osUUFBUSxLQUFLLG9CQUFvQixJQUFJLElBQUk7QUFBQSxZQUMxQztBQUFBLFlBRUEsV0FBVztBQUFBLFVBQ1osQ0FBQztBQUNELGlCQUFPO0FBQUEsUUFDUjtBQUFBLE1BQ0Q7QUFDQSxhQUFPO0FBQUEsSUFDUjtBQUVBLG1DQUEwQixDQUFDLE9BQXNCLFNBQXFCO0FBQ3JFLFVBQUssRUFBQyxTQUFTLFdBQVcsS0FBSyxPQUFPLEVBQUUsU0FBUyxNQUFNLEdBQUcsS0FBSyxLQUFLLEtBQUssTUFBTSxHQUFHLE1BQ2pGLEtBQUsscUJBQXFCO0FBQzFCLFlBQUksU0FBUyxLQUFLLE1BQU0sVUFBVSxTQUFTLEVBQUU7QUFDN0MsWUFBSSxPQUFPLFFBQVEsT0FBTztBQUFRO0FBQ2xDLFlBQUksY0FBYyxLQUFLLE1BQU0sSUFBSSxZQUFZLEtBQUssbUJBQW1CLE9BQU8sTUFBTTtBQUVsRixhQUFLLHNCQUFzQjtBQUMzQixZQUFJLEtBQUssbUJBQW1CLE1BQU0sT0FBTyxNQUFNO0FBQUc7QUFDbEQsWUFBSSxLQUFLLG1CQUFtQixNQUFNLEtBQUssaUJBQWlCO0FBQUc7QUFDM0QsWUFBSSxLQUFLLFNBQVMsY0FBYyxDQUFDLEtBQUsscUJBQXFCLEdBQUU7QUFDNUQsY0FBSSxlQUFlLEtBQUssT0FBTyxPQUFPLE1BQU0sS0FBSztBQUFlO0FBQ2hFLGNBQUksVUFBVSxLQUFLLFNBQVMsZ0JBQWdCLEtBQUssT0FBTyxLQUFLLFVBQzVELEtBQUssbUJBQW1CLE9BQU8sUUFBUSxXQUFXO0FBQ25ELGNBQUksV0FBVyxNQUFNO0FBQ3BCLGlCQUFLLFNBQVMsR0FBRyxRQUFRLEVBQUU7QUFDM0IsaUJBQUssU0FBUyxRQUFRLEVBQUU7QUFDeEI7QUFBQSxVQUNEO0FBQUEsUUFDRDtBQUFBLE1BQ0Q7QUFBQSxJQUNEO0FBRUEseUJBQWdCLENBQUMsUUFBZ0IsU0FBNkI7QUFDN0QsWUFBTSxhQUFhLE9BQU87QUFDMUIsWUFBTSxPQUFPLHVDQUFpQixXQUFXLE9BQU8sV0FBVyxNQUFNLElBQUksTUFBTTtBQUMzRSxVQUFJLENBQUMsTUFBSztBQUNULFlBQUksd0JBQU8sdUZBQXVGLEdBQUk7QUFDdEc7QUFBQSxNQUNEO0FBRUEsV0FBSyxrQkFBa0I7QUFFdkIsVUFBSSxZQUFZLE9BQU8sVUFBVTtBQUNqQyxVQUFJLGNBQWM7QUFDbEIsVUFBSSxLQUFLLE9BQU8sVUFBVTtBQUMxQixVQUFJLEtBQUs7QUFDVCxlQUFTLElBQUksR0FBRyxJQUFJLFdBQVcsS0FBSztBQUNuQyxZQUFJLEtBQUs7QUFBRyx5QkFBZTtBQUMzQixZQUFJLEtBQUssR0FBRyxNQUFNO0FBQ2pCLHlCQUFlLEtBQUssaUJBQWlCLFFBQVEsSUFBSSxDQUFDLEVBQUU7QUFBQSxRQUNyRCxPQUNLO0FBQ0osY0FBSSxVQUFVLEtBQUssaUJBQWlCLFFBQVEsSUFBSSxHQUFHLEdBQUcsRUFBRTtBQUN4RCx5QkFBZSxRQUFRO0FBQ3ZCLGVBQUssUUFBUTtBQUFBLFFBQ2Q7QUFBQSxNQUNEO0FBQ0EsYUFBTyxTQUFTLFdBQVc7QUFDM0IsYUFBTyxVQUFVLEVBQUUsTUFBTSxHQUFHLE1BQU0sR0FBTyxDQUFDO0FBRTFDLFdBQUssa0JBQWtCO0FBRXZCLFVBQUksd0JBQU8sa0NBQWtDO0FBQUEsSUFDOUM7QUF5QkEsb0NBQTJCLENBQUMsUUFBZ0IsU0FBNkI7QUFDeEUsVUFBSSxDQUFDLE9BQU8sa0JBQWtCLEtBQUssT0FBTyxhQUFhLE1BQU0sSUFBSTtBQUNoRSxZQUFJLGFBQWEsT0FBTyxVQUFVLEVBQUU7QUFDcEMsWUFBSSxjQUFjLEtBQUssaUJBQWlCLFFBQVEsYUFBYSxHQUFHLE9BQU8sVUFBVSxFQUFFLEVBQUU7QUFDckYsZUFBTyxhQUFhLFlBQVksSUFBSSxFQUFFLE1BQU0sWUFBWSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sWUFBWSxJQUFJLE9BQU8sUUFBUSxVQUFVLEVBQUUsT0FBTyxDQUFDO0FBQzVILGVBQU8sYUFBYSxFQUFFLE1BQU0sWUFBWSxJQUFJLFlBQVksR0FBRyxDQUFDO0FBQzVEO0FBQUEsTUFDRDtBQUNBLFVBQUksWUFBWSxPQUFPLGVBQWUsRUFBRTtBQUN4QyxVQUFJLFFBQVEsVUFBVSxPQUFPO0FBQzdCLFVBQUksTUFBTSxVQUFVLEtBQUs7QUFDekIsVUFBSSxRQUFRLEtBQUs7QUFDaEIsWUFBSSxPQUFPO0FBQ1gsZ0JBQVE7QUFDUixjQUFNO0FBQUEsTUFDUDtBQUVBLFVBQUksWUFBWTtBQUNoQixlQUFTLElBQUksT0FBTyxLQUFLLEtBQUssS0FBSztBQUNsQyxZQUFJLEtBQUs7QUFBTyx1QkFBYTtBQUM3QixxQkFBYSxLQUFLLGlCQUFpQixRQUFRLElBQUksQ0FBQyxFQUFFO0FBQUEsTUFDbkQ7QUFDQSxhQUFPLGFBQWEsV0FBVyxFQUFFLE1BQU0sT0FBTyxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sS0FBSyxJQUFJLE9BQU8sUUFBUSxHQUFHLEVBQUUsT0FBTyxDQUFDO0FBQ3BHLFVBQUksVUFBVSxPQUFPLE9BQU8sVUFBVSxLQUFLLE1BQU07QUFDaEQsZUFBTyxhQUFhLEVBQUUsTUFBTSxVQUFVLE9BQU8sTUFBTSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sVUFBVSxLQUFLLE1BQU0sSUFBSSxPQUFPLFFBQVEsVUFBVSxLQUFLLElBQUksRUFBRSxPQUFPLENBQUM7QUFBQSxNQUMxSSxPQUNLO0FBQ0osZUFBTyxhQUFhLEVBQUUsTUFBTSxVQUFVLE9BQU8sTUFBTSxJQUFJLE9BQU8sUUFBUSxVQUFVLE9BQU8sSUFBSSxFQUFFLE9BQU8sR0FBRyxFQUFFLE1BQU0sVUFBVSxLQUFLLE1BQU0sSUFBSSxFQUFFLENBQUM7QUFBQSxNQUM1STtBQUFBLElBQ0Q7QUFHQSx5QkFBZ0IsQ0FBQyxRQUFnQixlQUE2QjtBQUM3RCxZQUFNLGFBQWEsT0FBTztBQUMxQixVQUFJLFFBQVEsV0FBVztBQUN2QixVQUFJLE9BQU8sTUFBTSxJQUFJLEtBQUssVUFBVTtBQUVwQyxVQUFJLGVBQWUsT0FBTyxLQUFLLElBQUksS0FBSyxxQkFBaUIsZUFBZSxPQUFPLEtBQUssSUFBSSxLQUFLLHFCQUFnQjtBQUM1RyxZQUFJLFVBQVUsS0FBSztBQUNuQixZQUFJLFVBQVUsS0FBSyxTQUFTLFdBQVcsT0FBTyxZQUFZLEtBQUssVUFBVSxRQUFRLFFBQVEsQ0FBQyxFQUFFO0FBQzVGLFlBQUksV0FBVyxTQUFTO0FBQ3ZCLGlCQUFPLGFBQWEsU0FBUyxFQUFFLE1BQU0sYUFBYSxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLEdBQUcsSUFBSSxRQUFRLE9BQU8sQ0FBQztBQUMxRyxpQkFBTyxVQUFVLEVBQUUsTUFBTSxhQUFhLEdBQUcsSUFBSSxPQUFPLFFBQVEsYUFBYSxDQUFDLEVBQUUsT0FBTyxDQUFDO0FBQUEsUUFDckY7QUFBQSxNQUNEO0FBQ0E7QUFBQSxJQUNEO0FBR0EsNEJBQW1CLENBQUMsUUFBZ0IsWUFBb0IsS0FBYSxPQUF5QjtBQUM3RixZQUFNLGFBQWEsT0FBTztBQUMxQixVQUFJLFFBQVEsV0FBVztBQUN2QixVQUFJLE9BQU8sTUFBTSxJQUFJLEtBQUssVUFBVTtBQUVwQyxVQUFJLFVBQVUsS0FBSztBQUNuQixVQUFJLFFBQVE7QUFDWixVQUFJLFFBQVEsS0FBSyxLQUFLO0FBQ3RCLFVBQUksTUFBTSxJQUFJO0FBQ2IsZ0JBQVE7QUFBQSxNQUNUO0FBQ0EsVUFBSSxlQUFlLE9BQU8sS0FBSyxJQUFJLEtBQUsscUJBQWlCLGVBQWUsT0FBTyxLQUFLLElBQUksS0FBSyxxQkFBZ0I7QUFDNUcsWUFBSSxjQUFjLEtBQUssU0FBUyxXQUFXLE9BQU8sWUFBWSxLQUFLLFVBQVUsT0FBTyxDQUFDO0FBQ3JGLGtCQUFVLFlBQVk7QUFDdEIsZ0JBQVEsWUFBWTtBQUFBLE1BQ3JCO0FBRUEsYUFBTyxDQUFDLFNBQVMsS0FBSztBQUFBLElBQ3ZCO0FBRUEsNEJBQW1CLENBQUMsV0FBeUI7QUFDNUMsVUFBSSxLQUFLLFNBQVMsT0FBTztBQUN4QixnQkFBUSxJQUFJLEtBQUssSUFBSSxNQUFNLFVBQVUsa0JBQWtCLENBQUM7QUFBQSxNQUV6RDtBQUNBLFVBQUksbUJBQW1CLEtBQUssSUFBSSxNQUFNLFVBQVUsa0JBQWtCO0FBRWxFLFlBQU0sYUFBYSxPQUFPO0FBQzFCLFVBQUksUUFBUSxXQUFXO0FBQ3ZCLFVBQUksTUFBTSxNQUFNO0FBRWhCLFlBQU0sT0FBTyx1Q0FBaUIsT0FBTyxJQUFJLE1BQU07QUFDL0MsVUFBSSxDQUFDLE1BQUs7QUFDVCxZQUFJLHdCQUFPLHVGQUF1RixHQUFJO0FBQ3RHO0FBQUEsTUFDRDtBQUVBLFVBQUksYUFBYTtBQUNqQixVQUFJLFdBQVcsSUFBSTtBQUNuQixVQUFJLFdBQVcsSUFBSTtBQUNuQixZQUFNLFdBQVcsT0FBTyxrQkFBa0IsS0FBSyxPQUFPLGFBQWEsS0FBSztBQUN4RSxVQUFJLFVBQVU7QUFDYixZQUFJLFlBQVksT0FBTyxlQUFlLEVBQUU7QUFDeEMsWUFBSSxRQUFRLFVBQVUsT0FBTyxPQUFPO0FBQ3BDLFlBQUksTUFBTSxVQUFVLEtBQUssT0FBTztBQUNoQyxZQUFJLFFBQVEsS0FBSztBQUNoQixjQUFJLE9BQU87QUFDWCxrQkFBUTtBQUNSLGdCQUFNO0FBQUEsUUFDUDtBQUNBLHFCQUFhO0FBQ2IsbUJBQVc7QUFBQSxNQUNaO0FBYUEsVUFBSSxlQUF5QixDQUFDO0FBQzlCLFVBQUksWUFBWTtBQUNoQixVQUFJLG9CQUFvQjtBQUV4QixVQUFJLGNBQWMsR0FBRztBQUNwQixZQUFJLE9BQU8sS0FBSyxRQUFRLElBQUksS0FBSyxhQUFhLENBQUMsRUFBRSxNQUFNLENBQUM7QUFDeEQsWUFBSSxLQUFLLEtBQUssU0FBUyxNQUFNLEtBQUssS0FBSyxLQUFLLFNBQVMsT0FBTyxLQUFLLEtBQUssS0FBSyxTQUFTLFNBQVMsR0FBRztBQUMvRiw4QkFBb0I7QUFBQSxRQUNyQjtBQUFBLE1BQ0Q7QUFDQSxVQUFJLFlBQVksWUFBWSxDQUFDLFVBQVUsS0FBSyxJQUFJLEtBQUssV0FBVyxDQUFDLEVBQUUsSUFBSSxHQUFHO0FBQ3pFLG9CQUFZO0FBQUEsTUFDYjtBQUVBLGVBQVMsSUFBSSxZQUFZLEtBQUssVUFBVSxLQUFLO0FBQzVDLFlBQUksT0FBTyxJQUFJLEtBQUssQ0FBQztBQUNyQixZQUFJLE1BQU0sS0FBSztBQUNmLFlBQUksT0FBTyxLQUFLLFFBQVEsS0FBSyxDQUFDO0FBRzlCLFlBQUksVUFBVSxLQUFLLEtBQUssSUFBSSxLQUFLLENBQUMsbUJBQW1CO0FBQ3BELHVCQUFhLEtBQUssQ0FBQztBQUNuQjtBQUFBLFFBQ0QsV0FDUyxVQUFVLEtBQUssS0FBSyxJQUFJLEtBQUssbUJBQW1CO0FBQ3hELDhCQUFvQjtBQUNwQjtBQUFBLFFBQ0Q7QUFFQSxZQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxhQUFhLGFBQWEsU0FBUyxNQUFNLElBQUksR0FBRztBQUMvRSx1QkFBYSxJQUFJO0FBQUEsUUFDbEIsV0FDUyxLQUFLLEtBQUssU0FBUyxNQUFNLEtBQUssS0FBSyxLQUFLLFNBQVMsT0FBTyxLQUFLLEtBQUssS0FBSyxTQUFTLFNBQVMsR0FBRztBQUNwRyw4QkFBb0I7QUFBQSxRQUNyQixPQUNLO0FBQ0osOEJBQW9CO0FBQUEsUUFDckI7QUFBQSxNQUNEO0FBRUEsVUFBSSxhQUFhO0FBQ2pCLGVBQVMsSUFBSSxHQUFHLElBQUksVUFBVSxLQUFLO0FBQ2xDLFlBQUksQ0FBQyxhQUFhLFNBQVMsQ0FBQyxHQUFHO0FBQzlCLHdCQUFjLElBQUksS0FBSyxDQUFDLEVBQUUsT0FBTztBQUFBLFFBQ2xDO0FBQUEsTUFDRDtBQUNBLFVBQUksQ0FBQyxhQUFhLFNBQVMsUUFBUSxHQUFHO0FBQ3JDLHNCQUFjLElBQUksS0FBSyxRQUFRLEVBQUU7QUFBQSxNQUNsQztBQUVBLGFBQU8sU0FBUyxVQUFVO0FBQUEsSUFFM0I7QUF5S0EscUJBQVksTUFBcUI7QUFDaEMsVUFBSSxTQUFTO0FBQ2IsVUFBSSxlQUFlLEtBQUssSUFBSSxVQUFVLG9CQUFvQiw2QkFBWTtBQUN0RSxVQUFJLGNBQWM7QUFDakIsaUJBQVMsYUFBYTtBQUFBLE1BQ3ZCO0FBQ0EsVUFBSSxXQUFXO0FBQU0sZ0JBQVEsSUFBSSxrQkFBbUI7QUFDcEQsYUFBTztBQUFBLElBQ1I7QUFBQTtBQUFBLEVBL3hDQSxNQUFNLFNBQVM7QUFDZCxVQUFNLEtBQUssYUFBYTtBQUN4QixTQUFLLGdDQUFnQztBQUFBLE1BQ3BDLENBQUMsVUFBSyxFQUFFLE1BQU0sS0FBSyxPQUFPLElBQUksQ0FBQztBQUFBLE1BQUcsQ0FBQyxVQUFLLEVBQUUsTUFBTSxLQUFLLE9BQU8sSUFBSSxDQUFDO0FBQUEsTUFBRyxDQUFDLFFBQUssRUFBRSxNQUFNLEtBQUssT0FBTyxJQUFJLENBQUM7QUFBQSxNQUFHLENBQUMsUUFBSyxFQUFFLE1BQU0sS0FBSyxPQUFPLElBQUksQ0FBQztBQUFBLE1BQ3JJLENBQUMsVUFBSyxFQUFFLE1BQU0sVUFBSyxPQUFPLFNBQUksQ0FBQztBQUFBLE1BQUcsQ0FBQyxVQUFLLEVBQUUsTUFBTSxVQUFLLE9BQU8sU0FBSSxDQUFDO0FBQUEsTUFBRyxDQUFDLFVBQUssRUFBRSxNQUFNLFVBQUssT0FBTyxTQUFJLENBQUM7QUFBQSxNQUFHLENBQUMsVUFBSyxFQUFFLE1BQU0sVUFBSyxPQUFPLFNBQUksQ0FBQztBQUFBLE1BQ3JJLENBQUMsS0FBSyxFQUFFLE1BQU0sS0FBSyxPQUFPLElBQUksQ0FBQztBQUFBLElBQ2hDO0FBQ0EsU0FBSyw0QkFBNEI7QUFDakMsU0FBSyxpQkFBaUIsb0JBQUksSUFBb0I7QUFDOUMsUUFBSSxjQUFjLENBQUMsZ0JBQU0sZ0JBQU0sZ0JBQU0sZ0JBQU0sZ0JBQU0sZ0JBQU0sZ0JBQU0sTUFBTSxNQUFNLE1BQU0sTUFBTSxJQUFJO0FBQ3pGLGFBQVMsV0FBVztBQUFhLFdBQUssZUFBZSxJQUFJLFFBQVEsT0FBTyxDQUFDLEdBQUcsUUFBUSxPQUFPLENBQUMsQ0FBQztBQUU3RixTQUFLLHNCQUFzQixvQkFBSSxJQUFJO0FBQUEsTUFDbEMsQ0FBQyxLQUFLLFFBQUc7QUFBQSxNQUNULENBQUMsS0FBSyxRQUFHO0FBQUEsTUFDVCxDQUFDLEtBQUssUUFBRztBQUFBLE1BQ1QsQ0FBQyxLQUFLLFFBQUc7QUFBQSxJQUNWLENBQUM7QUFFRCxRQUFJLDBCQUFtRDtBQUFBLE1BQUMsQ0FBQyxhQUFPLEtBQUs7QUFBQSxNQUFHLENBQUMsNkJBQVEsUUFBUTtBQUFBLE1BQUUsQ0FBQyx1QkFBUSxRQUFRO0FBQUEsTUFDNUcsQ0FBQyx1QkFBUSxPQUFPO0FBQUEsTUFBRyxDQUFDLGlCQUFPLE9BQU87QUFBQSxNQUFHLENBQUMsaUJBQU8sS0FBSztBQUFBLE1BQUcsQ0FBQyxhQUFRLFdBQVc7QUFBQSxNQUFFLENBQUMsYUFBTSxLQUFLO0FBQUEsTUFBRyxDQUFDLFdBQVEsV0FBVztBQUFBLE1BQUUsQ0FBQyxRQUFRLFdBQVc7QUFBQSxNQUFHLENBQUMsT0FBTyxLQUFLO0FBQUEsTUFDcEosQ0FBQyxZQUFPLEtBQUs7QUFBQSxNQUFHLENBQUMsYUFBUSxNQUFNO0FBQUEsTUFBRyxDQUFDLFlBQU8sS0FBSztBQUFBLE1BQUcsQ0FBQyxhQUFRLE1BQU07QUFBQSxJQUFDO0FBQ2xFLFNBQUssaUJBQWlCLHdCQUF3Qix1QkFBdUI7QUFDckUsUUFBSSwwQkFBbUQ7QUFBQSxNQUFDLENBQUMsaUJBQU8sSUFBSTtBQUFBLE1BQUcsQ0FBQyxpQkFBTyxJQUFJO0FBQUEsTUFBRyxDQUFDLGlCQUFPLElBQUk7QUFBQSxNQUFHLENBQUMsaUJBQU8sSUFBSTtBQUFBLE1BQ2pILENBQUMsaUJBQU8sSUFBSTtBQUFBLE1BQUcsQ0FBQyxpQkFBTyxJQUFJO0FBQUEsTUFBRyxDQUFDLHVCQUFRLEtBQUs7QUFBQSxNQUFHLENBQUMsaUJBQU8sS0FBSztBQUFBLE1BQUcsQ0FBQyx1QkFBUSxLQUFPO0FBQUEsTUFBRyxDQUFDLHVCQUFRLEtBQU87QUFBQSxNQUFHLENBQUMsdUJBQVEsS0FBSztBQUFBLE1BQUcsQ0FBQyx1QkFBUSxLQUFLO0FBQUEsTUFDcEksQ0FBQyxpQkFBTyxJQUFJO0FBQUEsTUFBRyxDQUFDLHVCQUFRLElBQUk7QUFBQSxNQUFHLENBQUMsaUJBQU8sSUFBSTtBQUFBLElBQUM7QUFDNUMsU0FBSyxtQkFBbUIsd0JBQXdCLHVCQUF1QjtBQUN2RSxRQUFJLGVBQTRCLEVBQUMsUUFBTyxFQUFDLE1BQUssZ0JBQU0sT0FBTSxHQUFFLEdBQUcsT0FBTSxFQUFDLE1BQUssS0FBSyxPQUFNLEdBQUUsRUFBQztBQUN6RixTQUFLLGlCQUFpQixLQUFLLFlBQVk7QUFFdkMsUUFBSSxxQkFBOEMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxhQUFhLEdBQUcsQ0FBQztBQUNuRyxTQUFLLHVCQUF1Qix3QkFBd0Isa0JBQWtCO0FBRXRFLFFBQUksNEJBQXFEO0FBQUEsTUFBQyxDQUFDLHVCQUFRLGVBQUs7QUFBQSxNQUFHLENBQUMsdUJBQVEsZUFBSztBQUFBLE1BQ3pGLENBQUMsUUFBUSxLQUFLO0FBQUEsTUFBRyxDQUFDLHVCQUFRLGVBQUs7QUFBQSxNQUFHLENBQUMsdUJBQVEsZUFBSztBQUFBLE1BQUcsQ0FBQyx1QkFBUSxlQUFLO0FBQUEsTUFBRyxDQUFDLFFBQVEsS0FBSztBQUFBLE1BQUcsQ0FBQyxRQUFRLEtBQUs7QUFBQSxNQUNuRyxDQUFDLFFBQVEsS0FBSztBQUFBLE1BQUcsQ0FBQyxRQUFRLEtBQUs7QUFBQSxNQUFHLENBQUMsUUFBUSxLQUFLO0FBQUEsSUFDaEQ7QUFDQSxTQUFLLDhCQUE4Qix3QkFBd0IseUJBQXlCO0FBRXBGLFFBQUksaUJBQWlCO0FBQUEsTUFBQztBQUFBLE1BQU87QUFBQSxNQUFPO0FBQUEsTUFBTztBQUFBLE1BQU87QUFBQSxNQUMzQztBQUFBLE1BQU87QUFBQSxNQUFPO0FBQUEsTUFBTztBQUFBLE1BQVM7QUFBQSxNQUFTO0FBQUEsTUFBTztBQUFBLE1BQVM7QUFBQSxNQUN6RDtBQUFBLE1BQVM7QUFBQSxNQUFTO0FBQUEsTUFBUztBQUFBLE1BQU87QUFBQSxNQUFTO0FBQUEsTUFBTTtBQUFBLE1BQU87QUFBQSxNQUFPO0FBQUEsSUFBSztBQUN6RSxTQUFLLGlCQUFpQixlQUFlLElBQUksQ0FBQyxNQUFXLGtCQUFrQixDQUFDLENBQUM7QUFFekUsU0FBSyxzQkFBc0I7QUFDM0IsU0FBSyx1QkFBdUI7QUFFNUIsU0FBSyxvQkFBb0I7QUFFekIsU0FBSyxzQkFBc0I7QUFFM0IsU0FBSyxXQUFXLElBQUksYUFBYTtBQUVqQyxTQUFLLGtCQUFrQjtBQUV2QixTQUFLLHdCQUF3QjtBQUFBLE1BQzVCLHlCQUFZLGtCQUFrQixHQUFHLEtBQUssdUJBQXVCO0FBQUEsTUFDN0QsdUJBQVcsZUFBZSxHQUFHLEtBQUssZ0JBQWdCO0FBQUEsTUFDbEQsa0JBQUssUUFBUSx1QkFBVyxpQkFBaUI7QUFBQSxRQUN4QyxTQUFTLEtBQUs7QUFBQSxNQUNmLENBQUMsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUdELFNBQUssd0JBQXdCLGtCQUFLLFFBQVEsbUJBQU8sR0FBRztBQUFBLE1BQ25EO0FBQUEsUUFDQyxLQUFLO0FBQUEsUUFDTCxLQUFLLENBQUMsU0FBOEI7QUFDbkMsZ0JBQU0sVUFBVSxLQUFLLGNBQWMsSUFBSTtBQUN2QyxpQkFBTztBQUFBLFFBQ1I7QUFBQSxNQUNEO0FBQUEsTUFDQTtBQUFBLFFBQ0MsS0FBSztBQUFBLFFBQ0wsS0FBSyxDQUFDLFNBQThCO0FBQ25DLGdCQUFNLFVBQVUsS0FBSyxZQUFZLElBQUk7QUFDckMsaUJBQU87QUFBQSxRQUNSO0FBQUEsTUFDRDtBQUFBLE1BQ0E7QUFBQSxRQUNDLEtBQUs7QUFBQSxRQUNMLEtBQUssQ0FBQyxTQUE4QjtBQUNuQyxnQkFBTSxVQUFVLEtBQUssc0JBQXNCLElBQUk7QUFDL0MsaUJBQU87QUFBQSxRQUNSO0FBQUEsTUFDRDtBQUFBLElBQ0QsQ0FBQyxDQUFDLENBQUM7QUFFSCxTQUFLLE9BQU8sT0FBTyxhQUFhLFFBQVEsVUFBVTtBQUNsRCxRQUFJLG1CQUFtQixLQUFLLGtCQUFrQjtBQUU5QyxTQUFLLFdBQVc7QUFBQSxNQUNmLElBQUk7QUFBQSxNQUNKLE1BQU0saUJBQWlCLElBQUksZ0JBQWdCO0FBQUEsTUFDM0MsZ0JBQWdCLENBQUMsUUFBZ0IsU0FBdUI7QUFDdkQsYUFBSyxjQUFjLFFBQVEsSUFBSTtBQUFBLE1BQ2hDO0FBQUEsTUFDQSxTQUFTLENBQUM7QUFBQSxRQUNULFdBQVcsQ0FBQyxRQUFRLE9BQU87QUFBQSxRQUMzQixLQUFLO0FBQUEsTUFDTixDQUFDO0FBQUEsSUFDRixDQUFDO0FBRUQsU0FBSyxXQUFXO0FBQUEsTUFDZixJQUFJO0FBQUEsTUFDSixNQUFNLGlCQUFpQixJQUFJLGtCQUFrQjtBQUFBLE1BQzdDLGdCQUFnQixDQUFDLFFBQWdCLFNBQXVCO0FBQ3ZELGFBQUsseUJBQXlCLFFBQVEsSUFBSTtBQUFBLE1BQzNDO0FBQUEsTUFDQSxTQUFTLENBQUM7QUFBQSxRQUNULFdBQVcsQ0FBQyxRQUFRLE9BQU87QUFBQSxRQUMzQixLQUFLO0FBQUEsTUFDTixDQUFDO0FBQUEsSUFDRixDQUFDO0FBRUQsU0FBSyxXQUFXO0FBQUEsTUFDZixJQUFJO0FBQUEsTUFDSixNQUFNLGlCQUFpQixJQUFJLG1CQUFtQjtBQUFBLE1BQzlDLGdCQUFnQixDQUFDLFFBQWdCLFNBQXVCO0FBQ3ZELGFBQUssaUJBQWlCLE1BQU07QUFBQSxNQUM3QjtBQUFBLE1BQ0EsU0FBUyxDQUFDO0FBQUEsUUFDVCxXQUFXLENBQUMsUUFBUSxPQUFPO0FBQUEsUUFDM0IsS0FBSztBQUFBLE1BQ04sQ0FBQztBQUFBLElBQ0YsQ0FBQztBQUVELFNBQUssV0FBVztBQUFBLE1BQ2YsSUFBSTtBQUFBLE1BQ0osTUFBTSxpQkFBaUIsSUFBSSxrQkFBa0I7QUFBQSxNQUM3QyxnQkFBZ0IsQ0FBQyxRQUFnQixTQUF1QjtBQUN2RCxhQUFLLGtCQUFrQixNQUFNO0FBQUEsTUFDOUI7QUFBQSxNQUNBLFNBQVMsQ0FBQztBQUFBLFFBQ1QsV0FBVyxDQUFDLFFBQVEsT0FBTztBQUFBLFFBQzNCLEtBQUs7QUFBQSxNQUNOLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRCxTQUFLLFdBQVc7QUFBQSxNQUNmLElBQUk7QUFBQSxNQUNKLE1BQU0saUJBQWlCLElBQUksbUJBQW1CO0FBQUEsTUFDOUMsVUFBVSxNQUFNLEtBQUsscUJBQXFCO0FBQUEsTUFDMUMsU0FBUyxDQUFDO0FBQUEsUUFDVCxXQUFXLENBQUMsTUFBTTtBQUFBLFFBQ2xCLEtBQUs7QUFBQSxNQUNOLENBQUM7QUFBQSxJQUNGLENBQUM7QUFFRCxTQUFLLFdBQVc7QUFBQSxNQUNmLElBQUk7QUFBQSxNQUNKLE1BQU0saUJBQWlCLElBQUksaUJBQWlCO0FBQUEsTUFDNUMsZ0JBQWdCLENBQUMsV0FBVyxLQUFLLFlBQVksTUFBTTtBQUFBLE1BQ25ELFNBQVM7QUFBQSxRQUNQO0FBQUEsVUFDRCxXQUFXLENBQUMsT0FBTyxPQUFPO0FBQUEsVUFDMUIsS0FBSztBQUFBLFFBQ0o7QUFBQSxNQUNGO0FBQUEsSUFDQyxDQUFDO0FBR0gsU0FBSyxjQUFjLElBQUkscUJBQXFCLEtBQUssS0FBSyxJQUFJLENBQUM7QUFFM0QsU0FBSyxjQUFjLEtBQUssSUFBSSxVQUFVLEdBQUcsc0JBQXNCLENBQUMsU0FBd0I7QUFDdkYsVUFBSSxLQUFLLEtBQUssWUFBWSxLQUFLLFlBQVk7QUFDMUMsWUFBSSxPQUFPLEtBQUssSUFBSSxVQUFVLGNBQWM7QUFDNUMsWUFBSSxRQUFRLFFBQVEsS0FBSyxxQkFBcUIsS0FBSyxNQUFNO0FBQ3hELGVBQUssb0JBQW9CLEtBQUs7QUFDOUIsY0FBSSxLQUFLLFNBQVM7QUFDakIsZ0JBQUksd0JBQU8sdUJBQXVCLEtBQUssSUFBSTtBQUFBLFFBQzdDO0FBQUEsTUFDRDtBQUFBLElBQ0QsQ0FBQyxDQUFDO0FBR0YsUUFBSSwwQkFBUyxXQUFXLEtBQUssU0FBUyxxQkFBcUI7QUFFMUQsV0FBSyxjQUFjLEtBQUssSUFBSSxVQUFVLEdBQUcsZUFBZSxDQUFDLE1BQVksUUFBZ0IsU0FBdUI7QUFFM0csWUFBSSxPQUFPLGVBQWUsRUFBRSxVQUFVO0FBQUc7QUFDekMsWUFBSSxZQUFZLE9BQU8sZUFBZSxFQUFFO0FBQ3hDLFlBQUksV0FBVyxPQUFPLGFBQWE7QUFHbkMsWUFBSSxZQUFVLE1BQ2Q7QUFDQyxpQkFBTyxhQUFhLFVBQVUsUUFBUSxVQUFVLE1BQU07QUFBQSxRQUN2RDtBQUFBLE1BQ0QsQ0FBQyxDQUFDO0FBQUEsSUFDSDtBQWFBLFlBQVEsSUFBSSw0QkFBNEI7QUFBQSxFQUN6QztBQUFBLEVBRUEsV0FBVztBQUNWLFlBQVEsSUFBSSw4QkFBOEI7QUFBQSxFQUMzQztBQUFBLEVBd1dBLE1BQU0sWUFBWSxRQUErQjtBQUNoRCxRQUFJLGdCQUFnQixNQUFNLFVBQVUsVUFBVSxTQUFTO0FBQ3ZELFFBQUksa0JBQWtCLFFBQVEsa0JBQWtCO0FBQUk7QUFFcEQsUUFBSSxLQUFLLFNBQVM7QUFBTyxjQUFRLElBQUksZ0JBQWdCO0FBQ3JELFVBQU0sYUFBYSxPQUFPO0FBQzFCLFFBQUksZ0JBQWdCLFdBQVcsTUFBTSxVQUFVLFNBQVMsRUFBRTtBQUMxRCxlQUFXLFNBQVM7QUFBQSxNQUNuQixTQUFTLEVBQUUsTUFBTSxjQUFjLE1BQU0sSUFBSSxjQUFjLElBQUksUUFBUSxjQUFjO0FBQUEsTUFDakYsV0FBVyxFQUFDLFFBQVEsY0FBYyxPQUFPLGNBQWMsT0FBTTtBQUFBLE1BQzdELFdBQVc7QUFBQSxJQUNaLENBQUM7QUFBQSxFQUNGO0FBQUEsRUE2V0EsdUJBQWdDO0FBQy9CLFFBQUksS0FBSyxxQkFBcUIsSUFBSTtBQUNqQyxVQUFJLE9BQU8sS0FBSyxJQUFJLFVBQVUsY0FBYztBQUM1QyxVQUFJLFFBQVEsUUFBUSxLQUFLLHFCQUFxQixLQUFLLE1BQU07QUFDeEQsYUFBSyxvQkFBb0IsS0FBSztBQUFBLE1BQy9CLE9BQ0s7QUFDSixlQUFPO0FBQUEsTUFDUjtBQUFBLElBQ0Q7QUFDQSxRQUFJLGVBQWUsS0FBSyxTQUFTLGFBQWEsTUFBTSxJQUFJO0FBQ3hELGFBQVMsU0FBUyxjQUFjO0FBQy9CLFVBQUksTUFBTSxPQUFPLENBQUMsS0FBSztBQUFLLGdCQUFRLE1BQU0sVUFBVSxDQUFDO0FBQ3JELFVBQUksS0FBSyxxQkFBcUI7QUFBTyxlQUFPO0FBQzVDLFVBQUksTUFBTSxNQUFNO0FBQ2hCLFVBQUksS0FBSyxrQkFBa0IsVUFBVSxHQUFHLEdBQUcsS0FBSyxTQUFVLE1BQUssa0JBQWtCLE9BQU8sR0FBRyxLQUFLLE9BQU8sS0FBSyxrQkFBa0IsT0FBTyxHQUFHLEtBQUssUUFDNUksTUFBTSxPQUFPLE1BQU0sQ0FBQyxLQUFLLE9BQU8sTUFBTSxPQUFPLE1BQU0sQ0FBQyxLQUFLLE9BQU87QUFDaEUsZUFBTztBQUFBLE1BQ1I7QUFBQSxJQUNEO0FBQ0EsV0FBTztBQUFBLEVBQ1I7QUFBQSxFQTBLQSx1QkFBdUI7QUFDdEIsU0FBSyxTQUFTLGFBQWEsQ0FBQyxLQUFLLFNBQVM7QUFDMUMsUUFBSSxTQUFTLEtBQUssU0FBUyxhQUFhLE9BQU87QUFDL0MsUUFBSSx3QkFBTywrQkFBK0IsU0FBUyxHQUFHO0FBQUEsRUFDdkQ7QUFBQSxFQUVBLGtCQUFrQixRQUFnQjtBQUNqQyxRQUFJLEtBQUssU0FBUztBQUFPLGNBQVEsSUFBSSwwQ0FBMEM7QUFDL0UsUUFBSSxPQUFPLHFCQUFxQixPQUFPLGFBQWEsS0FBSyxJQUFJO0FBQzVELFVBQUksV0FBVyxPQUFPLGFBQWE7QUFDbkMsVUFBSSxnQkFBZ0IsT0FBTyxlQUFlLEVBQUU7QUFDNUMsVUFBSSxTQUFTLGNBQWM7QUFDM0IsVUFBSSxPQUFPLGNBQWM7QUFFekIsVUFBSSxjQUFjLFVBQVUsV0FBVztBQUV2QyxVQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVMsT0FBTyxRQUFRLEtBQUssUUFBUSxPQUFPLEtBQUssS0FBSyxJQUFLO0FBQ2pGLFlBQUksT0FBTztBQUNYLGlCQUFTO0FBQ1QsZUFBTztBQUFBLE1BQ1I7QUFDQSxVQUFJLFVBQVUsT0FBTztBQUNyQixVQUFJLE9BQU8sTUFBTSxHQUFHO0FBQ25CLHNCQUFjLE9BQU87QUFDckIsbUJBQVc7QUFBQSxNQUNaO0FBQ0EsVUFBSSxLQUFLLE1BQU0sT0FBTyxRQUFRLEtBQUssSUFBSSxFQUFFLFFBQVE7QUFDaEQsc0JBQWMsY0FBYztBQUFBLE1BQzdCO0FBQ0EsYUFBTyxpQkFBaUIsV0FBVztBQUNuQyxhQUFPLFVBQVUsRUFBRSxNQUFNLFNBQVMsSUFBSSxFQUFFLENBQUM7QUFBQSxJQUMxQyxPQUNLO0FBQ0osVUFBSSxLQUFLLE9BQU8sVUFBVTtBQUMxQixVQUFJLFVBQVU7QUFDZCxVQUFJLFVBQVUsR0FBRztBQUNqQixVQUFJLEdBQUcsTUFBTSxHQUFHO0FBQ2Ysa0JBQVUsT0FBTztBQUNqQixtQkFBVztBQUFBLE1BQ1o7QUFDQSxVQUFJLEdBQUcsTUFBTSxPQUFPLFFBQVEsR0FBRyxJQUFJLEVBQUUsUUFBUTtBQUM1QyxrQkFBVSxVQUFVO0FBQUEsTUFDckI7QUFDQSxhQUFPLGFBQWEsU0FBUyxFQUFFO0FBQy9CLGFBQU8sVUFBVSxFQUFFLE1BQU0sU0FBUyxJQUFJLEVBQUUsQ0FBQztBQUFBLElBQzFDO0FBQUEsRUFFRDtBQUFBLEVBRUEsOEJBQThCO0FBQzdCLFNBQUssc0JBQXNCLElBQUksSUFBSSxLQUFLLDZCQUE2QjtBQUNyRSxhQUFTLElBQUksR0FBRyxJQUFJLEtBQUssU0FBUyxzQkFBc0IsUUFBUSxLQUFLO0FBQ3BFLFVBQUksVUFBVSxLQUFLLFNBQVMsc0JBQXNCO0FBQ2xELFVBQUksUUFBUSxLQUFLLFNBQVMsb0JBQW9CLEdBQUc7QUFDakQsVUFBSSxTQUFTLEtBQUssU0FBUyxvQkFBb0IsR0FBRztBQUVsRCxXQUFLLG9CQUFvQixJQUFJLFNBQVMsRUFBRSxNQUFNLE9BQU8sT0FBTyxPQUFPLENBQUM7QUFBQSxJQUNyRTtBQUFBLEVBQ0Q7QUFBQSxFQUVBLHdCQUF3QixTQUFpQixNQUFjLE9BQXdCO0FBQzlFLFFBQUksS0FBSyxTQUFTLHNCQUFzQixTQUFTLE9BQU87QUFBRyxhQUFPO0FBQ2xFLFNBQUssU0FBUyxzQkFBc0IsS0FBSyxPQUFPO0FBQ2hELFNBQUssU0FBUyxvQkFBb0IsS0FBSyxFQUFFLE1BQVksTUFBYSxDQUFDO0FBQ25FLFNBQUssNEJBQTRCO0FBQ2pDLFdBQU87QUFBQSxFQUNSO0FBQUEsRUFFQSwyQkFBMkIsS0FBbUI7QUFDN0MsUUFBSSxNQUFNLEtBQUssT0FBTyxLQUFLLFNBQVMsc0JBQXNCO0FBQVE7QUFDbEUsU0FBSyxTQUFTLHNCQUFzQixPQUFPLEtBQUssQ0FBQztBQUNqRCxTQUFLLFNBQVMsb0JBQW9CLE9BQU8sS0FBSyxDQUFDO0FBQy9DLFNBQUssNEJBQTRCO0FBQUEsRUFDbEM7QUFBQSxFQUVBLDJCQUEyQixLQUFhLE1BQWMsT0FBZTtBQUNwRSxRQUFJLE1BQU0sS0FBSyxPQUFPLEtBQUssU0FBUyxzQkFBc0I7QUFBUTtBQUNsRSxTQUFLLFNBQVMsb0JBQW9CLEtBQUssT0FBTztBQUM5QyxTQUFLLFNBQVMsb0JBQW9CLEtBQUssUUFBUTtBQUMvQyxTQUFLLDRCQUE0QjtBQUFBLEVBQ2xDO0FBQUEsRUFFQSx3QkFBd0I7QUFDdkIsU0FBSyxrQkFBa0Isd0JBQXdCLEtBQUssU0FBUyxzQkFBc0I7QUFBQSxFQUNwRjtBQUFBLEVBRUEsa0JBQWtCLFFBQWdCLE9BQWU7QUFDaEQsU0FBSyxTQUFTLHVCQUF1QixLQUFLLENBQUMsUUFBUSxLQUFLLENBQUM7QUFDekQsU0FBSyxzQkFBc0I7QUFBQSxFQUM1QjtBQUFBLEVBRUEscUJBQXFCLEtBQWE7QUFDakMsUUFBSSxPQUFPLEtBQUssU0FBUyx1QkFBdUIsVUFBVSxNQUFNO0FBQUc7QUFDbkUsU0FBSyxTQUFTLHVCQUF1QixPQUFPLEtBQUssQ0FBQztBQUNsRCxTQUFLLHNCQUFzQjtBQUFBLEVBQzVCO0FBQUEsRUFFQSxxQkFBcUIsS0FBYSxRQUFnQixPQUFlO0FBQ2hFLFFBQUksT0FBTyxLQUFLLFNBQVMsdUJBQXVCLFVBQVUsTUFBTTtBQUFHO0FBQ25FLFNBQUssU0FBUyx1QkFBdUIsS0FBSyxLQUFLO0FBQy9DLFNBQUssU0FBUyx1QkFBdUIsS0FBSyxLQUFLO0FBQy9DLFNBQUssc0JBQXNCO0FBQUEsRUFDNUI7QUFBQSxFQUVBLHlCQUF5QjtBQUN4QixTQUFLLG1CQUFtQix3QkFBd0IsS0FBSyxTQUFTLHVCQUF1QjtBQUFBLEVBQ3RGO0FBQUEsRUFFQSxtQkFBbUIsUUFBZ0IsT0FBZTtBQUNqRCxTQUFLLFNBQVMsd0JBQXdCLEtBQUssQ0FBQyxRQUFRLEtBQUssQ0FBQztBQUMxRCxTQUFLLHVCQUF1QjtBQUFBLEVBQzdCO0FBQUEsRUFFQSxzQkFBc0IsS0FBYTtBQUNsQyxRQUFJLE9BQU8sS0FBSyxTQUFTLHdCQUF3QixVQUFVLE1BQU07QUFBRztBQUNwRSxTQUFLLFNBQVMsd0JBQXdCLE9BQU8sS0FBSyxDQUFDO0FBQ25ELFNBQUssdUJBQXVCO0FBQUEsRUFDN0I7QUFBQSxFQUVBLG9CQUF5QztBQUN4QyxVQUFNLE9BQU8sT0FBTyxhQUFhLFFBQVEsVUFBVTtBQUVuRCxRQUFJLHNCQUFzQixvQkFBSSxJQUFJO0FBQUEsTUFDakMsQ0FBQyxrQkFBa0Isd0JBQXdCO0FBQUEsTUFDM0MsQ0FBQyxvQkFBb0Isc0NBQXNDO0FBQUEsTUFDM0QsQ0FBQyxxQkFBcUIscURBQXFEO0FBQUEsTUFDM0UsQ0FBQyxvQkFBb0Isa0NBQWtDO0FBQUEsTUFDdkQsQ0FBQyxxQkFBcUIsbUJBQW1CO0FBQUEsTUFDekMsQ0FBQyxtQkFBbUIsc0JBQXNCO0FBQUEsSUFDM0MsQ0FBQztBQUVELFFBQUkseUJBQXlCLG9CQUFJLElBQUk7QUFBQSxNQUNwQyxDQUFDLGtCQUFrQixnQ0FBTztBQUFBLE1BQzFCLENBQUMsb0JBQW9CLCtEQUFhO0FBQUEsTUFDbEMsQ0FBQyxxQkFBcUIsdUZBQWlCO0FBQUEsTUFDdkMsQ0FBQyxvQkFBb0IsZ0NBQU87QUFBQSxNQUM1QixDQUFDLHFCQUFxQix3REFBVztBQUFBLE1BQ2pDLENBQUMsbUJBQW1CLHNDQUFRO0FBQUEsSUFDN0IsQ0FBQztBQUVELFFBQUksc0JBQXNCLG9CQUFJLElBQUk7QUFBQSxNQUNqQyxDQUFDLGtCQUFrQixnQ0FBTztBQUFBLE1BQzFCLENBQUMsb0JBQW9CLCtEQUFhO0FBQUEsTUFDbEMsQ0FBQyxxQkFBcUIsdUZBQWlCO0FBQUEsTUFDdkMsQ0FBQyxvQkFBb0IsZ0NBQU87QUFBQSxNQUM1QixDQUFDLHFCQUFxQix3REFBVztBQUFBLE1BQ2pDLENBQUMsbUJBQW1CLHNDQUFRO0FBQUEsSUFDN0IsQ0FBQztBQUVELFFBQUksbUJBQW1CO0FBQ3ZCLFFBQUksUUFBUSxNQUFNO0FBQ2pCLHlCQUFtQjtBQUFBLElBQ3BCLFdBQ1MsUUFBUSxTQUFTO0FBQ3pCLHlCQUFtQjtBQUFBLElBQ3BCO0FBRUEsV0FBTztBQUFBLEVBQ1I7QUFBQSxFQUVBLHNCQUFzQixLQUFhLFFBQWdCLE9BQWU7QUFDakUsUUFBSSxPQUFPLEtBQUssU0FBUyx3QkFBd0IsVUFBVSxNQUFNO0FBQUc7QUFDcEUsU0FBSyxTQUFTLHdCQUF3QixLQUFLLEtBQUs7QUFDaEQsU0FBSyxTQUFTLHdCQUF3QixLQUFLLEtBQUs7QUFDaEQsU0FBSyx1QkFBdUI7QUFBQSxFQUM3QjtBQUFBLEVBWUEsTUFBTSxlQUFlO0FBQ3BCLFNBQUssV0FBVyxPQUFPLE9BQU8sQ0FBQyxHQUFHLGtCQUFrQixNQUFNLEtBQUssU0FBUyxDQUFDO0FBQUEsRUFDMUU7QUFBQSxFQUVBLE1BQU0sZUFBZTtBQUNwQixVQUFNLEtBQUssU0FBUyxLQUFLLFFBQVE7QUFBQSxFQUNsQztBQUNEOyIsCiAgIm5hbWVzIjogW10KfQo=
|