FanficNotes/.obsidian/plugins/obsidian-regex-replace/main.js

321 lines
62 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const DEFAULT_SETTINGS = {
findText: '',
replaceText: '',
useRegEx: true,
selOnly: false,
caseInsensitive: false,
processLineBreak: false,
processTab: false,
prefillFind: false
};
// logThreshold: 0 ... only error messages
// 9 ... verbose output
const logThreshold = 9;
const logger = (logString, logLevel = 0) => { if (logLevel <= logThreshold)
console.log('RegexFiRe: ' + logString); };
class RegexFindReplacePlugin extends obsidian.Plugin {
onload() {
return __awaiter(this, void 0, void 0, function* () {
logger('Loading Plugin...', 9);
yield this.loadSettings();
this.addSettingTab(new RegexFindReplaceSettingTab(this.app, this));
this.addCommand({
id: 'obsidian-regex-replace',
name: 'Find and Replace using regular expressions',
editorCallback: (editor) => {
new FindAndReplaceModal(this.app, editor, this.settings, this).open();
},
});
});
}
onunload() {
logger('Bye!', 9);
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
logger('Loading Settings...', 6);
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
logger(' findVal: ' + this.settings.findText, 6);
logger(' replaceText: ' + this.settings.replaceText, 6);
logger(' caseInsensitive: ' + this.settings.caseInsensitive, 6);
logger(' processLineBreak: ' + this.settings.processLineBreak, 6);
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settings);
});
}
}
class FindAndReplaceModal extends obsidian.Modal {
constructor(app, editor, settings, plugin) {
super(app);
this.editor = editor;
this.settings = settings;
this.plugin = plugin;
}
onOpen() {
const { contentEl, titleEl, editor, modalEl } = this;
modalEl.addClass('find-replace-modal');
titleEl.setText('Regex Find/Replace');
const rowClass = 'row';
const divClass = 'div';
const noSelection = editor.getSelection() === '';
let regexFlags = 'gm';
if (this.settings.caseInsensitive)
regexFlags = regexFlags.concat('i');
logger('No text selected?: ' + noSelection, 9);
const addTextComponent = (label, placeholder, postfix = '') => {
const containerEl = document.createElement(divClass);
containerEl.addClass(rowClass);
const targetEl = document.createElement(divClass);
targetEl.addClass('input-wrapper');
const labelEl = document.createElement(divClass);
labelEl.addClass('input-label');
labelEl.setText(label);
const labelEl2 = document.createElement(divClass);
labelEl2.addClass('postfix-label');
labelEl2.setText(postfix);
containerEl.appendChild(labelEl);
containerEl.appendChild(targetEl);
containerEl.appendChild(labelEl2);
const component = new obsidian.TextComponent(targetEl);
component.setPlaceholder(placeholder);
contentEl.append(containerEl);
return [component, labelEl2];
};
const addToggleComponent = (label, tooltip, hide = false) => {
const containerEl = document.createElement(divClass);
containerEl.addClass(rowClass);
const targetEl = document.createElement(divClass);
targetEl.addClass(rowClass);
const component = new obsidian.ToggleComponent(targetEl);
component.setTooltip(tooltip);
const labelEl = document.createElement(divClass);
labelEl.addClass('check-label');
labelEl.setText(label);
containerEl.appendChild(labelEl);
containerEl.appendChild(targetEl);
if (!hide)
contentEl.appendChild(containerEl);
return component;
};
// Create input fields
const findRow = addTextComponent('Find:', 'e.g. (.*)', '/' + regexFlags);
const findInputComponent = findRow[0];
const findRegexFlags = findRow[1];
const replaceRow = addTextComponent('Replace:', 'e.g. $1', this.settings.processLineBreak ? '\\n=LF' : '');
const replaceWithInputComponent = replaceRow[0];
// Create and show regular expression toggle switch
const regToggleComponent = addToggleComponent('Use regular expressions', 'If enabled, regular expressions in the find field are processed as such, and regex groups might be addressed in the replace field');
// Update regex-flags label if regular expressions are enabled or disabled
regToggleComponent.onChange(regNew => {
if (regNew) {
findRegexFlags.setText('/' + regexFlags);
}
else {
findRegexFlags.setText('');
}
});
// Create and show selection toggle switch only if any text is selected
const selToggleComponent = addToggleComponent('Replace only in selection', 'If enabled, replaces only occurances in the currently selected text', noSelection);
// Create Buttons
const buttonContainerEl = document.createElement(divClass);
buttonContainerEl.addClass(rowClass);
const submitButtonTarget = document.createElement(divClass);
submitButtonTarget.addClass('button-wrapper');
submitButtonTarget.addClass(rowClass);
const cancelButtonTarget = document.createElement(divClass);
cancelButtonTarget.addClass('button-wrapper');
cancelButtonTarget.addClass(rowClass);
const submitButtonComponent = new obsidian.ButtonComponent(submitButtonTarget);
const cancelButtonComponent = new obsidian.ButtonComponent(cancelButtonTarget);
cancelButtonComponent.setButtonText('Cancel');
cancelButtonComponent.onClick(() => {
logger('Action cancelled.', 8);
this.close();
});
submitButtonComponent.setButtonText('Replace All');
submitButtonComponent.setCta();
submitButtonComponent.onClick(() => {
let resultString = 'No match';
let scope = '';
const searchString = findInputComponent.getValue();
let replaceString = replaceWithInputComponent.getValue();
const selectedText = editor.getSelection();
if (searchString === '') {
new obsidian.Notice('Nothing to search for!');
return;
}
// Replace line breaks in find-field if option is enabled
if (this.settings.processLineBreak) {
logger('Replacing linebreaks in replace-field', 9);
logger(' old: ' + replaceString, 9);
replaceString = replaceString.replace(/\\n/gm, '\n');
logger(' new: ' + replaceString, 9);
}
// Replace line breaks in find-field if option is enabled
if (this.settings.processTab) {
logger('Replacing tabs in replace-field', 9);
logger(' old: ' + replaceString, 9);
replaceString = replaceString.replace(/\\t/gm, '\t');
logger(' new: ' + replaceString, 9);
}
// Check if regular expressions should be used
if (regToggleComponent.getValue()) {
logger('USING regex with flags: ' + regexFlags, 8);
const searchRegex = new RegExp(searchString, regexFlags);
if (!selToggleComponent.getValue()) {
logger(' SCOPE: Full document', 9);
const documentText = editor.getValue();
const rresult = documentText.match(searchRegex);
if (rresult) {
editor.setValue(documentText.replace(searchRegex, replaceString));
resultString = `Made ${rresult.length} replacement(s) in document`;
}
}
else {
logger(' SCOPE: Selection', 9);
const rresult = selectedText.match(searchRegex);
if (rresult) {
editor.replaceSelection(selectedText.replace(searchRegex, replaceString));
resultString = `Made ${rresult.length} replacement(s) in selection`;
}
}
}
else {
logger('NOT using regex', 8);
let nrOfHits = 0;
if (!selToggleComponent.getValue()) {
logger(' SCOPE: Full document', 9);
scope = 'selection';
const documentText = editor.getValue();
const documentSplit = documentText.split(searchString);
nrOfHits = documentSplit.length - 1;
editor.setValue(documentSplit.join(replaceString));
}
else {
logger(' SCOPE: Selection', 9);
scope = 'document';
const selectedSplit = selectedText.split(searchString);
nrOfHits = selectedSplit.length - 1;
editor.replaceSelection(selectedSplit.join(replaceString));
}
resultString = `Made ${nrOfHits} replacement(s) in ${scope}`;
}
// Saving settings (find/replace text and toggle switch states)
this.settings.findText = searchString;
this.settings.replaceText = replaceString;
this.settings.useRegEx = regToggleComponent.getValue();
this.settings.selOnly = selToggleComponent.getValue();
this.plugin.saveData(this.settings);
this.close();
new obsidian.Notice(resultString);
});
// Apply settings
regToggleComponent.setValue(this.settings.useRegEx);
selToggleComponent.setValue(this.settings.selOnly);
replaceWithInputComponent.setValue(this.settings.replaceText);
// Check if the prefill find option is enabled and the selection does not contain linebreaks
if (this.settings.prefillFind && editor.getSelection().indexOf('\n') < 0 && !noSelection) {
logger('Found selection without linebreaks and option is enabled -> fill', 9);
findInputComponent.setValue(editor.getSelection());
selToggleComponent.setValue(false);
}
else {
logger('Restore find text', 9);
findInputComponent.setValue(this.settings.findText);
}
// Add button row to dialog
buttonContainerEl.appendChild(submitButtonTarget);
buttonContainerEl.appendChild(cancelButtonTarget);
contentEl.appendChild(buttonContainerEl);
// If no text is selected, disable selection-toggle-switch
if (noSelection)
selToggleComponent.setValue(false);
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
}
class RegexFindReplaceSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl('h4', { text: 'Regular Expression Settings' });
new obsidian.Setting(containerEl)
.setName('Case Insensitive')
.setDesc('When using regular expressions, apply the \'/i\' modifier for case insensitive search)')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.caseInsensitive)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
logger('Settings update: caseInsensitive: ' + value);
this.plugin.settings.caseInsensitive = value;
yield this.plugin.saveSettings();
})));
containerEl.createEl('h4', { text: 'General Settings' });
new obsidian.Setting(containerEl)
.setName('Process \\n as line break')
.setDesc('When \'\\n\' is used in the replace field, a \'line break\' will be inserted accordingly')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.processLineBreak)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
logger('Settings update: processLineBreak: ' + value);
this.plugin.settings.processLineBreak = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName('Prefill Find Field')
.setDesc('Copy the currently selected text (if any) into the \'Find\' text field. This setting is only applied if the selection does not contain linebreaks')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.prefillFind)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
logger('Settings update: prefillFind: ' + value);
this.plugin.settings.prefillFind = value;
yield this.plugin.saveSettings();
})));
}
}
module.exports = RegexFindReplacePlugin;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9tYWluLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfSk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuIiwiaW1wb3J0IHtcblx0QXBwLFxuXHRCdXR0b25Db21wb25lbnQsXG5cdEVkaXRvcixcblx0TW9kYWwsXG5cdE5vdGljZSxcblx0UGx1Z2luLFxuXHRUZXh0Q29tcG9uZW50LFxuXHRUb2dnbGVDb21wb25lbnQsXG5cdFBsdWdpblNldHRpbmdUYWIsXG5cdFNldHRpbmdcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbnRlcmZhY2UgUmZyUGx1Z2luU2V0dGluZ3Mge1xuXHRmaW5kVGV4dDogc3RyaW5nO1xuXHRyZXBsYWNlVGV4dDogc3RyaW5nO1xuXHR1c2VSZWdFeDogYm9vbGVhbjtcblx0c2VsT25seTogYm9vbGVhbjtcblx0Y2FzZUluc2Vuc2l0aXZlOiBib29sZWFuO1xuXHRwcm9jZXNzTGluZUJyZWFrOiBib29sZWFuO1xuXHRwcm9jZXNzVGFiOiBib29sZWFuO1xuXHRwcmVmaWxsRmluZDogYm9vbGVhbjtcbn1cblxuY29uc3QgREVGQVVMVF9TRVRUSU5HUzogUmZyUGx1Z2luU2V0dGluZ3MgPSB7XG5cdGZpbmRUZXh0OiAnJyxcblx0cmVwbGFjZVRleHQ6ICcnLFxuXHR1c2VSZWdFeDogdHJ1ZSxcblx0c2VsT25seTogZmFsc2UsXG5cdGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG5cdHByb2Nlc3NMaW5lQnJlYWs6IGZhbHNlLFxuXHRwcm9jZXNzVGFiOiBmYWxzZSxcblx0cHJlZmlsbEZpbmQ6IGZhbHNlXG59XG5cbi8vIGxvZ1RocmVzaG9sZDogMCAuLi4gb25seSBlcnJvciBtZXNzYWdlc1xuLy8gICAgICAgICAgICAgICA5IC4uLiB2ZXJib3NlIG91dHB1dFxuY29uc3QgbG9nVGhyZXNob2xkID0gOTtcbmNvbnN0IGxvZ2dlciA9IChsb2dTdHJpbmc6IHN0cmluZywgbG9nTGV2ZWw9MCk6IHZvaWQgPT4ge2lmIChsb2dMZXZlbCA8PSBsb2dUaHJlc2hvbGQpIGNvbnNvbGUubG9nICgnUmVnZXhGaVJlOiAnICsgbG9nU3RyaW5nKX07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlZ2V4RmluZFJlcGxhY2VQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogUmZyUGx1Z2luU2V0dGluZ3M7XG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGxvZ2dlcignTG9hZGluZyBQbHVnaW4uLi4nLCA5KTtcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xuXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBSZWdleEZpbmRSZXBsYWNlU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdvYnNpZGlhbi1yZWdleC1yZXBsYWNlJyxcblx0XHRcdG5hbWU6ICdGaW5kIGFuZCBSZXBsYWNlIHVzaW5nIHJlZ3VsYXIgZXhwcmVzc2lvbnMnLFxuXHRcdFx0ZWRpdG9yQ2FsbGJhY2s6IChlZGl0b3IpID0+IHtcblx0XHRcdFx0bmV3IEZpbmRBbmRSZXBsYWNlTW9kYWwodGhpcy5hcHAsIGVkaXRvciwgdGhpcy5zZXR0aW5ncywgdGhpcykub3BlbigpO1xuXHRcdFx0fSxcblx0XHR9KTtcblx0fVxuXG5cdG9udW5sb2FkKCkge1xuXHRcdGxvZ2dlcignQnllIScsIDkpO1xuXHR9XG5cblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdGxvZ2dlcignTG9hZGluZyBTZXR0aW5ncy4uLicsIDYpO1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHRcdGxvZ2dlcignICAgZmluZFZhbDogICAgICAgICAnICsgdGhpcy5zZXR0aW5ncy5maW5kVGV4dCwgNik7XG5cdFx0bG9nZ2VyKCcgICByZXBsYWNlVGV4dDogICAgICcgKyB0aGlzLnNldHRpbmdzLnJlcGxhY2VUZXh0LCA2KTtcblx0XHRsb2dnZXIoJyAgIGNhc2VJbnNlbnNpdGl2ZTogJyArIHRoaXMuc2V0dGluZ3MuY2FzZUluc2Vuc2l0aXZlLCA2KTtcblx0XHRsb2dnZXIoJyAgIHByb2Nlc3NMaW5lQnJlYWs6ICcgKyB0aGlzLnNldHRpbmdzLnByb2Nlc3NMaW5lQnJlYWssIDYpO1xuXG5cdH1cblxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxuXG59XG5cbmNsYXNzIEZpbmRBbmRSZXBsYWNlTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBlZGl0b3I6IEVkaXRvciwgc2V0dGluZ3M6IFJmclBsdWdpblNldHRpbmdzLCBwbHVnaW46IFBsdWdpbikge1xuXHRcdHN1cGVyKGFwcCk7XG5cdFx0dGhpcy5lZGl0b3IgPSBlZGl0b3I7XG5cdFx0dGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHR9XG5cblx0c2V0dGluZ3M6IFJmclBsdWdpblNldHRpbmdzO1xuXHRlZGl0b3I6IEVkaXRvcjtcblx0cGx1Z2luOiBQbHVnaW47XG5cblx0b25PcGVuKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsLCB0aXRsZUVsLCBlZGl0b3IsIG1vZGFsRWwgfSA9IHRoaXM7XG5cblx0XHRtb2RhbEVsLmFkZENsYXNzKCdmaW5kLXJlcGxhY2UtbW9kYWwnKTtcblx0XHR0aXRsZUVsLnNldFRleHQoJ1JlZ2V4IEZpbmQvUmVwbGFjZScpO1xuXG5cdFx0Y29uc3Qgcm93Q2xhc3MgPSAncm93Jztcblx0XHRjb25zdCBkaXZDbGFzcyA9ICdkaXYnO1xuXHRcdGNvbnN0IG5vU2VsZWN0aW9uID0gZWRpdG9yLmdldFNlbGVjdGlvbigpID09PSAnJztcblx0XHRsZXQgcmVnZXhGbGFncyA9ICdnbSc7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MuY2FzZUluc2Vuc2l0aXZlKSByZWdleEZsYWdzID0gcmVnZXhGbGFncy5jb25jYXQoJ2knKTtcblxuXHRcdGxvZ2dlcignTm8gdGV4dCBzZWxlY3RlZD86ICcgKyBub1NlbGVjdGlvbiwgOSk7XG5cblx0XHRjb25zdCBhZGRUZXh0Q29tcG9uZW50ID0gKGxhYmVsOiBzdHJpbmcsIHBsYWNlaG9sZGVyOiBzdHJpbmcsIHBvc3RmaXg9JycpOiBbVGV4dENvbXBvbmVudCwgSFRNTERpdkVsZW1lbnRdID0+IHtcblx0XHRcdGNvbnN0IGNvbnRhaW5lckVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHRjb250YWluZXJFbC5hZGRDbGFzcyhyb3dDbGFzcyk7XG5cblx0XHRcdGNvbnN0IHRhcmdldEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHR0YXJnZXRFbC5hZGRDbGFzcygnaW5wdXQtd3JhcHBlcicpO1xuXG5cdFx0XHRjb25zdCBsYWJlbEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHRsYWJlbEVsLmFkZENsYXNzKCdpbnB1dC1sYWJlbCcpO1xuXHRcdFx0bGFiZWxFbC5zZXRUZXh0KGxhYmVsKTtcblxuXHRcdFx0Y29uc3QgbGFiZWxFbDIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGRpdkNsYXNzKTtcblx0XHRcdGxhYmVsRWwyLmFkZENsYXNzKCdwb3N0Zml4LWxhYmVsJyk7XG5cdFx0XHRsYWJlbEVsMi5zZXRUZXh0KHBvc3RmaXgpO1xuXG5cdFx0XHRjb250YWluZXJFbC5hcHBlbmRDaGlsZChsYWJlbEVsKTtcblx0XHRcdGNvbnRhaW5lckVsLmFwcGVuZENoaWxkKHRhcmdldEVsKTtcblx0XHRcdGNvbnRhaW5lckVsLmFwcGVuZENoaWxkKGxhYmVsRWwyKTtcblxuXHRcdFx0Y29uc3QgY29tcG9uZW50ID0gbmV3IFRleHRDb21wb25lbnQodGFyZ2V0RWwpO1xuXHRcdFx0Y29tcG9uZW50LnNldFBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyKTtcblxuXHRcdFx0Y29udGVudEVsLmFwcGVuZChjb250YWluZXJFbCk7XG5cdFx0XHRyZXR1cm4gW2NvbXBvbmVudCwgbGFiZWxFbDJdO1xuXHRcdH07XG5cblx0XHRjb25zdCBhZGRUb2dnbGVDb21wb25lbnQgPSAobGFiZWw6IHN0cmluZywgdG9vbHRpcDogc3RyaW5nLCBoaWRlID0gZmFsc2UpOiBUb2dnbGVDb21wb25lbnQgPT4ge1xuXHRcdFx0Y29uc3QgY29udGFpbmVyRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGRpdkNsYXNzKTtcblx0XHRcdGNvbnRhaW5lckVsLmFkZENsYXNzKHJvd0NsYXNzKTtcblx0XG5cdFx0XHRjb25zdCB0YXJnZXRFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZGl2Q2xhc3MpO1xuXHRcdFx0dGFyZ2V0RWwuYWRkQ2xhc3Mocm93Q2xhc3MpO1xuXG5cdFx0XHRjb25zdCBjb21wb25lbnQgPSBuZXcgVG9nZ2xlQ29tcG9uZW50KHRhcmdldEVsKTtcblx0XHRcdGNvbXBvbmVudC5zZXRUb29sdGlwKHRvb2x0aXApO1xuXHRcblx0XHRcdGNvbnN0IGxhYmVsRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGRpdkNsYXNzKTtcblx0XHRcdGxhYmVsRWwuYWRkQ2xhc3MoJ2NoZWNrLWxhYmVsJyk7XG5cdFx0XHRsYWJlbEVsLnNldFRleHQobGFiZWwpO1xuXHRcblx0XHRcdGNvbnRhaW5lckVsLmFwcGVuZENoaWxkKGxhYmVsRWwpO1xuXHRcdFx0Y29udGFpbmVyRWwuYXBwZW5kQ2hpbGQodGFyZ2V0RWwpO1xuXHRcdFx0aWYgKCFoaWRlKSBjb250ZW50RWwuYXBwZW5kQ2hpbGQoY29udGFpbmVyRWwpO1xuXHRcdFx0cmV0dXJuIGNvbXBvbmVudDtcblx0XHR9O1xuXG5cdFx0Ly8gQ3JlYXRlIGlucHV0IGZpZWxkc1xuXHRcdGNvbnN0IGZpbmRSb3cgPSBhZGRUZXh0Q29tcG9uZW50KCdGaW5kOicsICdlLmcuICguKiknLCAnLycgKyByZWdleEZsYWdzKTtcblx0XHRjb25zdCBmaW5kSW5wdXRDb21wb25lbnQgPSBmaW5kUm93WzBdO1xuXHRcdGNvbnN0IGZpbmRSZWdleEZsYWdzID0gZmluZFJvd1sxXTtcblx0XHRjb25zdCByZXBsYWNlUm93ID0gYWRkVGV4dENvbXBvbmVudCgnUmVwbGFjZTonLCAnZS5nLiAkMScsIHRoaXMuc2V0dGluZ3MucHJvY2Vzc0xpbmVCcmVhayA/ICdcXFxcbj1MRicgOiAnJyk7XG5cdFx0Y29uc3QgcmVwbGFjZVdpdGhJbnB1dENvbXBvbmVudCA9IHJlcGxhY2VSb3dbMF07XG5cblx0XHQvLyBDcmVhdGUgYW5kIHNob3cgcmVndWxhciBleHByZXNzaW9uIHRvZ2dsZSBzd2l0Y2hcblx0XHRjb25zdCByZWdUb2dnbGVDb21wb25lbnQgPSBhZGRUb2dnbGVDb21wb25lbnQoJ1VzZSByZWd1bGFyIGV4cHJlc3Npb25zJywgJ0lmIGVuYWJsZWQsIHJlZ3VsYXIgZXhwcmVzc2lvbnMgaW4gdGhlIGZpbmQgZmllbGQgYXJlIHByb2Nlc3NlZCBhcyBzdWNoLCBhbmQgcmVnZXggZ3JvdXBzIG1pZ2h0IGJlIGFkZHJlc3NlZCBpbiB0aGUgcmVwbGFjZSBmaWVsZCcpO1xuXHRcdFxuXHRcdC8vIFVwZGF0ZSByZWdleC1mbGFncyBsYWJlbCBpZiByZWd1bGFyIGV4cHJlc3Npb25zIGFyZSBlbmFibGVkIG9yIGRpc2FibGVkXG5cdFx0cmVnVG9nZ2xlQ29tcG9uZW50Lm9uQ2hhbmdlKCByZWdOZXcgPT4ge1xuXHRcdFx0aWYgKHJlZ05ldykge1xuXHRcdFx0XHRmaW5kUmVnZXhGbGFncy5zZXRUZXh0KCcvJyArIHJlZ2V4RmxhZ3MpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdGZpbmRSZWdleEZsYWdzLnNldFRleHQoJycpO1xuXHRcdFx0fVxuXHRcdH0pXG5cblx0XHQvLyBDcmVhdGUgYW5kIHNob3cgc2VsZWN0aW9uIHRvZ2dsZSBzd2l0Y2ggb25seSBpZiBhbnkgdGV4dCBpcyBzZWxlY3RlZFxuXHRcdGNvbnN0IHNlbFRvZ2dsZUNvbXBvbmVudCA9IGFkZFRvZ2dsZUNvbXBvbmVudCgnUmVwbGFjZSBvbmx5IGluIHNlbGVjdGlvbicsICdJZiBlbmFibGVkLCByZXBsYWNlcyBvbmx5IG9jY3VyYW5jZXMgaW4gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCB0ZXh0Jywgbm9TZWxlY3Rpb24pO1xuXG5cdFx0Ly8gQ3JlYXRlIEJ1dHRvbnNcblx0XHRjb25zdCBidXR0b25Db250YWluZXJFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZGl2Q2xhc3MpO1xuXHRcdGJ1dHRvbkNvbnRhaW5lckVsLmFkZENsYXNzKHJvd0NsYXNzKTtcblxuXHRcdGNvbnN0IHN1Ym1pdEJ1dHRvblRhcmdldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZGl2Q2xhc3MpO1xuXHRcdHN1Ym1pdEJ1dHRvblRhcmdldC5hZGRDbGFzcygnYnV0dG9uLXdyYXBwZXInKTtcblx0XHRzdWJtaXRCdXR0b25UYXJnZXQuYWRkQ2xhc3Mocm93Q2xhc3MpO1xuXG5cdFx0Y29uc3QgY2FuY2VsQnV0dG9uVGFyZ2V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0Y2FuY2VsQnV0dG9uVGFyZ2V0LmFkZENsYXNzKCdidXR0b24td3JhcHBlcicpO1xuXHRcdGNhbmNlbEJ1dHRvblRhcmdldC5hZGRDbGFzcyhyb3dDbGFzcyk7XG5cblx0XHRjb25zdCBzdWJtaXRCdXR0b25Db21wb25lbnQgPSBuZXcgQnV0dG9uQ29tcG9uZW50KHN1Ym1pdEJ1dHRvblRhcmdldCk7XG5cdFx0Y29uc3QgY2FuY2VsQnV0dG9uQ29tcG9uZW50ID0gbmV3IEJ1dHRvbkNvbXBvbmVudChjYW5jZWxCdXR0b25UYXJnZXQpO1xuXHRcdFxuXHRcdGNhbmNlbEJ1dHRvbkNvbXBvbmVudC5zZXRCdXR0b25UZXh0KCdDYW5jZWwnKTtcblx0XHRjYW5jZWxCdXR0b25Db21wb25lbnQub25DbGljaygoKSA9PiB7XG5cdFx0XHRsb2dnZXIoJ0FjdGlvbiBjYW5jZWxsZWQuJywgOCk7XG5cdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0fSk7XG5cblx0XHRzdWJtaXRCdXR0b25Db21wb25lbnQuc2V0QnV0dG9uVGV4dCgnUmVwbGFjZSBBbGwnKTtcblx0XHRzdWJtaXRCdXR0b25Db21wb25lbnQuc2V0Q3RhKCk7XG5cdFx0c3VibWl0QnV0dG9uQ29tcG9uZW50Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0bGV0IHJlc3VsdFN0cmluZyA9ICdObyBtYXRjaCc7XG5cdFx0XHRsZXQgc2NvcGUgPSAnJztcblx0XHRcdGNvbnN0IHNlYXJjaFN0cmluZyA9IGZpbmRJbnB1dENvbXBvbmVudC5nZXRWYWx1ZSgpO1xuXHRcdFx0bGV0IHJlcGxhY2VTdHJpbmcgPSByZXBsYWNlV2l0aElucHV0Q29tcG9uZW50LmdldFZhbHVlKCk7XG5cdFx0XHRjb25zdCBzZWxlY3RlZFRleHQgPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCk7XG5cblx0XHRcdGlmIChzZWFyY2hTdHJpbmcgPT09ICcnKSB7XG5cdFx0XHRcdG5ldyBOb3RpY2UoJ05vdGhpbmcgdG8gc2VhcmNoIGZvciEnKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXBsYWNlIGxpbmUgYnJlYWtzIGluIGZpbmQtZmllbGQgaWYgb3B0aW9uIGlzIGVuYWJsZWRcblx0XHRcdGlmICh0aGlzLnNldHRpbmdzLnByb2Nlc3NMaW5lQnJlYWspIHtcblx0XHRcdFx0bG9nZ2VyKCdSZXBsYWNpbmcgbGluZWJyZWFrcyBpbiByZXBsYWNlLWZpZWxkJywgOSk7XG5cdFx0XHRcdGxvZ2dlcignICBvbGQ6ICcgKyByZXBsYWNlU3RyaW5nLCA5KTtcblx0XHRcdFx0cmVwbGFjZVN0cmluZyA9IHJlcGxhY2VTdHJpbmcucmVwbGFjZSgvXFxcXG4vZ20sICdcXG4nKTtcblx0XHRcdFx0bG9nZ2VyKCcgIG5ldzogJyArIHJlcGxhY2VTdHJpbmcsIDkpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXBsYWNlIGxpbmUgYnJlYWtzIGluIGZpbmQtZmllbGQgaWYgb3B0aW9uIGlzIGVuYWJsZWRcblx0XHRcdGlmICh0aGlzLnNldHRpbmdzLnByb2Nlc3NUYWIpIHtcblx0XHRcdFx0bG9nZ2VyKCdSZXBsYWNpbmcgdGFicyBpbiByZXBsYWNlLWZpZWxkJywgOSk7XG5cdFx0XHRcdGxvZ2dlcignICBvbGQ6ICcgKyByZXBsYWNlU3RyaW5nLCA5KTtcblx0XHRcdFx0cmVwbGFjZVN0cmluZyA9IHJlcGxhY2VTdHJpbmcucmVwbGFjZSgvXFxcXHQvZ20sICdcXHQnKTtcblx0XHRcdFx0bG9nZ2VyKCcgIG5ldzogJyArIHJlcGxhY2VTdHJpbmcsIDkpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDaGVjayBpZiByZWd1bGFyIGV4cHJlc3Npb25zIHNob3VsZCBiZSB1c2VkXG5cdFx0XHRpZihyZWdUb2dnbGVDb21wb25lbnQuZ2V0VmFsdWUoKSkge1xuXHRcdFx0XHRsb2dnZXIoJ1VTSU5HIHJlZ2V4IHdpdGggZmxhZ3M6ICcgKyByZWdleEZsYWdzLCA4KTtcblxuXHRcdFx0XHRjb25zdCBzZWFyY2hSZWdleCA9IG5ldyBSZWdFeHAoc2VhcmNoU3RyaW5nLCByZWdleEZsYWdzKTtcblx0XHRcdFx0aWYoIXNlbFRvZ2dsZUNvbXBvbmVudC5nZXRWYWx1ZSgpKSB7XG5cdFx0XHRcdFx0bG9nZ2VyKCcgICBTQ09QRTogRnVsbCBkb2N1bWVudCcsIDkpO1xuXHRcdFx0XHRcdGNvbnN0IGRvY3VtZW50VGV4dCA9IGVkaXRvci5nZXRWYWx1ZSgpO1xuXHRcdFx0XHRcdGNvbnN0IHJyZXN1bHQgPSBkb2N1bWVudFRleHQubWF0Y2goc2VhcmNoUmVnZXgpO1xuXHRcdFx0XHRcdGlmIChycmVzdWx0KSB7XG5cdFx0XHRcdFx0XHRlZGl0b3Iuc2V0VmFsdWUoZG9jdW1lbnRUZXh0LnJlcGxhY2Uoc2VhcmNoUmVnZXgsIHJlcGxhY2VTdHJpbmcpKTtcblx0XHRcdFx0XHRcdHJlc3VsdFN0cmluZyA9IGBNYWRlICR7cnJlc3VsdC5sZW5ndGh9IHJlcGxhY2VtZW50KHMpIGluIGRvY3VtZW50YDtcdFx0XHRcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0bG9nZ2VyKCcgICBTQ09QRTogU2VsZWN0aW9uJywgOSk7XG5cdFx0XHRcdFx0Y29uc3QgcnJlc3VsdCA9IHNlbGVjdGVkVGV4dC5tYXRjaChzZWFyY2hSZWdleCk7XG5cdFx0XHRcdFx0aWYgKHJyZXN1bHQpIHtcblx0XHRcdFx0XHRcdGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKHNlbGVjdGVkVGV4dC5yZXBsYWNlKHNlYXJjaFJlZ2V4LCByZXBsYWNlU3RyaW5nKSk7XHRcblx0XHRcdFx0XHRcdHJlc3VsdFN0cmluZyA9IGBNYWRlICR7cnJlc3VsdC5sZW5ndGh9IHJlcGxhY2VtZW50KHMpIGluIHNlbGVjdGlvbmA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0bG9nZ2VyKCdOT1QgdXNpbmcgcmVnZXgnLCA4KTtcblx0XHRcdFx0bGV0IG5yT2ZIaXRzID0gMDtcblx0XHRcdFx0aWYoIXNlbFRvZ2dsZUNvbXBvbmVudC5nZXRWYWx1ZSgpKSB7XG5cdFx0XHRcdFx0bG9nZ2VyKCcgICBTQ09QRTogRnVsbCBkb2N1bWVudCcsIDkpO1xuXHRcdFx0XHRcdHNjb3BlID0gJ3NlbGVjdGlvbidcblx0XHRcdFx0XHRjb25zdCBkb2N1bWVudFRleHQgPSBlZGl0b3IuZ2V0VmFsdWUoKTtcblx0XHRcdFx0XHRjb25zdCBkb2N1bWVudFNwbGl0ID0gZG9jdW1lbnRUZXh0LnNwbGl0KHNlYXJjaFN0cmluZyk7XG5cdFx0XHRcdFx0bnJPZkhpdHMgPSBkb2N1bWVudFNwbGl0Lmxlbmd0aCAtIDE7XG5cdFx0XHRcdFx0ZWRpdG9yLnNldFZhbHVlKGRvY3VtZW50U3BsaXQuam9pbihyZXBsYWNlU3RyaW5nKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0bG9nZ2VyKCcgICBTQ09QRTogU2VsZWN0aW9uJywgOSk7XG5cdFx0XHRcdFx0c2NvcGUgPSAnZG9jdW1lbnQnO1xuXHRcdFx0XHRcdGNvbnN0IHNlbGVjdGVkU3BsaXQgPSBzZWxlY3RlZFRleHQuc3BsaXQoc2VhcmNoU3RyaW5nKTtcblx0XHRcdFx0XHRuck9mSGl0cyA9IHNlbGVjdGVkU3BsaXQubGVuZ3RoIC0gMTtcblx0XHRcdFx0XHRlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihzZWxlY3RlZFNwbGl0LmpvaW4ocmVwbGFjZVN0cmluZykpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJlc3VsdFN0cmluZyA9IGBNYWRlICR7bnJPZkhpdHN9IHJlcGxhY2VtZW50KHMpIGluICR7c2NvcGV9YDtcblx0XHRcdH0gXHRcdFxuXHRcdFx0XG5cdFx0XHQvLyBTYXZpbmcgc2V0dGluZ3MgKGZpbmQvcmVwbGFjZSB0ZXh0IGFuZCB0b2dnbGUgc3dpdGNoIHN0YXRlcylcblx0XHRcdHRoaXMuc2V0dGluZ3MuZmluZFRleHQgPSBzZWFyY2hTdHJpbmc7XG5cdFx0XHR0aGlzLnNldHRpbmdzLnJlcGxhY2VUZXh0ID0gcmVwbGFjZVN0cmluZztcblx0XHRcdHRoaXMuc2V0dGluZ3MudXNlUmVnRXggPSByZWdUb2dnbGVDb21wb25lbnQuZ2V0VmFsdWUoKTtcblx0XHRcdHRoaXMuc2V0dGluZ3Muc2VsT25seSA9IHNlbFRvZ2dsZUNvbXBvbmVudC5nZXRWYWx1ZSgpO1xuXHRcdFx0dGhpcy5wbHVnaW4uc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XG5cblx0XHRcdHRoaXMuY2xvc2UoKTtcblx0XHRcdG5ldyBOb3RpY2UocmVzdWx0U3RyaW5nKTtcdFx0XHRcdFx0XG5cdFx0fSk7XG5cblx0XHQvLyBBcHBseSBzZXR0aW5nc1xuXHRcdHJlZ1RvZ2dsZUNvbXBvbmVudC5zZXRWYWx1ZSh0aGlzLnNldHRpbmdzLnVzZVJlZ0V4KTtcblx0XHRzZWxUb2dnbGVDb21wb25lbnQuc2V0VmFsdWUodGhpcy5zZXR0aW5ncy5zZWxPbmx5KTtcblx0XHRyZXBsYWNlV2l0aElucHV0Q29tcG9uZW50LnNldFZhbHVlKHRoaXMuc2V0dGluZ3MucmVwbGFjZVRleHQpO1xuXHRcdFxuXHRcdC8vIENoZWNrIGlmIHRoZSBwcmVmaWxsIGZpbmQgb3B0aW9uIGlzIGVuYWJsZWQgYW5kIHRoZSBzZWxlY3Rpb24gZG9lcyBub3QgY29udGFpbiBsaW5lYnJlYWtzXG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MucHJlZmlsbEZpbmQgJiYgZWRpdG9yLmdldFNlbGVjdGlvbigpLmluZGV4T2YoJ1xcbicpIDwgMCAmJiAhbm9TZWxlY3Rpb24pIHtcblx0XHRcdGxvZ2dlcignRm91bmQgc2VsZWN0aW9uIHdpdGhvdXQgbGluZWJyZWFrcyBhbmQgb3B0aW9uIGlzIGVuYWJsZWQgLT4gZmlsbCcsOSk7XG5cdFx0XHRmaW5kSW5wdXRDb21wb25lbnQuc2V0VmFsdWUoZWRpdG9yLmdldFNlbGVjdGlvbigpKTtcblx0XHRcdHNlbFRvZ2dsZUNvbXBvbmVudC5zZXRWYWx1ZShmYWxzZSk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0bG9nZ2VyKCdSZXN0b3JlIGZpbmQgdGV4dCcsIDkpO1xuXHRcdFx0ZmluZElucHV0Q29tcG9uZW50LnNldFZhbHVlKHRoaXMuc2V0dGluZ3MuZmluZFRleHQpO1xuXHRcdH1cblx0XHRcblx0XHQvLyBBZGQgYnV0dG9uIHJvdyB0byBkaWFsb2dcblx0XHRidXR0b25Db250YWluZXJFbC5hcHBlbmRDaGlsZChzdWJtaXRCdXR0b25UYXJnZXQpO1xuXHRcdGJ1dHRvbkNvbnRhaW5lckVsLmFwcGVuZENoaWxkKGNhbmNlbEJ1dHRvblRhcmdldCk7XG5cdFx0Y29udGVudEVsLmFwcGVuZENoaWxkKGJ1dHRvbkNvbnRhaW5lckVsKTtcblxuXHRcdC8vIElmIG5vIHRleHQgaXMgc2VsZWN0ZWQsIGRpc2FibGUgc2VsZWN0aW9uLXRvZ2dsZS1zd2l0Y2hcblx0XHRpZiAobm9TZWxlY3Rpb24pIHNlbFRvZ2dsZUNvbXBvbmVudC5zZXRWYWx1ZShmYWxzZSk7XG5cdH1cblx0XG5cdG9uQ2xvc2UoKSB7XG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XG5cdH1cbn1cblxuY2xhc3MgUmVnZXhGaW5kUmVwbGFjZVNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBSZWdleEZpbmRSZXBsYWNlUGx1Z2luO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IFJlZ2V4RmluZFJlcGxhY2VQbHVnaW4pIHtcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRkaXNwbGF5KCk6IHZvaWQge1xuXHRcdGNvbnN0IHtjb250YWluZXJFbH0gPSB0aGlzO1xuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDQnLCB7dGV4dDogJ1JlZ3VsYXIgRXhwcmVzc2lvbiBTZXR0aW5ncyd9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ0Nhc2UgSW5zZW5zaXRpdmUnKVxuXHRcdFx0LnNldERlc2MoJ1doZW4gdXNpbmcgcmVndWxhciBleHByZXNzaW9ucywgYXBwbHkgdGhlIFxcJy9pXFwnIG1vZGlmaWVyIGZvciBjYXNlIGluc2Vuc2l0aXZlIHNlYXJjaCknKVxuXHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4gdG9nZ2xlXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5jYXNlSW5zZW5zaXRpdmUpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHRsb2dnZXIoJ1NldHRpbmdzIHVwZGF0ZTogY2FzZUluc2Vuc2l0aXZlOiAnICsgdmFsdWUpO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmNhc2VJbnNlbnNpdGl2ZSA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KSk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDQnLCB7dGV4dDogJ0dlbmVyYWwgU2V0dGluZ3MnfSk7XG5cblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1Byb2Nlc3MgXFxcXG4gYXMgbGluZSBicmVhaycpXG5cdFx0XHQuc2V0RGVzYygnV2hlbiBcXCdcXFxcblxcJyBpcyB1c2VkIGluIHRoZSByZXBsYWNlIGZpZWxkLCBhIFxcJ2xpbmUgYnJlYWtcXCcgd2lsbCBiZSBpbnNlcnRlZCBhY2NvcmRpbmdseScpXG5cdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB0b2dnbGVcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnByb2Nlc3NMaW5lQnJlYWspXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHRsb2dnZXIoJ1NldHRpbmdzIHVwZGF0ZTogcHJvY2Vzc0xpbmVCcmVhazogJyArIHZhbHVlKTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5wcm9jZXNzTGluZUJyZWFrID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pKTtcblxuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnUHJlZmlsbCBGaW5kIEZpZWxkJylcblx0XHRcdC5zZXREZXNjKCdDb3B5IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgdGV4dCAoaWYgYW55KSBpbnRvIHRoZSBcXCdGaW5kXFwnIHRleHQgZmllbGQuIFRoaXMgc2V0dGluZyBpcyBvbmx5IGFwcGxpZWQgaWYgdGhlIHNlbGVjdGlvbiBkb2VzIG5vdCBjb250YWluIGxpbmVicmVha3MnKVxuXHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4gdG9nZ2xlXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5wcmVmaWxsRmluZClcblx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdGxvZ2dlcignU2V0dGluZ3MgdXBkYXRlOiBwcmVmaWxsRmluZDogJyArIHZhbHVlKTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5wcmVmaWxsRmluZCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KSk7XG5cdH1cbn0iXSwibmFtZXMiOlsiUGx1Z2luIiwiTW9kYWwiLCJUZXh0Q29tcG9uZW50IiwiVG9nZ2xlQ29tcG9uZW50IiwiQnV0dG9uQ29tcG9uZW50IiwiTm90aWNlIiwiUGx1Z2luU2V0dGluZ1RhYiIsIlNldHRpbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF1REE7QUFDTyxTQUFTLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUU7QUFDN0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTyxFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEgsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDL0QsUUFBUSxTQUFTLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ25HLFFBQVEsU0FBUyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3RHLFFBQVEsU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUFFO0FBQ3RILFFBQVEsSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFVBQVUsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzlFLEtBQUssQ0FBQyxDQUFDO0FBQ1A7O0FDckRBLE1BQU0sZ0JBQWdCLEdBQXNCO0lBQzNDLFFBQVEsRUFBRSxFQUFFO0lBQ1osV0FBVyxFQUFFLEVBQUU7SUFDZixRQUFRLEVBQUUsSUFBSTtJQUNkLE9BQU8sRUFBRSxLQUFLO0lBQ2QsZUFBZSxFQUFFLEtBQUs7SUFDdEIsZ0JBQWdCLEVBQUUsS0FBSztJQUN2QixVQUFVLEVBQUUsS0FBSztJQUNqQixXQUFXLEVBQUUsS0FBSztDQUNsQixDQUFBO0FBRUQ7QUFDQTtBQUNBLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLE1BQU0sR0FBRyxDQUFDLFNBQWlCLEVBQUUsUUFBUSxHQUFDLENBQUMsT0FBWSxJQUFJLFFBQVEsSUFBSSxZQUFZO0lBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBRSxhQUFhLEdBQUcsU0FBUyxDQUFDLENBQUEsRUFBQyxDQUFDO01BRTNHLHNCQUF1QixTQUFRQSxlQUFNO0lBR25ELE1BQU07O1lBQ1gsTUFBTSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRTFCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSwwQkFBMEIsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7WUFHbkUsSUFBSSxDQUFDLFVBQVUsQ0FBQztnQkFDZixFQUFFLEVBQUUsd0JBQXdCO2dCQUM1QixJQUFJLEVBQUUsNENBQTRDO2dCQUNsRCxjQUFjLEVBQUUsQ0FBQyxNQUFNO29CQUN0QixJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7aUJBQ3RFO2FBQ0QsQ0FBQyxDQUFDO1NBQ0g7S0FBQTtJQUVELFFBQVE7UUFDUCxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0tBQ2xCO0lBRUssWUFBWTs7WUFDakIsTUFBTSxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUMzRSxNQUFNLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0QsTUFBTSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNsRSxNQUFNLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUVwRTtLQUFBO0lBRUssWUFBWTs7WUFDakIsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNuQztLQUFBO0NBRUQ7QUFFRCxNQUFNLG1CQUFvQixTQUFRQyxjQUFLO0lBQ3RDLFlBQVksR0FBUSxFQUFFLE1BQWMsRUFBRSxRQUEyQixFQUFFLE1BQWM7UUFDaEYsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7S0FDckI7SUFNRCxNQUFNO1FBQ0wsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQztRQUVyRCxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDdkMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBRXRDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN2QixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdkIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUNqRCxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWU7WUFBRSxVQUFVLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV2RSxNQUFNLENBQUMscUJBQXFCLEdBQUcsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRS9DLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFhLEVBQUUsV0FBbUIsRUFBRSxPQUFPLEdBQUMsRUFBRTtZQUN2RSxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JELFdBQVcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFL0IsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRCxRQUFRLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRW5DLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXZCLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbEQsUUFBUSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNuQyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRTFCLFdBQVcsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDakMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsQyxXQUFXLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRWxDLE1BQU0sU0FBUyxHQUFHLElBQUlDLHNCQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUV0QyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7U0FDN0IsQ0FBQztRQUVGLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxLQUFhLEVBQUUsT0FBZSxFQUFFLElBQUksR0FBRyxLQUFLO1lBQ3ZFLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckQsV0FBVyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUvQixNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xELFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFNUIsTUFBTSxTQUFTLEdBQUcsSUFBSUMsd0JBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNoRCxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRTlCLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXZCLFdBQVcsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDakMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsSUFBSTtnQkFBRSxTQUFTLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlDLE9BQU8sU0FBUyxDQUFDO1NBQ2pCLENBQUM7O1FBR0YsTUFBTSxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxHQUFHLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFDekUsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEMsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxRQUFRLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDM0csTUFBTSx5QkFBeUIsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7O1FBR2hELE1BQU0sa0JBQWtCLEdBQUcsa0JBQWtCLENBQUMseUJBQXlCLEVBQUUsbUlBQW1JLENBQUMsQ0FBQzs7UUFHOU0sa0JBQWtCLENBQUMsUUFBUSxDQUFFLE1BQU07WUFDbEMsSUFBSSxNQUFNLEVBQUU7Z0JBQ1gsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsVUFBVSxDQUFDLENBQUM7YUFDekM7aUJBQ0k7Z0JBQ0osY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUMzQjtTQUNELENBQUMsQ0FBQTs7UUFHRixNQUFNLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDLDJCQUEyQixFQUFFLHFFQUFxRSxFQUFFLFdBQVcsQ0FBQyxDQUFDOztRQUcvSixNQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0QsaUJBQWlCLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXJDLE1BQU0sa0JBQWtCLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1RCxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUM5QyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFdEMsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVELGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzlDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV0QyxNQUFNLHFCQUFxQixHQUFHLElBQUlDLHdCQUFlLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN0RSxNQUFNLHFCQUFxQixHQUFHLElBQUlBLHdCQUFlLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUV0RSxxQkFBcUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUMscUJBQXFCLENBQUMsT0FBTyxDQUFDO1lBQzdCLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDYixDQUFDLENBQUM7UUFFSCxxQkFBcUIsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDbkQscUJBQXFCLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0IscUJBQXFCLENBQUMsT0FBTyxDQUFDO1lBQzdCLElBQUksWUFBWSxHQUFHLFVBQVUsQ0FBQztZQUM5QixJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDZixNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNuRCxJQUFJLGFBQWEsR0FBRyx5QkFBeUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN6RCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFM0MsSUFBSSxZQUFZLEtBQUssRUFBRSxFQUFFO2dCQUN4QixJQUFJQyxlQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztnQkFDckMsT0FBTzthQUNQOztZQUdELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDbkMsTUFBTSxDQUFDLHVDQUF1QyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNuRCxNQUFNLENBQUMsU0FBUyxHQUFHLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDckMsYUFBYSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNyRCxNQUFNLENBQUMsU0FBUyxHQUFHLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUNyQzs7WUFHRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFO2dCQUM3QixNQUFNLENBQUMsaUNBQWlDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNyQyxhQUFhLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3JELE1BQU0sQ0FBQyxTQUFTLEdBQUcsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ3JDOztZQUdELElBQUcsa0JBQWtCLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ2pDLE1BQU0sQ0FBQywwQkFBMEIsR0FBRyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBRW5ELE1BQU0sV0FBVyxHQUFHLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDekQsSUFBRyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxFQUFFO29CQUNsQyxNQUFNLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ3JDLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDdkMsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDaEQsSUFBSSxPQUFPLEVBQUU7d0JBQ1osTUFBTSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDO3dCQUNsRSxZQUFZLEdBQUcsUUFBUSxPQUFPLENBQUMsTUFBTSw2QkFBNkIsQ0FBQztxQkFDbkU7aUJBQ0Q7cUJBQ0k7b0JBQ0osTUFBTSxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNqQyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUNoRCxJQUFJLE9BQU8sRUFBRTt3QkFDWixNQUFNLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQzt3QkFDMUUsWUFBWSxHQUFHLFFBQVEsT0FBTyxDQUFDLE1BQU0sOEJBQThCLENBQUM7cUJBQ3BFO2lCQUNEO2FBQ0Q7aUJBQ0k7Z0JBQ0osTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUM3QixJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7Z0JBQ2pCLElBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsRUFBRTtvQkFDbEMsTUFBTSxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNyQyxLQUFLLEdBQUcsV0FBVyxDQUFBO29CQUNuQixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3ZDLE1BQU0sYUFBYSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3ZELFFBQVEsR0FBRyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztvQkFDcEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7aUJBQ25EO3FCQUNJO29CQUNKLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDakMsS0FBSyxHQUFHLFVBQVUsQ0FBQztvQkFDbkIsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDdkQsUUFBUSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUNwQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO2lCQUMzRDtnQkFDRCxZQUFZLEdBQUcsUUFBUSxRQUFRLHNCQUFzQixLQUFLLEVBQUUsQ0FBQzthQUM3RDs7WUFHRCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxZQUFZLENBQUM7WUFDdEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEdBQUcsYUFBYSxDQUFDO1lBQzFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3RELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUVwQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDYixJQUFJQSxlQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDekIsQ0FBQyxDQUFDOztRQUdILGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BELGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25ELHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDOztRQUc5RCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3pGLE1BQU0sQ0FBQyxrRUFBa0UsRUFBQyxDQUFDLENBQUMsQ0FBQztZQUM3RSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDbkQsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ25DO2FBQ0k7WUFDSixNQUFNLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0Isa0JBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDcEQ7O1FBR0QsaUJBQWlCLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDbEQsaUJBQWlCLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDbEQsU0FBUyxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDOztRQUd6QyxJQUFJLFdBQVc7WUFBRSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDcEQ7SUFFRCxPQUFPO1FBQ04sTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQztRQUMzQixTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7S0FDbEI7Q0FDRDtBQUVELE1BQU0sMEJBQTJCLFNBQVFDLHlCQUFnQjtJQUd4RCxZQUFZLEdBQVEsRUFBRSxNQUE4QjtRQUNuRCxLQUFLLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0tBQ3JCO0lBRUQsT0FBTztRQUNOLE1BQU0sRUFBQyxXQUFXLEVBQUMsR0FBRyxJQUFJLENBQUM7UUFDM0IsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRXBCLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLDZCQUE2QixFQUFDLENBQUMsQ0FBQztRQUVsRSxJQUFJQyxnQkFBTyxDQUFDLFdBQVcsQ0FBQzthQUN0QixPQUFPLENBQUMsa0JBQWtCLENBQUM7YUFDM0IsT0FBTyxDQUFDLHdGQUF3RixDQUFDO2FBQ2pHLFNBQVMsQ0FBQyxNQUFNLElBQUksTUFBTTthQUN6QixRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDO2FBQzlDLFFBQVEsQ0FBQyxDQUFPLEtBQUs7WUFDckIsTUFBTSxDQUFDLG9DQUFvQyxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDN0MsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ2pDLENBQUEsQ0FBQyxDQUFDLENBQUM7UUFFTixXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBQyxDQUFDLENBQUM7UUFHdkQsSUFBSUEsZ0JBQU8sQ0FBQyxXQUFXLENBQUM7YUFDdEIsT0FBTyxDQUFDLDJCQUEyQixDQUFDO2FBQ3BDLE9BQU8sQ0FBQywwRkFBMEYsQ0FBQzthQUNuRyxTQUFTLENBQUMsTUFBTSxJQUFJLE1BQU07YUFDekIsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDO2FBQy9DLFFBQVEsQ0FBQyxDQUFPLEtBQUs7WUFDckIsTUFBTSxDQUFDLHFDQUFxQyxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztZQUM5QyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDakMsQ0FBQSxDQUFDLENBQUMsQ0FBQztRQUdOLElBQUlBLGdCQUFPLENBQUMsV0FBVyxDQUFDO2FBQ3RCLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQzthQUM3QixPQUFPLENBQUMsbUpBQW1KLENBQUM7YUFDNUosU0FBUyxDQUFDLE1BQU0sSUFBSSxNQUFNO2FBQ3pCLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7YUFDMUMsUUFBUSxDQUFDLENBQU8sS0FBSztZQUNyQixNQUFNLENBQUMsZ0NBQWdDLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztZQUN6QyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDakMsQ0FBQSxDQUFDLENBQUMsQ0FBQztLQUNOOzs7OzsifQ==