257 lines
52 KiB
JavaScript
257 lines
52 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
|
|
};
|
|
// logThreshold: 0 ... only error messages
|
|
// 9 ... verbose output
|
|
const logThreshold = 9;
|
|
const logger = (logString, logLevel = 0) => { if (logLevel <= logThreshold)
|
|
console.log('RegexFR: ' + 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) => {
|
|
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);
|
|
containerEl.appendChild(labelEl);
|
|
containerEl.appendChild(targetEl);
|
|
const component = new obsidian.TextComponent(targetEl);
|
|
component.setPlaceholder(placeholder);
|
|
contentEl.append(containerEl);
|
|
return component;
|
|
};
|
|
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 findInputComponent = addTextComponent('Find:', 'e.g. (.*)');
|
|
const replaceWithInputComponent = addTextComponent('Replace:', 'e.g. $1');
|
|
// 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');
|
|
// 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();
|
|
const replaceString = replaceWithInputComponent.getValue();
|
|
const selectedText = editor.getSelection();
|
|
if (searchString === '') {
|
|
new obsidian.Notice('Nothing to search for!');
|
|
return;
|
|
}
|
|
// 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);
|
|
findInputComponent.setValue(this.settings.findText);
|
|
replaceWithInputComponent.setValue(this.settings.replaceText);
|
|
// 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();
|
|
new obsidian.Setting(containerEl)
|
|
.setName('Case Insensitive')
|
|
.setDesc('when using regular expressions (regex /i modifier)')
|
|
.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();
|
|
})));
|
|
}
|
|
}
|
|
|
|
module.exports = RegexFindReplacePlugin;
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9tYWluLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfSk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuIiwiaW1wb3J0IHtcblx0QXBwLFxuXHRCdXR0b25Db21wb25lbnQsXG5cdEVkaXRvcixcblx0TW9kYWwsXG5cdE5vdGljZSxcblx0UGx1Z2luLFxuXHRUZXh0Q29tcG9uZW50LFxuXHRUb2dnbGVDb21wb25lbnQsXG5cdFBsdWdpblNldHRpbmdUYWIsXG5cdFNldHRpbmdcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbnRlcmZhY2UgUmZyUGx1Z2luU2V0dGluZ3Mge1xuXHRmaW5kVGV4dDogc3RyaW5nO1xuXHRyZXBsYWNlVGV4dDogc3RyaW5nO1xuXHR1c2VSZWdFeDogYm9vbGVhbjtcblx0c2VsT25seTogYm9vbGVhbjtcblx0Y2FzZUluc2Vuc2l0aXZlOiBib29sZWFuO1xuXHRwcm9jZXNzTGluZUJyZWFrOiBib29sZWFuO1xufVxuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTOiBSZnJQbHVnaW5TZXR0aW5ncyA9IHtcblx0ZmluZFRleHQ6ICcnLFxuXHRyZXBsYWNlVGV4dDogJycsXG5cdHVzZVJlZ0V4OiB0cnVlLFxuXHRzZWxPbmx5OiBmYWxzZSxcblx0Y2FzZUluc2Vuc2l0aXZlOiBmYWxzZSxcblx0cHJvY2Vzc0xpbmVCcmVhazogZmFsc2Vcbn1cblxuLy8gbG9nVGhyZXNob2xkOiAwIC4uLiBvbmx5IGVycm9yIG1lc3NhZ2VzXG4vLyAgICAgICAgICAgICAgIDkgLi4uIHZlcmJvc2Ugb3V0cHV0XG5jb25zdCBsb2dUaHJlc2hvbGQgPSA5O1xuY29uc3QgbG9nZ2VyID0gKGxvZ1N0cmluZzogc3RyaW5nLCBsb2dMZXZlbD0wKTogdm9pZCA9PiB7aWYgKGxvZ0xldmVsIDw9IGxvZ1RocmVzaG9sZCkgY29uc29sZS5sb2cgKCdSZWdleEZSOiAnICsgbG9nU3RyaW5nKX07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlZ2V4RmluZFJlcGxhY2VQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogUmZyUGx1Z2luU2V0dGluZ3M7XG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGxvZ2dlcignTG9hZGluZyBQbHVnaW4uLi4nLCA5KTtcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xuXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBSZWdleEZpbmRSZXBsYWNlU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdvYnNpZGlhbi1yZWdleC1yZXBsYWNlJyxcblx0XHRcdG5hbWU6ICdGaW5kIGFuZCBSZXBsYWNlIHVzaW5nIHJlZ3VsYXIgZXhwcmVzc2lvbnMnLFxuXHRcdFx0ZWRpdG9yQ2FsbGJhY2s6IChlZGl0b3IpID0+IHtcblx0XHRcdFx0bmV3IEZpbmRBbmRSZXBsYWNlTW9kYWwodGhpcy5hcHAsIGVkaXRvciwgdGhpcy5zZXR0aW5ncywgdGhpcykub3BlbigpO1xuXHRcdFx0fSxcblx0XHR9KTtcblx0fVxuXG5cdG9udW5sb2FkKCkge1xuXHRcdGxvZ2dlcignQnllIScsIDkpO1xuXHR9XG5cblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdGxvZ2dlcignTG9hZGluZyBTZXR0aW5ncy4uLicsIDYpO1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHRcdGxvZ2dlcignICAgZmluZFZhbDogICAgICAgICAnICsgdGhpcy5zZXR0aW5ncy5maW5kVGV4dCwgNik7XG5cdFx0bG9nZ2VyKCcgICByZXBsYWNlVGV4dDogICAgICcgKyB0aGlzLnNldHRpbmdzLnJlcGxhY2VUZXh0LCA2KTtcblx0XHRsb2dnZXIoJyAgIGNhc2VJbnNlbnNpdGl2ZTogJyArIHRoaXMuc2V0dGluZ3MuY2FzZUluc2Vuc2l0aXZlLCA2KTtcblx0XHRsb2dnZXIoJyAgIHByb2Nlc3NMaW5lQnJlYWs6ICcgKyB0aGlzLnNldHRpbmdzLnByb2Nlc3NMaW5lQnJlYWssIDYpO1xuXG5cdH1cblxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxuXG59XG5cbmNsYXNzIEZpbmRBbmRSZXBsYWNlTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBlZGl0b3I6IEVkaXRvciwgc2V0dGluZ3M6IFJmclBsdWdpblNldHRpbmdzLCBwbHVnaW46IFBsdWdpbikge1xuXHRcdHN1cGVyKGFwcCk7XG5cdFx0dGhpcy5lZGl0b3IgPSBlZGl0b3I7XG5cdFx0dGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHR9XG5cblx0c2V0dGluZ3M6IFJmclBsdWdpblNldHRpbmdzO1xuXHRlZGl0b3I6IEVkaXRvcjtcblx0cGx1Z2luOiBQbHVnaW47XG5cblx0b25PcGVuKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsLCB0aXRsZUVsLCBlZGl0b3IsIG1vZGFsRWwgfSA9IHRoaXM7XG5cblx0XHRtb2RhbEVsLmFkZENsYXNzKCdmaW5kLXJlcGxhY2UtbW9kYWwnKTtcblx0XHR0aXRsZUVsLnNldFRleHQoJ1JlZ2V4IEZpbmQvUmVwbGFjZScpO1xuXG5cdFx0Y29uc3Qgcm93Q2xhc3MgPSAncm93Jztcblx0XHRjb25zdCBkaXZDbGFzcyA9ICdkaXYnO1xuXHRcdGNvbnN0IG5vU2VsZWN0aW9uID0gZWRpdG9yLmdldFNlbGVjdGlvbigpID09PSAnJztcblx0XHRsZXQgcmVnZXhGbGFncyA9ICdnbSc7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MuY2FzZUluc2Vuc2l0aXZlKSByZWdleEZsYWdzID0gcmVnZXhGbGFncy5jb25jYXQoJ2knKTtcblxuXHRcdGxvZ2dlcignTm8gdGV4dCBzZWxlY3RlZD86ICcgKyBub1NlbGVjdGlvbiwgOSk7XG5cblx0XHRjb25zdCBhZGRUZXh0Q29tcG9uZW50ID0gKGxhYmVsOiBzdHJpbmcsIHBsYWNlaG9sZGVyOiBzdHJpbmcpOiBUZXh0Q29tcG9uZW50ID0+IHtcblx0XHRcdGNvbnN0IGNvbnRhaW5lckVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHRjb250YWluZXJFbC5hZGRDbGFzcyhyb3dDbGFzcyk7XG5cblx0XHRcdGNvbnN0IHRhcmdldEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHR0YXJnZXRFbC5hZGRDbGFzcygnaW5wdXQtd3JhcHBlcicpO1xuXG5cdFx0XHRjb25zdCBsYWJlbEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHRsYWJlbEVsLmFkZENsYXNzKCdpbnB1dC1sYWJlbCcpO1xuXHRcdFx0bGFiZWxFbC5zZXRUZXh0KGxhYmVsKTtcblxuXHRcdFx0Y29udGFpbmVyRWwuYXBwZW5kQ2hpbGQobGFiZWxFbCk7XG5cdFx0XHRjb250YWluZXJFbC5hcHBlbmRDaGlsZCh0YXJnZXRFbCk7XG5cblx0XHRcdGNvbnN0IGNvbXBvbmVudCA9IG5ldyBUZXh0Q29tcG9uZW50KHRhcmdldEVsKTtcblx0XHRcdGNvbXBvbmVudC5zZXRQbGFjZWhvbGRlcihwbGFjZWhvbGRlcik7XG5cblx0XHRcdGNvbnRlbnRFbC5hcHBlbmQoY29udGFpbmVyRWwpO1xuXHRcdFx0cmV0dXJuIGNvbXBvbmVudDtcblx0XHR9O1xuXG5cdFx0Y29uc3QgYWRkVG9nZ2xlQ29tcG9uZW50ID0gKGxhYmVsOiBzdHJpbmcsIHRvb2x0aXA6IHN0cmluZywgaGlkZSA9IGZhbHNlKTogVG9nZ2xlQ29tcG9uZW50ID0+IHtcblx0XHRcdGNvbnN0IGNvbnRhaW5lckVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHRjb250YWluZXJFbC5hZGRDbGFzcyhyb3dDbGFzcyk7XG5cdFxuXHRcdFx0Y29uc3QgdGFyZ2V0RWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGRpdkNsYXNzKTtcblx0XHRcdHRhcmdldEVsLmFkZENsYXNzKHJvd0NsYXNzKTtcblxuXHRcdFx0Y29uc3QgY29tcG9uZW50ID0gbmV3IFRvZ2dsZUNvbXBvbmVudCh0YXJnZXRFbCk7XG5cdFx0XHRjb21wb25lbnQuc2V0VG9vbHRpcCh0b29sdGlwKTtcblx0XG5cdFx0XHRjb25zdCBsYWJlbEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0XHRsYWJlbEVsLmFkZENsYXNzKCdjaGVjay1sYWJlbCcpO1xuXHRcdFx0bGFiZWxFbC5zZXRUZXh0KGxhYmVsKTtcblx0XG5cdFx0XHRjb250YWluZXJFbC5hcHBlbmRDaGlsZChsYWJlbEVsKTtcblx0XHRcdGNvbnRhaW5lckVsLmFwcGVuZENoaWxkKHRhcmdldEVsKTtcblx0XHRcdGlmICghaGlkZSkgY29udGVudEVsLmFwcGVuZENoaWxkKGNvbnRhaW5lckVsKTtcblx0XHRcdHJldHVybiBjb21wb25lbnQ7XG5cdFx0fTtcblxuXHRcdC8vIENyZWF0ZSBpbnB1dCBmaWVsZHNcblx0XHRjb25zdCBmaW5kSW5wdXRDb21wb25lbnQgPSBhZGRUZXh0Q29tcG9uZW50KCdGaW5kOicsICdlLmcuICguKiknKTtcblx0XHRjb25zdCByZXBsYWNlV2l0aElucHV0Q29tcG9uZW50ID0gYWRkVGV4dENvbXBvbmVudCgnUmVwbGFjZTonLCAnZS5nLiAkMScpO1xuXG5cdFx0Ly8gQ3JlYXRlIGFuZCBzaG93IHJlZ3VsYXIgZXhwcmVzc2lvbiB0b2dnbGUgc3dpdGNoXG5cdFx0Y29uc3QgcmVnVG9nZ2xlQ29tcG9uZW50ID0gYWRkVG9nZ2xlQ29tcG9uZW50KCdVc2UgcmVndWxhciBleHByZXNzaW9ucycsICdJZiBlbmFibGVkLCByZWd1bGFyIGV4cHJlc3Npb25zIGluIHRoZSBmaW5kIGZpZWxkIGFyZSBwcm9jZXNzZWQgYXMgc3VjaCwgYW5kIHJlZ2V4IGdyb3VwcyBtaWdodCBiZSBhZGRyZXNzZWQgaW4gdGhlIHJlcGxhY2UgZmllbGQnKTtcblx0XHRcblx0XHQvLyBDcmVhdGUgYW5kIHNob3cgc2VsZWN0aW9uIHRvZ2dsZSBzd2l0Y2ggb25seSBpZiBhbnkgdGV4dCBpcyBzZWxlY3RlZFxuXHRcdGNvbnN0IHNlbFRvZ2dsZUNvbXBvbmVudCA9IGFkZFRvZ2dsZUNvbXBvbmVudCgnUmVwbGFjZSBvbmx5IGluIHNlbGVjdGlvbicsICdJZiBlbmFibGVkLCByZXBsYWNlcyBvbmx5IG9jY3VyYW5jZXMgaW4gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCB0ZXh0Jywgbm9TZWxlY3Rpb24pO1xuXG5cdFx0Ly8gQ3JlYXRlIEJ1dHRvbnNcblx0XHRjb25zdCBidXR0b25Db250YWluZXJFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZGl2Q2xhc3MpO1xuXHRcdGJ1dHRvbkNvbnRhaW5lckVsLmFkZENsYXNzKHJvd0NsYXNzKTtcblxuXHRcdGNvbnN0IHN1Ym1pdEJ1dHRvblRhcmdldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZGl2Q2xhc3MpO1xuXHRcdHN1Ym1pdEJ1dHRvblRhcmdldC5hZGRDbGFzcygnYnV0dG9uLXdyYXBwZXInKTtcblx0XHRzdWJtaXRCdXR0b25UYXJnZXQuYWRkQ2xhc3Mocm93Q2xhc3MpO1xuXG5cdFx0Y29uc3QgY2FuY2VsQnV0dG9uVGFyZ2V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChkaXZDbGFzcyk7XG5cdFx0Y2FuY2VsQnV0dG9uVGFyZ2V0LmFkZENsYXNzKCdidXR0b24td3JhcHBlcicpO1xuXHRcdGNhbmNlbEJ1dHRvblRhcmdldC5hZGRDbGFzcyhyb3dDbGFzcyk7XG5cblx0XHRjb25zdCBzdWJtaXRCdXR0b25Db21wb25lbnQgPSBuZXcgQnV0dG9uQ29tcG9uZW50KHN1Ym1pdEJ1dHRvblRhcmdldCk7XG5cdFx0Y29uc3QgY2FuY2VsQnV0dG9uQ29tcG9uZW50ID0gbmV3IEJ1dHRvbkNvbXBvbmVudChjYW5jZWxCdXR0b25UYXJnZXQpO1xuXHRcdFxuXHRcdGNhbmNlbEJ1dHRvbkNvbXBvbmVudC5zZXRCdXR0b25UZXh0KCdDYW5jZWwnKTtcblx0XHRjYW5jZWxCdXR0b25Db21wb25lbnQub25DbGljaygoKSA9PiB7XG5cdFx0XHRsb2dnZXIoJ0FjdGlvbiBjYW5jZWxsZWQuJywgOCk7XG5cdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0fSk7XG5cblx0XHRzdWJtaXRCdXR0b25Db21wb25lbnQuc2V0QnV0dG9uVGV4dCgnUmVwbGFjZSBBbGwnKTtcblx0XHRzdWJtaXRCdXR0b25Db21wb25lbnQuc2V0Q3RhKCk7XG5cdFx0c3VibWl0QnV0dG9uQ29tcG9uZW50Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0bGV0IHJlc3VsdFN0cmluZyA9ICdObyBtYXRjaCc7XG5cdFx0XHRsZXQgc2NvcGUgPSAnJztcblx0XHRcdGNvbnN0IHNlYXJjaFN0cmluZyA9IGZpbmRJbnB1dENvbXBvbmVudC5nZXRWYWx1ZSgpO1xuXHRcdFx0Y29uc3QgcmVwbGFjZVN0cmluZyA9IHJlcGxhY2VXaXRoSW5wdXRDb21wb25lbnQuZ2V0VmFsdWUoKTtcblx0XHRcdGNvbnN0IHNlbGVjdGVkVGV4dCA9IGVkaXRvci5nZXRTZWxlY3Rpb24oKTtcblxuXHRcdFx0aWYgKHNlYXJjaFN0cmluZyA9PT0gJycpIHtcblx0XHRcdFx0bmV3IE5vdGljZSgnTm90aGluZyB0byBzZWFyY2ggZm9yIScpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIENoZWNrIGlmIHJlZ3VsYXIgZXhwcmVzc2lvbnMgc2hvdWxkIGJlIHVzZWRcblx0XHRcdGlmKHJlZ1RvZ2dsZUNvbXBvbmVudC5nZXRWYWx1ZSgpKSB7XG5cdFx0XHRcdGxvZ2dlcignVVNJTkcgcmVnZXggd2l0aCBmbGFnczogJyArIHJlZ2V4RmxhZ3MsIDgpO1xuXG5cdFx0XHRcdGNvbnN0IHNlYXJjaFJlZ2V4ID0gbmV3IFJlZ0V4cChzZWFyY2hTdHJpbmcsIHJlZ2V4RmxhZ3MpO1xuXHRcdFx0XHRpZighc2VsVG9nZ2xlQ29tcG9uZW50LmdldFZhbHVlKCkpIHtcblx0XHRcdFx0XHRsb2dnZXIoJyAgIFNDT1BFOiBGdWxsIGRvY3VtZW50JywgOSk7XG5cdFx0XHRcdFx0Y29uc3QgZG9jdW1lbnRUZXh0ID0gZWRpdG9yLmdldFZhbHVlKCk7XG5cdFx0XHRcdFx0Y29uc3QgcnJlc3VsdCA9IGRvY3VtZW50VGV4dC5tYXRjaChzZWFyY2hSZWdleCk7XG5cdFx0XHRcdFx0aWYgKHJyZXN1bHQpIHtcblx0XHRcdFx0XHRcdGVkaXRvci5zZXRWYWx1ZShkb2N1bWVudFRleHQucmVwbGFjZShzZWFyY2hSZWdleCwgcmVwbGFjZVN0cmluZykpO1xuXHRcdFx0XHRcdFx0cmVzdWx0U3RyaW5nID0gYE1hZGUgJHtycmVzdWx0Lmxlbmd0aH0gcmVwbGFjZW1lbnQocykgaW4gZG9jdW1lbnRgO1x0XHRcdFxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRsb2dnZXIoJyAgIFNDT1BFOiBTZWxlY3Rpb24nLCA5KTtcblx0XHRcdFx0XHRjb25zdCBycmVzdWx0ID0gc2VsZWN0ZWRUZXh0Lm1hdGNoKHNlYXJjaFJlZ2V4KTtcblx0XHRcdFx0XHRpZiAocnJlc3VsdCkge1xuXHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oc2VsZWN0ZWRUZXh0LnJlcGxhY2Uoc2VhcmNoUmVnZXgsIHJlcGxhY2VTdHJpbmcpKTtcdFxuXHRcdFx0XHRcdFx0cmVzdWx0U3RyaW5nID0gYE1hZGUgJHtycmVzdWx0Lmxlbmd0aH0gcmVwbGFjZW1lbnQocykgaW4gc2VsZWN0aW9uYDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRsb2dnZXIoJ05PVCB1c2luZyByZWdleCcsIDgpO1xuXHRcdFx0XHRsZXQgbnJPZkhpdHMgPSAwO1xuXHRcdFx0XHRpZighc2VsVG9nZ2xlQ29tcG9uZW50LmdldFZhbHVlKCkpIHtcblx0XHRcdFx0XHRsb2dnZXIoJyAgIFNDT1BFOiBGdWxsIGRvY3VtZW50JywgOSk7XG5cdFx0XHRcdFx0c2NvcGUgPSAnc2VsZWN0aW9uJ1xuXHRcdFx0XHRcdGNvbnN0IGRvY3VtZW50VGV4dCA9IGVkaXRvci5nZXRWYWx1ZSgpO1xuXHRcdFx0XHRcdGNvbnN0IGRvY3VtZW50U3BsaXQgPSBkb2N1bWVudFRleHQuc3BsaXQoc2VhcmNoU3RyaW5nKTtcblx0XHRcdFx0XHRuck9mSGl0cyA9IGRvY3VtZW50U3BsaXQubGVuZ3RoIC0gMTtcblx0XHRcdFx0XHRlZGl0b3Iuc2V0VmFsdWUoZG9jdW1lbnRTcGxpdC5qb2luKHJlcGxhY2VTdHJpbmcpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRsb2dnZXIoJyAgIFNDT1BFOiBTZWxlY3Rpb24nLCA5KTtcblx0XHRcdFx0XHRzY29wZSA9ICdkb2N1bWVudCc7XG5cdFx0XHRcdFx0Y29uc3Qgc2VsZWN0ZWRTcGxpdCA9IHNlbGVjdGVkVGV4dC5zcGxpdChzZWFyY2hTdHJpbmcpO1xuXHRcdFx0XHRcdG5yT2ZIaXRzID0gc2VsZWN0ZWRTcGxpdC5sZW5ndGggLSAxO1xuXHRcdFx0XHRcdGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKHNlbGVjdGVkU3BsaXQuam9pbihyZXBsYWNlU3RyaW5nKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzdWx0U3RyaW5nID0gYE1hZGUgJHtuck9mSGl0c30gcmVwbGFjZW1lbnQocykgaW4gJHtzY29wZX1gO1xuXHRcdFx0fSBcdFx0XG5cdFx0XHRcblx0XHRcdC8vIFNhdmluZyBzZXR0aW5ncyAoZmluZC9yZXBsYWNlIHRleHQgYW5kIHRvZ2dsZSBzd2l0Y2ggc3RhdGVzKVxuXHRcdFx0dGhpcy5zZXR0aW5ncy5maW5kVGV4dCA9IHNlYXJjaFN0cmluZztcblx0XHRcdHRoaXMuc2V0dGluZ3MucmVwbGFjZVRleHQgPSByZXBsYWNlU3RyaW5nO1xuXHRcdFx0dGhpcy5zZXR0aW5ncy51c2VSZWdFeCA9IHJlZ1RvZ2dsZUNvbXBvbmVudC5nZXRWYWx1ZSgpO1xuXHRcdFx0dGhpcy5zZXR0aW5ncy5zZWxPbmx5ID0gc2VsVG9nZ2xlQ29tcG9uZW50LmdldFZhbHVlKCk7XG5cdFx0XHR0aGlzLnBsdWdpbi5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblxuXHRcdFx0dGhpcy5jbG9zZSgpO1xuXHRcdFx0bmV3IE5vdGljZShyZXN1bHRTdHJpbmcpO1x0XHRcdFx0XHRcblx0XHR9KTtcblxuXHRcdC8vIEFwcGx5IHNldHRpbmdzXG5cdFx0cmVnVG9nZ2xlQ29tcG9uZW50LnNldFZhbHVlKHRoaXMuc2V0dGluZ3MudXNlUmVnRXgpO1xuXHRcdHNlbFRvZ2dsZUNvbXBvbmVudC5zZXRWYWx1ZSh0aGlzLnNldHRpbmdzLnNlbE9ubHkpO1xuXHRcdGZpbmRJbnB1dENvbXBvbmVudC5zZXRWYWx1ZSh0aGlzLnNldHRpbmdzLmZpbmRUZXh0KTtcblx0XHRyZXBsYWNlV2l0aElucHV0Q29tcG9uZW50LnNldFZhbHVlKHRoaXMuc2V0dGluZ3MucmVwbGFjZVRleHQpO1xuXHRcdFxuXHRcdC8vIEFkZCBidXR0b24gcm93IHRvIGRpYWxvZ1xuXHRcdGJ1dHRvbkNvbnRhaW5lckVsLmFwcGVuZENoaWxkKHN1Ym1pdEJ1dHRvblRhcmdldCk7XG5cdFx0YnV0dG9uQ29udGFpbmVyRWwuYXBwZW5kQ2hpbGQoY2FuY2VsQnV0dG9uVGFyZ2V0KTtcblx0XHRjb250ZW50RWwuYXBwZW5kQ2hpbGQoYnV0dG9uQ29udGFpbmVyRWwpO1xuXG5cdFx0Ly8gSWYgbm8gdGV4dCBpcyBzZWxlY3RlZCwgZGlzYWJsZSBzZWxlY3Rpb24tdG9nZ2xlLXN3aXRjaFxuXHRcdGlmIChub1NlbGVjdGlvbikgc2VsVG9nZ2xlQ29tcG9uZW50LnNldFZhbHVlKGZhbHNlKTtcblxuXHR9XG5cblx0XG5cdG9uQ2xvc2UoKSB7XG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XG5cdH1cbn1cblxuY2xhc3MgUmVnZXhGaW5kUmVwbGFjZVNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBSZWdleEZpbmRSZXBsYWNlUGx1Z2luO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IFJlZ2V4RmluZFJlcGxhY2VQbHVnaW4pIHtcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRkaXNwbGF5KCk6IHZvaWQge1xuXHRcdGNvbnN0IHtjb250YWluZXJFbH0gPSB0aGlzO1xuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdDYXNlIEluc2Vuc2l0aXZlJylcblx0XHRcdC5zZXREZXNjKCd3aGVuIHVzaW5nIHJlZ3VsYXIgZXhwcmVzc2lvbnMgKHJlZ2V4IC9pIG1vZGlmaWVyKScpXG5cdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB0b2dnbGVcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmNhc2VJbnNlbnNpdGl2ZSlcblx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdGxvZ2dlcignU2V0dGluZ3MgdXBkYXRlOiBjYXNlSW5zZW5zaXRpdmU6ICcgKyB2YWx1ZSk7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY2FzZUluc2Vuc2l0aXZlID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pKTtcblxuXHR9XG59Il0sIm5hbWVzIjpbIlBsdWdpbiIsIk1vZGFsIiwiVGV4dENvbXBvbmVudCIsIlRvZ2dsZUNvbXBvbmVudCIsIkJ1dHRvbkNvbXBvbmVudCIsIk5vdGljZSIsIlBsdWdpblNldHRpbmdUYWIiLCJTZXR0aW5nIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdURBO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2hILElBQUksT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQy9ELFFBQVEsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUNuRyxRQUFRLFNBQVMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUN0RyxRQUFRLFNBQVMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRTtBQUN0SCxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxVQUFVLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM5RSxLQUFLLENBQUMsQ0FBQztBQUNQOztBQ3ZEQSxNQUFNLGdCQUFnQixHQUFzQjtJQUMzQyxRQUFRLEVBQUUsRUFBRTtJQUNaLFdBQVcsRUFBRSxFQUFFO0lBQ2YsUUFBUSxFQUFFLElBQUk7SUFDZCxPQUFPLEVBQUUsS0FBSztJQUNkLGVBQWUsRUFBRSxLQUFLO0lBQ3RCLGdCQUFnQixFQUFFLEtBQUs7Q0FDdkIsQ0FBQTtBQUVEO0FBQ0E7QUFDQSxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDdkIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxTQUFpQixFQUFFLFFBQVEsR0FBQyxDQUFDLE9BQVksSUFBSSxRQUFRLElBQUksWUFBWTtJQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUUsV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUFBLEVBQUMsQ0FBQztNQUV6RyxzQkFBdUIsU0FBUUEsZUFBTTtJQUduRCxNQUFNOztZQUNYLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvQixNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUUxQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksMEJBQTBCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBR25FLElBQUksQ0FBQyxVQUFVLENBQUM7Z0JBQ2YsRUFBRSxFQUFFLHdCQUF3QjtnQkFDNUIsSUFBSSxFQUFFLDRDQUE0QztnQkFDbEQsY0FBYyxFQUFFLENBQUMsTUFBTTtvQkFDdEIsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2lCQUN0RTthQUNELENBQUMsQ0FBQztTQUNIO0tBQUE7SUFFRCxRQUFRO1FBQ1AsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztLQUNsQjtJQUVLLFlBQVk7O1lBQ2pCLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNqQyxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDM0UsTUFBTSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNELE1BQU0sQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbEUsTUFBTSxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FFcEU7S0FBQTtJQUVLLFlBQVk7O1lBQ2pCLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDbkM7S0FBQTtDQUVEO0FBRUQsTUFBTSxtQkFBb0IsU0FBUUMsY0FBSztJQUN0QyxZQUFZLEdBQVEsRUFBRSxNQUFjLEVBQUUsUUFBMkIsRUFBRSxNQUFjO1FBQ2hGLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNYLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0tBQ3JCO0lBTUQsTUFBTTtRQUNMLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFFckQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUV0QyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdkIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDakQsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlO1lBQUUsVUFBVSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFdkUsTUFBTSxDQUFDLHFCQUFxQixHQUFHLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUUvQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBYSxFQUFFLFdBQW1CO1lBQzNELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckQsV0FBVyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUvQixNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xELFFBQVEsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFbkMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqRCxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFdkIsV0FBVyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNqQyxXQUFXLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRWxDLE1BQU0sU0FBUyxHQUFHLElBQUlDLHNCQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUV0QyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sU0FBUyxDQUFDO1NBQ2pCLENBQUM7UUFFRixNQUFNLGtCQUFrQixHQUFHLENBQUMsS0FBYSxFQUFFLE9BQWUsRUFBRSxJQUFJLEdBQUcsS0FBSztZQUN2RSxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JELFdBQVcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFL0IsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRCxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRTVCLE1BQU0sU0FBUyxHQUFHLElBQUlDLHdCQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDaEQsU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU5QixNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pELE9BQU8sQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDaEMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV2QixXQUFXLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2pDLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLElBQUk7Z0JBQUUsU0FBUyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5QyxPQUFPLFNBQVMsQ0FBQztTQUNqQixDQUFDOztRQUdGLE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0seUJBQXlCLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDOztRQUcxRSxNQUFNLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDLHlCQUF5QixFQUFFLG1JQUFtSSxDQUFDLENBQUM7O1FBRzlNLE1BQU0sa0JBQWtCLEdBQUcsa0JBQWtCLENBQUMsMkJBQTJCLEVBQUUscUVBQXFFLEVBQUUsV0FBVyxDQUFDLENBQUM7O1FBRy9KLE1BQU0saUJBQWlCLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRCxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFckMsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVELGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzlDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV0QyxNQUFNLGtCQUFrQixHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDNUQsa0JBQWtCLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDOUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXRDLE1BQU0scUJBQXFCLEdBQUcsSUFBSUMsd0JBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0scUJBQXFCLEdBQUcsSUFBSUEsd0JBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRXRFLHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QyxxQkFBcUIsQ0FBQyxPQUFPLENBQUM7WUFDN0IsTUFBTSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztTQUNiLENBQUMsQ0FBQztRQUVILHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRCxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMvQixxQkFBcUIsQ0FBQyxPQUFPLENBQUM7WUFDN0IsSUFBSSxZQUFZLEdBQUcsVUFBVSxDQUFDO1lBQzlCLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNmLE1BQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25ELE1BQU0sYUFBYSxHQUFHLHlCQUF5QixDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzNELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUUzQyxJQUFJLFlBQVksS0FBSyxFQUFFLEVBQUU7Z0JBQ3hCLElBQUlDLGVBQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO2dCQUNyQyxPQUFPO2FBQ1A7O1lBR0QsSUFBRyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDakMsTUFBTSxDQUFDLDBCQUEwQixHQUFHLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFFbkQsTUFBTSxXQUFXLEdBQUcsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUN6RCxJQUFHLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLEVBQUU7b0JBQ2xDLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDckMsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUN2QyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUNoRCxJQUFJLE9BQU8sRUFBRTt3QkFDWixNQUFNLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7d0JBQ2xFLFlBQVksR0FBRyxRQUFRLE9BQU8sQ0FBQyxNQUFNLDZCQUE2QixDQUFDO3FCQUNuRTtpQkFDRDtxQkFDSTtvQkFDSixNQUFNLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ2pDLE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7b0JBQ2hELElBQUksT0FBTyxFQUFFO3dCQUNaLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDO3dCQUMxRSxZQUFZLEdBQUcsUUFBUSxPQUFPLENBQUMsTUFBTSw4QkFBOEIsQ0FBQztxQkFDcEU7aUJBQ0Q7YUFDRDtpQkFDSTtnQkFDSixNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztnQkFDakIsSUFBRyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxFQUFFO29CQUNsQyxNQUFNLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ3JDLEtBQUssR0FBRyxXQUFXLENBQUE7b0JBQ25CLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDdkMsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDdkQsUUFBUSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztpQkFDbkQ7cUJBQ0k7b0JBQ0osTUFBTSxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNqQyxLQUFLLEdBQUcsVUFBVSxDQUFDO29CQUNuQixNQUFNLGFBQWEsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUN2RCxRQUFRLEdBQUcsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7b0JBQ3BDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7aUJBQzNEO2dCQUNELFlBQVksR0FBRyxRQUFRLFFBQVEsc0JBQXNCLEtBQUssRUFBRSxDQUFDO2FBQzdEOztZQUdELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLFlBQVksQ0FBQztZQUN0QyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxhQUFhLENBQUM7WUFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsa0JBQWtCLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEdBQUcsa0JBQWtCLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXBDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNiLElBQUlBLGVBQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUN6QixDQUFDLENBQUM7O1FBR0gsa0JBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEQsa0JBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkQsa0JBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEQseUJBQXlCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7O1FBRzlELGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xELGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xELFNBQVMsQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUMsQ0FBQzs7UUFHekMsSUFBSSxXQUFXO1lBQUUsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBRXBEO0lBR0QsT0FBTztRQUNOLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDM0IsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO0tBQ2xCO0NBQ0Q7QUFFRCxNQUFNLDBCQUEyQixTQUFRQyx5QkFBZ0I7SUFHeEQsWUFBWSxHQUFRLEVBQUUsTUFBOEI7UUFDbkQsS0FBSyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztLQUNyQjtJQUVELE9BQU87UUFDTixNQUFNLEVBQUMsV0FBVyxFQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzNCLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUVwQixJQUFJQyxnQkFBTyxDQUFDLFdBQVcsQ0FBQzthQUN0QixPQUFPLENBQUMsa0JBQWtCLENBQUM7YUFDM0IsT0FBTyxDQUFDLG9EQUFvRCxDQUFDO2FBQzdELFNBQVMsQ0FBQyxNQUFNLElBQUksTUFBTTthQUN6QixRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDO2FBQzlDLFFBQVEsQ0FBQyxDQUFPLEtBQUs7WUFDckIsTUFBTSxDQUFDLG9DQUFvQyxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDN0MsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ2pDLENBQUEsQ0FBQyxDQUFDLENBQUM7S0FFTjs7Ozs7In0=
|