@glimmer/compiler
Version:
563 lines (452 loc) • 55.1 kB
JavaScript
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
import { assert } from '@glimmer/util';
import { Stack, DictSet } from '@glimmer/util';
import { isArgument, isAttribute, isFlushElement } from '@glimmer/wire-format';
export var Block = function () {
function Block() {
_classCallCheck(this, Block);
this.statements = [];
}
Block.prototype.push = function push(statement) {
this.statements.push(statement);
};
return Block;
}();
export var InlineBlock = function (_Block) {
_inherits(InlineBlock, _Block);
function InlineBlock(table) {
_classCallCheck(this, InlineBlock);
var _this = _possibleConstructorReturn(this, _Block.call(this));
_this.table = table;
return _this;
}
InlineBlock.prototype.toJSON = function toJSON() {
return {
statements: this.statements,
parameters: this.table.slots
};
};
return InlineBlock;
}(Block);
export var NamedBlock = function (_InlineBlock) {
_inherits(NamedBlock, _InlineBlock);
function NamedBlock(name, table) {
_classCallCheck(this, NamedBlock);
var _this2 = _possibleConstructorReturn(this, _InlineBlock.call(this, table));
_this2.name = name;
return _this2;
}
return NamedBlock;
}(InlineBlock);
export var TemplateBlock = function (_Block2) {
_inherits(TemplateBlock, _Block2);
function TemplateBlock(symbolTable) {
_classCallCheck(this, TemplateBlock);
var _this3 = _possibleConstructorReturn(this, _Block2.call(this));
_this3.symbolTable = symbolTable;
_this3.type = 'template';
_this3.yields = new DictSet();
_this3.named = new DictSet();
_this3.blocks = [];
_this3.hasEval = false;
return _this3;
}
TemplateBlock.prototype.push = function push(statement) {
this.statements.push(statement);
};
TemplateBlock.prototype.toJSON = function toJSON() {
return {
symbols: this.symbolTable.symbols,
statements: this.statements,
hasEval: this.hasEval,
upvars: this.symbolTable.freeVariables
};
};
return TemplateBlock;
}(Block);
export var ComponentBlock = function (_Block3) {
_inherits(ComponentBlock, _Block3);
function ComponentBlock(tag, table, selfClosing) {
_classCallCheck(this, ComponentBlock);
var _this4 = _possibleConstructorReturn(this, _Block3.call(this));
_this4.tag = tag;
_this4.table = table;
_this4.selfClosing = selfClosing;
_this4.attributes = [];
_this4.arguments = [];
_this4.inParams = true;
_this4.positionals = [];
_this4.blocks = [];
return _this4;
}
ComponentBlock.prototype.push = function push(statement) {
if (this.inParams) {
if (isFlushElement(statement)) {
this.inParams = false;
} else if (isArgument(statement)) {
this.arguments.push(statement);
} else if (isAttribute(statement)) {
this.attributes.push(statement);
} else {
throw new Error('Compile Error: only parameters allowed before flush-element');
}
} else {
this.statements.push(statement);
}
};
ComponentBlock.prototype.pushBlock = function pushBlock(name, block) {
this.blocks.push([name, block]);
};
ComponentBlock.prototype.toJSON = function toJSON() {
var blocks = void 0;
var args = this.arguments;
var keys = args.map(function (arg) {
return arg[1];
});
var values = args.map(function (arg) {
return arg[2];
});
if (this.selfClosing) {
blocks = null;
} else if (this.blocks.length > 0) {
var _keys = [];
var _values = [];
for (var i = 0; i < this.blocks.length; i++) {
var _blocks$i = this.blocks[i],
key = _blocks$i[0],
value = _blocks$i[1];
_keys.push(key.slice(1));
_values.push(value);
}
blocks = [_keys, _values];
} else {
blocks = [['default'], [{
statements: this.statements,
parameters: this.table.slots
}]];
}
return [this.tag, this.attributes, [keys, values], blocks];
};
return ComponentBlock;
}(Block);
export var Template = function () {
function Template(symbols) {
_classCallCheck(this, Template);
this.block = new TemplateBlock(symbols);
}
Template.prototype.toJSON = function toJSON() {
return this.block.toJSON();
};
return Template;
}();
var JavaScriptCompiler = function () {
function JavaScriptCompiler(opcodes, symbols, locations, options) {
_classCallCheck(this, JavaScriptCompiler);
this.locations = locations;
this.blocks = new Stack();
this.values = [];
this.location = null;
this.locationStack = [];
this.opcodes = opcodes;
this.template = new Template(symbols);
this.options = options;
}
JavaScriptCompiler.process = function process(opcodes, locations, symbols, options) {
var compiler = new JavaScriptCompiler(opcodes, symbols, locations, options);
return compiler.process();
};
JavaScriptCompiler.prototype.process = function process() {
var _this5 = this;
this.opcodes.forEach(function (op, i) {
var opcode = op[0];
_this5.location = _this5.locations[i];
var arg = op[1];
if (!_this5[opcode]) {
throw new Error('unimplemented ' + opcode + ' on JavaScriptCompiler');
}
_this5[opcode](arg);
});
return this.template;
};
/// Nesting
JavaScriptCompiler.prototype.startBlock = function startBlock(program) {
this.startInlineBlock(program.symbols);
};
JavaScriptCompiler.prototype.endBlock = function endBlock() {
var block = this.endInlineBlock();
this.template.block.blocks.push(block);
};
JavaScriptCompiler.prototype.startProgram = function startProgram() {
this.blocks.push(this.template.block);
};
JavaScriptCompiler.prototype.endProgram = function endProgram() {};
/// Statements
JavaScriptCompiler.prototype.text = function text(content) {
this.push([1 /* Append */, 1, 0, 0, content]);
};
JavaScriptCompiler.prototype.append = function append(trusted) {
this.push([1 /* Append */, +trusted, 0, 0, this.popValue()]);
};
JavaScriptCompiler.prototype.comment = function comment(value) {
this.push([2 /* Comment */, value]);
};
JavaScriptCompiler.prototype.modifier = function modifier() {
var name = this.popValue();
var params = this.popValue();
var hash = this.popValue();
this.push([3 /* Modifier */, 0, 0, name, params, hash]);
};
JavaScriptCompiler.prototype.block = function block(_ref) {
var template = _ref[0],
inverse = _ref[1];
var head = this.popValue();
var params = this.popValue();
var hash = this.popValue();
var blocks = this.template.block.blocks;
false && assert(typeof template !== 'number' || blocks[template] !== null, 'missing block in the compiler');
false && assert(typeof inverse !== 'number' || blocks[inverse] !== null, 'missing block in the compiler');
var namedBlocks = void 0;
if (template === null && inverse === null) {
namedBlocks = null;
} else if (inverse === null) {
namedBlocks = [['default'], [blocks[template]]];
} else {
namedBlocks = [['default', 'else'], [blocks[template], blocks[inverse]]];
}
// assert(head[]);
this.push([5 /* Block */, head, params, hash, namedBlocks]);
};
JavaScriptCompiler.prototype.openComponent = function openComponent(element) {
var tag = this.options && this.options.customizeComponentName ? this.options.customizeComponentName(element.tag) : element.tag;
var component = new ComponentBlock(tag, element.symbols, element.selfClosing);
this.blocks.push(component);
};
JavaScriptCompiler.prototype.openNamedBlock = function openNamedBlock(element) {
var block = new NamedBlock(element.tag, element.symbols);
this.blocks.push(block);
};
JavaScriptCompiler.prototype.openElement = function openElement(_ref2) {
var element = _ref2[0],
simple = _ref2[1];
var tag = element.tag;
if (element.blockParams.length > 0) {
throw new Error('Compile Error: <' + element.tag + '> is not a component and doesn\'t support block parameters');
} else {
this.push([9 /* OpenElement */, tag, simple]);
}
};
JavaScriptCompiler.prototype.flushElement = function flushElement() {
this.push([10 /* FlushElement */]);
};
JavaScriptCompiler.prototype.closeComponent = function closeComponent(_element) {
var _endComponent = this.endComponent(),
tag = _endComponent[0],
attrs = _endComponent[1],
args = _endComponent[2],
blocks = _endComponent[3];
this.push([7 /* Component */, tag, attrs, args, blocks]);
};
JavaScriptCompiler.prototype.closeNamedBlock = function closeNamedBlock(_element) {
var blocks = this.blocks;
var block = blocks.pop();
this.currentComponent.pushBlock(block.name, block.toJSON());
};
JavaScriptCompiler.prototype.closeDynamicComponent = function closeDynamicComponent(_element) {
var _endComponent2 = this.endComponent(),
attrs = _endComponent2[1],
args = _endComponent2[2],
block = _endComponent2[3];
this.push([7 /* Component */, this.popValue(), attrs, args, block]);
};
JavaScriptCompiler.prototype.closeElement = function closeElement(_element) {
this.push([11 /* CloseElement */]);
};
JavaScriptCompiler.prototype.staticAttr = function staticAttr(_ref3) {
var name = _ref3[0],
namespace = _ref3[1];
var value = this.popValue();
this.push([12 /* StaticAttr */, name, value, namespace]);
};
JavaScriptCompiler.prototype.dynamicAttr = function dynamicAttr(_ref4) {
var name = _ref4[0],
namespace = _ref4[1];
var value = this.popValue();
this.push([13 /* DynamicAttr */, name, value, namespace]);
};
JavaScriptCompiler.prototype.componentAttr = function componentAttr(_ref5) {
var name = _ref5[0],
namespace = _ref5[1];
var value = this.popValue();
this.push([14 /* ComponentAttr */, name, value, namespace]);
};
JavaScriptCompiler.prototype.trustingAttr = function trustingAttr(_ref6) {
var name = _ref6[0],
namespace = _ref6[1];
var value = this.popValue();
this.push([20 /* TrustingDynamicAttr */, name, value, namespace]);
};
JavaScriptCompiler.prototype.trustingComponentAttr = function trustingComponentAttr(_ref7) {
var name = _ref7[0],
namespace = _ref7[1];
var value = this.popValue();
this.push([21 /* TrustingComponentAttr */, name, value, namespace]);
};
JavaScriptCompiler.prototype.staticArg = function staticArg(name) {
var value = this.popValue();
this.push([19 /* StaticArg */, name, value]);
};
JavaScriptCompiler.prototype.dynamicArg = function dynamicArg(name) {
var value = this.popValue();
this.push([18 /* DynamicArg */, name, value]);
};
JavaScriptCompiler.prototype.yield = function _yield(to) {
var params = this.popValue();
this.push([16 /* Yield */, to, params]);
};
JavaScriptCompiler.prototype.attrSplat = function attrSplat(to) {
// consume (and disregard) the value pushed for the
// ...attributes attribute
this.popValue();
this.push([15 /* AttrSplat */, to]);
};
JavaScriptCompiler.prototype.debugger = function _debugger(evalInfo) {
this.push([22 /* Debugger */, evalInfo]);
this.template.block.hasEval = true;
};
JavaScriptCompiler.prototype.hasBlock = function hasBlock(name) {
this.pushValue([28 /* HasBlock */, [24 /* GetSymbol */, name]]);
};
JavaScriptCompiler.prototype.hasBlockParams = function hasBlockParams(name) {
this.pushValue([29 /* HasBlockParams */
, [24 /* GetSymbol */, name]]);
};
JavaScriptCompiler.prototype.partial = function partial(evalInfo) {
var params = this.popValue();
this.push([17 /* Partial */, params[0], evalInfo]);
this.template.block.hasEval = true;
};
/// Expressions
JavaScriptCompiler.prototype.literal = function literal(value) {
if (value === undefined) {
this.pushValue([30 /* Undefined */]);
} else {
this.pushValue(value);
}
};
JavaScriptCompiler.prototype.getPath = function getPath(rest) {
var head = this.popValue();
this.pushValue([27 /* GetPath */, head, rest]);
};
JavaScriptCompiler.prototype.getSymbol = function getSymbol(head) {
this.pushValue([24 /* GetSymbol */, head]);
};
JavaScriptCompiler.prototype.getFree = function getFree(head) {
this.pushValue([25 /* GetFree */, head]);
};
JavaScriptCompiler.prototype.getFreeWithContext = function getFreeWithContext(_ref8) {
var head = _ref8[0],
context = _ref8[1];
this.pushValue([26 /* GetContextualFree */, head, context]);
};
JavaScriptCompiler.prototype.concat = function concat() {
this.pushValue([32 /* Concat */, this.popValue()]);
};
JavaScriptCompiler.prototype.helper = function helper() {
var _popLocatedValue = this.popLocatedValue(),
head = _popLocatedValue.value,
location = _popLocatedValue.location;
var params = this.popValue();
var hash = this.popValue();
this.pushValue([31 /* Call */
, start(location), end(location), head, params, hash]);
};
/// Stack Management Opcodes
JavaScriptCompiler.prototype.prepareArray = function prepareArray(size) {
var values = [];
for (var i = 0; i < size; i++) {
values.push(this.popValue());
}
this.pushValue(values);
};
JavaScriptCompiler.prototype.prepareObject = function prepareObject(size) {
false && assert(this.values.length >= size, 'Expected ' + size + ' values on the stack, found ' + this.values.length);
var keys = new Array(size);
var values = new Array(size);
for (var i = 0; i < size; i++) {
keys[i] = this.popValue();
values[i] = this.popValue();
}
this.pushValue([keys, values]);
};
/// Utilities
JavaScriptCompiler.prototype.endComponent = function endComponent() {
var component = this.blocks.pop();
false && assert(component instanceof ComponentBlock, 'Compiler bug: endComponent() should end a component');
return component.toJSON();
};
JavaScriptCompiler.prototype.startInlineBlock = function startInlineBlock(symbols) {
var block = new InlineBlock(symbols);
this.blocks.push(block);
};
JavaScriptCompiler.prototype.endInlineBlock = function endInlineBlock() {
var blocks = this.blocks;
var block = blocks.pop();
return block.toJSON();
};
JavaScriptCompiler.prototype.push = function push(args) {
this.currentBlock.push(args);
};
JavaScriptCompiler.prototype.pushValue = function pushValue(val) {
this.values.push(val);
this.locationStack.push(this.location);
};
JavaScriptCompiler.prototype.popLocatedValue = function popLocatedValue() {
false && assert(this.values.length, 'No expression found on stack');
var value = this.values.pop();
var location = this.locationStack.pop();
if (location === undefined) {
throw new Error('Unbalanced location push and pop');
}
return { value: value, location: location };
};
JavaScriptCompiler.prototype.popValue = function popValue() {
return this.popLocatedValue().value;
};
_createClass(JavaScriptCompiler, [{
key: 'currentBlock',
get: function get() {
return this.blocks.current;
}
}, {
key: 'currentComponent',
get: function get() {
var block = this.currentBlock;
if (block instanceof ComponentBlock) {
return block;
} else {
throw new Error('Expected ComponentBlock on stack, found ' + block.constructor.name);
}
}
}]);
return JavaScriptCompiler;
}();
export default JavaScriptCompiler;
function start(location) {
if (location) {
return location.start;
} else {
return -1;
}
}
function end(location) {
if (location) {
return location.end - location.start;
} else {
return -1;
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL2NvbXBpbGVyL2xpYi9qYXZhc2NyaXB0LWNvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSxTQUFBLE1BQUEsUUFBQSxlQUFBO0FBQ0EsU0FBQSxLQUFBLEVBQUEsT0FBQSxRQUFBLGVBQUE7QUFHQSxTQUFBLFVBQUEsRUFBQSxXQUFBLEVBQUEsY0FBQSxRQUFBLHNCQUFBO0FBc0JBLFdBQU0sS0FBTjtBQUFBLHFCQUFBO0FBQUE7O0FBQ1MsYUFBQSxVQUFBLEdBQUEsRUFBQTtBQU9SOztBQVJELG9CQUtFLElBTEYsaUJBS0UsU0FMRixFQUtzQztBQUNsQyxhQUFBLFVBQUEsQ0FBQSxJQUFBLENBQUEsU0FBQTtBQUNELEtBUEg7O0FBQUE7QUFBQTtBQVVBLFdBQU0sV0FBTjtBQUFBOztBQUNFLHlCQUFBLEtBQUEsRUFBMEM7QUFBQTs7QUFBQSxxREFDeEMsaUJBRHdDOztBQUF2QixjQUFBLEtBQUEsR0FBQSxLQUFBO0FBQXVCO0FBRXpDOztBQUhILDBCQUtFLE1BTEYscUJBS1E7QUFDSixlQUFPO0FBQ0wsd0JBQVksS0FEUCxVQUFBO0FBRUwsd0JBQVksS0FBQSxLQUFBLENBQVc7QUFGbEIsU0FBUDtBQUlELEtBVkg7O0FBQUE7QUFBQSxFQUFNLEtBQU47QUFhQSxXQUFNLFVBQU47QUFBQTs7QUFDRSx3QkFBQSxJQUFBLEVBQUEsS0FBQSxFQUF3RDtBQUFBOztBQUFBLHNEQUN0RCx3QkFBQSxLQUFBLENBRHNEOztBQUFyQyxlQUFBLElBQUEsR0FBQSxJQUFBO0FBQXFDO0FBRXZEOztBQUhIO0FBQUEsRUFBTSxXQUFOO0FBTUEsV0FBTSxhQUFOO0FBQUE7O0FBT0UsMkJBQUEsV0FBQSxFQUFtRDtBQUFBOztBQUFBLHNEQUNqRCxrQkFEaUQ7O0FBQS9CLGVBQUEsV0FBQSxHQUFBLFdBQUE7QUFOYixlQUFBLElBQUEsR0FBQSxVQUFBO0FBQ0EsZUFBQSxNQUFBLEdBQVMsSUFBVCxPQUFTLEVBQVQ7QUFDQSxlQUFBLEtBQUEsR0FBUSxJQUFSLE9BQVEsRUFBUjtBQUNBLGVBQUEsTUFBQSxHQUFBLEVBQUE7QUFDQSxlQUFBLE9BQUEsR0FBQSxLQUFBO0FBRTRDO0FBRWxEOztBQVRILDRCQVdFLElBWEYsaUJBV0UsU0FYRixFQVcyQjtBQUN2QixhQUFBLFVBQUEsQ0FBQSxJQUFBLENBQUEsU0FBQTtBQUNELEtBYkg7O0FBQUEsNEJBZUUsTUFmRixxQkFlUTtBQUNKLGVBQU87QUFDTCxxQkFBUyxLQUFBLFdBQUEsQ0FESixPQUFBO0FBRUwsd0JBQVksS0FGUCxVQUFBO0FBR0wscUJBQVMsS0FISixPQUFBO0FBSUwsb0JBQVEsS0FBQSxXQUFBLENBQWlCO0FBSnBCLFNBQVA7QUFNRCxLQXRCSDs7QUFBQTtBQUFBLEVBQU0sS0FBTjtBQXlCQSxXQUFNLGNBQU47QUFBQTs7QUFPRSw0QkFBQSxHQUFBLEVBQUEsS0FBQSxFQUFBLFdBQUEsRUFBOEY7QUFBQTs7QUFBQSxzREFDNUYsa0JBRDRGOztBQUExRSxlQUFBLEdBQUEsR0FBQSxHQUFBO0FBQXFCLGVBQUEsS0FBQSxHQUFBLEtBQUE7QUFBaUMsZUFBQSxXQUFBLEdBQUEsV0FBQTtBQU5uRSxlQUFBLFVBQUEsR0FBQSxFQUFBO0FBQ0EsZUFBQSxTQUFBLEdBQUEsRUFBQTtBQUNDLGVBQUEsUUFBQSxHQUFBLElBQUE7QUFDRCxlQUFBLFdBQUEsR0FBQSxFQUFBO0FBQ0EsZUFBQSxNQUFBLEdBQUEsRUFBQTtBQUV1RjtBQUU3Rjs7QUFUSCw2QkFXRSxJQVhGLGlCQVdFLFNBWEYsRUFXMkI7QUFDdkIsWUFBSSxLQUFKLFFBQUEsRUFBbUI7QUFDakIsZ0JBQUksZUFBSixTQUFJLENBQUosRUFBK0I7QUFDN0IscUJBQUEsUUFBQSxHQUFBLEtBQUE7QUFERixhQUFBLE1BRU8sSUFBSSxXQUFKLFNBQUksQ0FBSixFQUEyQjtBQUNoQyxxQkFBQSxTQUFBLENBQUEsSUFBQSxDQUFBLFNBQUE7QUFESyxhQUFBLE1BRUEsSUFBSSxZQUFKLFNBQUksQ0FBSixFQUE0QjtBQUNqQyxxQkFBQSxVQUFBLENBQUEsSUFBQSxDQUFBLFNBQUE7QUFESyxhQUFBLE1BRUE7QUFDTCxzQkFBTSxJQUFBLEtBQUEsQ0FBTiw2REFBTSxDQUFOO0FBQ0Q7QUFUSCxTQUFBLE1BVU87QUFDTCxpQkFBQSxVQUFBLENBQUEsSUFBQSxDQUFBLFNBQUE7QUFDRDtBQUNGLEtBekJIOztBQUFBLDZCQTJCRSxTQTNCRixzQkEyQkUsSUEzQkYsRUEyQkUsS0EzQkYsRUEyQnNEO0FBQ2xELGFBQUEsTUFBQSxDQUFBLElBQUEsQ0FBaUIsQ0FBQSxJQUFBLEVBQWpCLEtBQWlCLENBQWpCO0FBQ0QsS0E3Qkg7O0FBQUEsNkJBK0JFLE1BL0JGLHFCQStCUTtBQUNKLFlBQUEsZUFBQTtBQUNBLFlBQUksT0FBTyxLQUFYLFNBQUE7QUFDQSxZQUFJLE9BQU8sS0FBQSxHQUFBLENBQVM7QUFBQSxtQkFBTyxJQUEzQixDQUEyQixDQUFQO0FBQUEsU0FBVCxDQUFYO0FBQ0EsWUFBSSxTQUFTLEtBQUEsR0FBQSxDQUFTO0FBQUEsbUJBQU8sSUFBN0IsQ0FBNkIsQ0FBUDtBQUFBLFNBQVQsQ0FBYjtBQUVBLFlBQUksS0FBSixXQUFBLEVBQXNCO0FBQ3BCLHFCQUFBLElBQUE7QUFERixTQUFBLE1BRU8sSUFBSSxLQUFBLE1BQUEsQ0FBQSxNQUFBLEdBQUosQ0FBQSxFQUE0QjtBQUNqQyxnQkFBSSxRQUFKLEVBQUE7QUFDQSxnQkFBSSxVQUFKLEVBQUE7QUFFQSxpQkFBSyxJQUFJLElBQVQsQ0FBQSxFQUFnQixJQUFJLEtBQUEsTUFBQSxDQUFwQixNQUFBLEVBQUEsR0FBQSxFQUE2QztBQUFBLGdDQUN4QixLQUFBLE1BQUEsQ0FBbkIsQ0FBbUIsQ0FEd0I7QUFBQSxvQkFDdkMsR0FEdUM7QUFBQSxvQkFDdkMsS0FEdUM7O0FBRTNDLHNCQUFBLElBQUEsQ0FBVSxJQUFBLEtBQUEsQ0FBVixDQUFVLENBQVY7QUFDQSx3QkFBQSxJQUFBLENBQUEsS0FBQTtBQUNEO0FBQ0QscUJBQVMsQ0FBQSxLQUFBLEVBQVQsT0FBUyxDQUFUO0FBVEssU0FBQSxNQVVBO0FBQ0wscUJBQVMsQ0FDUCxDQURPLFNBQ1AsQ0FETyxFQUVQLENBQ0U7QUFDRSw0QkFBWSxLQURkLFVBQUE7QUFFRSw0QkFBWSxLQUFBLEtBQUEsQ0FBVztBQUZ6QixhQURGLENBRk8sQ0FBVDtBQVNEO0FBRUQsZUFBTyxDQUFDLEtBQUQsR0FBQSxFQUFXLEtBQVgsVUFBQSxFQUE0QixDQUFBLElBQUEsRUFBNUIsTUFBNEIsQ0FBNUIsRUFBUCxNQUFPLENBQVA7QUFDRCxLQTlESDs7QUFBQTtBQUFBLEVBQU0sS0FBTjtBQWlFQSxXQUFNLFFBQU47QUFHRSxzQkFBQSxPQUFBLEVBQXVDO0FBQUE7O0FBQ3JDLGFBQUEsS0FBQSxHQUFhLElBQUEsYUFBQSxDQUFiLE9BQWEsQ0FBYjtBQUNEOztBQUxILHVCQU9FLE1BUEYscUJBT1E7QUFDSixlQUFPLEtBQUEsS0FBQSxDQUFQLE1BQU8sRUFBUDtBQUNELEtBVEg7O0FBQUE7QUFBQTs7SUFjYyxrQjtBQW1CWixnQ0FBQSxPQUFBLEVBQUEsT0FBQSxFQUFBLFNBQUEsRUFBQSxPQUFBLEVBSTBCO0FBQUE7O0FBRGhCLGFBQUEsU0FBQSxHQUFBLFNBQUE7QUFWTyxhQUFBLE1BQUEsR0FBUyxJQUFULEtBQVMsRUFBVDtBQUVBLGFBQUEsTUFBQSxHQUFBLEVBQUE7QUFFVCxhQUFBLFFBQUEsR0FBQSxJQUFBO0FBQ0EsYUFBQSxhQUFBLEdBQUEsRUFBQTtBQVFOLGFBQUEsT0FBQSxHQUFBLE9BQUE7QUFDQSxhQUFBLFFBQUEsR0FBZ0IsSUFBQSxRQUFBLENBQWhCLE9BQWdCLENBQWhCO0FBQ0EsYUFBQSxPQUFBLEdBQUEsT0FBQTtBQUNEOzt1QkEzQkQsTyxvQkFBQSxPLEVBQUEsUyxFQUFBLE8sRUFBQSxPLEVBSTBCO0FBRXhCLFlBQUksV0FBVyxJQUFBLGtCQUFBLENBQUEsT0FBQSxFQUFBLE9BQUEsRUFBQSxTQUFBLEVBQWYsT0FBZSxDQUFmO0FBQ0EsZUFBTyxTQUFQLE9BQU8sRUFBUDtBQUNELEs7O2lDQW1DRCxPLHNCQUFPO0FBQUE7O0FBQ0wsYUFBQSxPQUFBLENBQUEsT0FBQSxDQUFxQixVQUFBLEVBQUEsRUFBQSxDQUFBLEVBQVU7QUFDN0IsZ0JBQUksU0FBUyxHQUFiLENBQWEsQ0FBYjtBQUNBLG1CQUFBLFFBQUEsR0FBZ0IsT0FBQSxTQUFBLENBQWhCLENBQWdCLENBQWhCO0FBRUEsZ0JBQUksTUFBTSxHQUFWLENBQVUsQ0FBVjtBQUVBLGdCQUFJLENBQUMsT0FBTCxNQUFLLENBQUwsRUFBbUI7QUFDakIsc0JBQU0sSUFBQSxLQUFBLG9CQUFOLE1BQU0sNEJBQU47QUFDRDtBQUNBLG1CQUFBLE1BQUEsRUFBQSxHQUFBO0FBVEgsU0FBQTtBQVdBLGVBQU8sS0FBUCxRQUFBO0FBQ0QsSztBQUVEOzs7aUNBRUEsVSx1QkFBQSxPLEVBQTZCO0FBQzNCLGFBQUEsZ0JBQUEsQ0FBc0IsUUFBdEIsT0FBQTtBQUNELEs7O2lDQUVELFEsdUJBQVE7QUFDTixZQUFJLFFBQVEsS0FBWixjQUFZLEVBQVo7QUFDQSxhQUFBLFFBQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLElBQUEsQ0FBQSxLQUFBO0FBQ0QsSzs7aUNBRUQsWSwyQkFBWTtBQUNWLGFBQUEsTUFBQSxDQUFBLElBQUEsQ0FBaUIsS0FBQSxRQUFBLENBQWpCLEtBQUE7QUFDRCxLOztpQ0FFRCxVLHlCQUFVLENBQUssQztBQUVmOzs7aUNBRUEsSSxpQkFBQSxPLEVBQW9CO0FBQ2xCLGFBQUEsSUFBQSxDQUFVLENBQUEsQ0FBQSxDQUFBLFlBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsRUFBVixPQUFVLENBQVY7QUFDRCxLOztpQ0FFRCxNLG1CQUFBLE8sRUFBdUI7QUFDckIsYUFBQSxJQUFBLENBQVUsQ0FBQSxDQUFBLENBQUEsWUFBQSxFQUFxQixDQUFyQixPQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsRUFBcUMsS0FBL0MsUUFBK0MsRUFBckMsQ0FBVjtBQUNELEs7O2lDQUVELE8sb0JBQUEsSyxFQUFxQjtBQUNuQixhQUFBLElBQUEsQ0FBVSxDQUFBLENBQUEsQ0FBQSxhQUFBLEVBQVYsS0FBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsUSx1QkFBUTtBQUNOLFlBQUksT0FBTyxLQUFYLFFBQVcsRUFBWDtBQUNBLFlBQUksU0FBUyxLQUFiLFFBQWEsRUFBYjtBQUNBLFlBQUksT0FBTyxLQUFYLFFBQVcsRUFBWDtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsQ0FBQSxDQUFBLGNBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLElBQUEsRUFBQSxNQUFBLEVBQVYsSUFBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsSyx3QkFBbUQ7QUFBQSxZQUE3QyxRQUE2QztBQUFBLFlBQW5ELE9BQW1EOztBQUNqRCxZQUFJLE9BQU8sS0FBWCxRQUFXLEVBQVg7QUFDQSxZQUFJLFNBQVMsS0FBYixRQUFhLEVBQWI7QUFDQSxZQUFJLE9BQU8sS0FBWCxRQUFXLEVBQVg7QUFFQSxZQUFJLFNBQVMsS0FBQSxRQUFBLENBQUEsS0FBQSxDQUFiLE1BQUE7QUFMaUQsaUJBTWpELE9BQ0UsT0FBQSxRQUFBLEtBQUEsUUFBQSxJQUFnQyxPQUFBLFFBQUEsTUFEbEMsSUFBQSxFQU5pRCwrQkFNakQsQ0FOaUQ7QUFBQSxpQkFVakQsT0FDRSxPQUFBLE9BQUEsS0FBQSxRQUFBLElBQStCLE9BQUEsT0FBQSxNQURqQyxJQUFBLEVBVmlELCtCQVVqRCxDQVZpRDs7QUFlakQsWUFBQSxvQkFBQTtBQUVBLFlBQUksYUFBQSxJQUFBLElBQXFCLFlBQXpCLElBQUEsRUFBMkM7QUFDekMsMEJBQUEsSUFBQTtBQURGLFNBQUEsTUFFTyxJQUFJLFlBQUosSUFBQSxFQUFzQjtBQUMzQiwwQkFBYyxDQUFDLENBQUQsU0FBQyxDQUFELEVBQWMsQ0FBQyxPQUE3QixRQUE2QixDQUFELENBQWQsQ0FBZDtBQURLLFNBQUEsTUFFQTtBQUNMLDBCQUFjLENBQUMsQ0FBQSxTQUFBLEVBQUQsTUFBQyxDQUFELEVBQXNCLENBQUMsT0FBRCxRQUFDLENBQUQsRUFBbUIsT0FBdkQsT0FBdUQsQ0FBbkIsQ0FBdEIsQ0FBZDtBQUNEO0FBRUQ7QUFFQSxhQUFBLElBQUEsQ0FBVSxDQUFBLENBQUEsQ0FBQSxXQUFBLEVBQUEsSUFBQSxFQUFBLE1BQUEsRUFBQSxJQUFBLEVBQVYsV0FBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsYSwwQkFBQSxPLEVBQXNDO0FBQ3BDLFlBQUksTUFDRixLQUFBLE9BQUEsSUFBZ0IsS0FBQSxPQUFBLENBQWhCLHNCQUFBLEdBQ0ksS0FBQSxPQUFBLENBQUEsc0JBQUEsQ0FBb0MsUUFEeEMsR0FDSSxDQURKLEdBRUksUUFITixHQUFBO0FBSUEsWUFBSSxZQUFZLElBQUEsY0FBQSxDQUFBLEdBQUEsRUFBd0IsUUFBeEIsT0FBQSxFQUEwQyxRQUExRCxXQUFnQixDQUFoQjtBQUNBLGFBQUEsTUFBQSxDQUFBLElBQUEsQ0FBQSxTQUFBO0FBQ0QsSzs7aUNBRUQsYywyQkFBQSxPLEVBQXVDO0FBQ3JDLFlBQUksUUFBZSxJQUFBLFVBQUEsQ0FBZSxRQUFmLEdBQUEsRUFBNEIsUUFBL0MsT0FBbUIsQ0FBbkI7QUFDQSxhQUFBLE1BQUEsQ0FBQSxJQUFBLENBQUEsS0FBQTtBQUNELEs7O2lDQUVELFcsK0JBQXlEO0FBQUEsWUFBN0MsT0FBNkM7QUFBQSxZQUF6RCxNQUF5RDs7QUFDdkQsWUFBSSxNQUFNLFFBQVYsR0FBQTtBQUVBLFlBQUksUUFBQSxXQUFBLENBQUEsTUFBQSxHQUFKLENBQUEsRUFBb0M7QUFDbEMsa0JBQU0sSUFBQSxLQUFBLHNCQUNlLFFBRHJCLEdBQU0sZ0VBQU47QUFERixTQUFBLE1BSU87QUFDTCxpQkFBQSxJQUFBLENBQVUsQ0FBQSxDQUFBLENBQUEsaUJBQUEsRUFBQSxHQUFBLEVBQVYsTUFBVSxDQUFWO0FBQ0Q7QUFDRixLOztpQ0FFRCxZLDJCQUFZO0FBQ1YsYUFBQSxJQUFBLENBQVUsQ0FBQSxFQUFBLENBQVYsa0JBQVUsQ0FBVjtBQUNELEs7O2lDQUVELGMsMkJBQUEsUSxFQUF3QztBQUFBLDRCQUNMLEtBQWpDLFlBQWlDLEVBREs7QUFBQSxZQUNsQyxHQURrQztBQUFBLFlBQ2xDLEtBRGtDO0FBQUEsWUFDbEMsSUFEa0M7QUFBQSxZQUNsQyxNQURrQzs7QUFHdEMsYUFBQSxJQUFBLENBQVUsQ0FBQSxDQUFBLENBQUEsZUFBQSxFQUFBLEdBQUEsRUFBQSxLQUFBLEVBQUEsSUFBQSxFQUFWLE1BQVUsQ0FBVjtBQUNELEs7O2lDQUVELGUsNEJBQUEsUSxFQUF5QztBQUFBLFlBQ25DLE1BRG1DLEdBQ3ZDLElBRHVDLENBQ25DLE1BRG1DOztBQUV2QyxZQUFJLFFBQWUsT0FBbkIsR0FBbUIsRUFBbkI7QUFFQSxhQUFBLGdCQUFBLENBQUEsU0FBQSxDQUFnQyxNQUFoQyxJQUFBLEVBQTRDLE1BQTVDLE1BQTRDLEVBQTVDO0FBQ0QsSzs7aUNBRUQscUIsa0NBQUEsUSxFQUErQztBQUFBLDZCQUNoQixLQUE3QixZQUE2QixFQURnQjtBQUFBLFlBQ3pDLEtBRHlDO0FBQUEsWUFDekMsSUFEeUM7QUFBQSxZQUN6QyxLQUR5Qzs7QUFHN0MsYUFBQSxJQUFBLENBQVUsQ0FBQSxDQUFBLENBQUEsZUFBQSxFQUF3QixLQUF4QixRQUF3QixFQUF4QixFQUFBLEtBQUEsRUFBQSxJQUFBLEVBQVYsS0FBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsWSx5QkFBQSxRLEVBQXNDO0FBQ3BDLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFWLGtCQUFVLENBQVY7QUFDRCxLOztpQ0FFRCxVLDhCQUFzRDtBQUFBLFlBQTNDLElBQTJDO0FBQUEsWUFBdEQsU0FBc0Q7O0FBQ3BELFlBQUksUUFBUSxLQUFaLFFBQVksRUFBWjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLGdCQUFBLEVBQUEsSUFBQSxFQUFBLEtBQUEsRUFBVixTQUFVLENBQVY7QUFDRCxLOztpQ0FFRCxXLCtCQUF1RDtBQUFBLFlBQTNDLElBQTJDO0FBQUEsWUFBdkQsU0FBdUQ7O0FBQ3JELFlBQUksUUFBUSxLQUFaLFFBQVksRUFBWjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLGlCQUFBLEVBQUEsSUFBQSxFQUFBLEtBQUEsRUFBVixTQUFVLENBQVY7QUFDRCxLOztpQ0FFRCxhLGlDQUF5RDtBQUFBLFlBQTNDLElBQTJDO0FBQUEsWUFBekQsU0FBeUQ7O0FBQ3ZELFlBQUksUUFBUSxLQUFaLFFBQVksRUFBWjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLG1CQUFBLEVBQUEsSUFBQSxFQUFBLEtBQUEsRUFBVixTQUFVLENBQVY7QUFDRCxLOztpQ0FFRCxZLGdDQUF3RDtBQUFBLFlBQTNDLElBQTJDO0FBQUEsWUFBeEQsU0FBd0Q7O0FBQ3RELFlBQUksUUFBUSxLQUFaLFFBQVksRUFBWjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLHlCQUFBLEVBQUEsSUFBQSxFQUFBLEtBQUEsRUFBVixTQUFVLENBQVY7QUFDRCxLOztpQ0FFRCxxQix5Q0FBaUU7QUFBQSxZQUEzQyxJQUEyQztBQUFBLFlBQWpFLFNBQWlFOztBQUMvRCxZQUFJLFFBQVEsS0FBWixRQUFZLEVBQVo7QUFDQSxhQUFBLElBQUEsQ0FBVSxDQUFBLEVBQUEsQ0FBQSwyQkFBQSxFQUFBLElBQUEsRUFBQSxLQUFBLEVBQVYsU0FBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsUyxzQkFBQSxJLEVBQW1CO0FBQ2pCLFlBQUksUUFBUSxLQUFaLFFBQVksRUFBWjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLGVBQUEsRUFBQSxJQUFBLEVBQVYsS0FBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsVSx1QkFBQSxJLEVBQW9CO0FBQ2xCLFlBQUksUUFBUSxLQUFaLFFBQVksRUFBWjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLGdCQUFBLEVBQUEsSUFBQSxFQUFWLEtBQVUsQ0FBVjtBQUNELEs7O2lDQUVELEssbUJBQUEsRSxFQUFnQjtBQUNkLFlBQUksU0FBUyxLQUFiLFFBQWEsRUFBYjtBQUNBLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLFdBQUEsRUFBQSxFQUFBLEVBQVYsTUFBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsUyxzQkFBQSxFLEVBQTRCO0FBQzFCO0FBQ0E7QUFDQSxhQUFBLFFBQUE7QUFDQSxhQUFBLElBQUEsQ0FBVSxDQUFBLEVBQUEsQ0FBQSxlQUFBLEVBQVYsRUFBVSxDQUFWO0FBQ0QsSzs7aUNBRUQsUSxzQkFBQSxRLEVBQXdDO0FBQ3RDLGFBQUEsSUFBQSxDQUFVLENBQUEsRUFBQSxDQUFBLGNBQUEsRUFBVixRQUFVLENBQVY7QUFDQSxhQUFBLFFBQUEsQ0FBQSxLQUFBLENBQUEsT0FBQSxHQUFBLElBQUE7QUFDRCxLOztpQ0FFRCxRLHFCQUFBLEksRUFBcUI7QUFDbkIsYUFBQSxTQUFBLENBQXFDLENBQUEsRUFBQSxDQUFBLGNBQUEsRUFBdUIsQ0FBQSxFQUFBLENBQUEsZUFBQSxFQUE1RCxJQUE0RCxDQUF2QixDQUFyQztBQUNELEs7O2lDQUVELGMsMkJBQUEsSSxFQUEyQjtBQUN6QixhQUFBLFNBQUEsQ0FBMkMsQ0FBQSxFQUFBLEM7QUFBQSxVQUV6QyxDQUFBLEVBQUEsQ0FBQSxlQUFBLEVBRkYsSUFFRSxDQUZ5QyxDQUEzQztBQUlELEs7O2lDQUVELE8sb0JBQUEsUSxFQUF1QztBQUNyQyxZQUFJLFNBQVMsS0FBYixRQUFhLEVBQWI7QUFDQSxhQUFBLElBQUEsQ0FBVSxDQUFBLEVBQUEsQ0FBQSxhQUFBLEVBQXNCLE9BQXRCLENBQXNCLENBQXRCLEVBQVYsUUFBVSxDQUFWO0FBQ0EsYUFBQSxRQUFBLENBQUEsS0FBQSxDQUFBLE9BQUEsR0FBQSxJQUFBO0FBQ0QsSztBQUVEOzs7aUNBRUEsTyxvQkFBQSxLLEVBQTRDO0FBQzFDLFlBQUksVUFBSixTQUFBLEVBQXlCO0FBQ3ZCLGlCQUFBLFNBQUEsQ0FBc0MsQ0FBQSxFQUFBLENBQXRDLGVBQXNDLENBQXRDO0FBREYsU0FBQSxNQUVPO0FBQ0wsaUJBQUEsU0FBQSxDQUFBLEtBQUE7QUFDRDtBQUNGLEs7O2lDQUVELE8sb0JBQUEsSSxFQUFzQjtBQUNwQixZQUFJLE9BQU8sS0FBWCxRQUFXLEVBQVg7QUFDQSxhQUFBLFNBQUEsQ0FBb0MsQ0FBQSxFQUFBLENBQUEsYUFBQSxFQUFBLElBQUEsRUFBcEMsSUFBb0MsQ0FBcEM7QUFDRCxLOztpQ0FFRCxTLHNCQUFBLEksRUFBc0I7QUFDcEIsYUFBQSxTQUFBLENBQXNDLENBQUEsRUFBQSxDQUFBLGVBQUEsRUFBdEMsSUFBc0MsQ0FBdEM7QUFDRCxLOztpQ0FFRCxPLG9CQUFBLEksRUFBb0I7QUFDbEIsYUFBQSxTQUFBLENBQW9DLENBQUEsRUFBQSxDQUFBLGFBQUEsRUFBcEMsSUFBb0MsQ0FBcEM7QUFDRCxLOztpQ0FFRCxrQixzQ0FBK0Q7QUFBQSxZQUE1QyxJQUE0QztBQUFBLFlBQS9ELE9BQStEOztBQUM3RCxhQUFBLFNBQUEsQ0FBOEMsQ0FBQSxFQUFBLENBQUEsdUJBQUEsRUFBQSxJQUFBLEVBQTlDLE9BQThDLENBQTlDO0FBQ0QsSzs7aUNBRUQsTSxxQkFBTTtBQUNKLGFBQUEsU0FBQSxDQUFtQyxDQUFBLEVBQUEsQ0FBQSxZQUFBLEVBQXFCLEtBQXhELFFBQXdELEVBQXJCLENBQW5DO0FBQ0QsSzs7aUNBRUQsTSxxQkFBTTtBQUFBLCtCQUM0QixLQUFoQyxlQUFnQyxFQUQ1QjtBQUFBLFlBQ0EsSUFEQSxvQkFDRSxLQURGO0FBQUEsWUFDQSxRQURBLG9CQUNBLFFBREE7O0FBRUosWUFBSSxTQUFTLEtBQWIsUUFBYSxFQUFiO0FBQ0EsWUFBSSxPQUFPLEtBQVgsUUFBVyxFQUFYO0FBRUEsYUFBQSxTQUFBLENBQW1DLENBQUEsRUFBQSxDO0FBQUEsVUFFakMsTUFGaUMsUUFFakMsQ0FGaUMsRUFHakMsSUFIaUMsUUFHakMsQ0FIaUMsRUFBQSxJQUFBLEVBQUEsTUFBQSxFQUFuQyxJQUFtQyxDQUFuQztBQVFELEs7QUFFRDs7O2lDQUVBLFkseUJBQUEsSSxFQUF5QjtBQUN2QixZQUFJLFNBQUosRUFBQTtBQUVBLGFBQUssSUFBSSxJQUFULENBQUEsRUFBZ0IsSUFBaEIsSUFBQSxFQUFBLEdBQUEsRUFBK0I7QUFDN0IsbUJBQUEsSUFBQSxDQUFZLEtBQVosUUFBWSxFQUFaO0FBQ0Q7QUFFRCxhQUFBLFNBQUEsQ0FBQSxNQUFBO0FBQ0QsSzs7aUNBRUQsYSwwQkFBQSxJLEVBQTBCO0FBQUEsaUJBQ3hCLE9BQ0UsS0FBQSxNQUFBLENBQUEsTUFBQSxJQURGLElBQUEsZ0JBRWMsSUFGZCxvQ0FFaUQsS0FBQSxNQUFBLENBSHpCLE1BQ3hCLENBRHdCOztBQU14QixZQUFJLE9BQWlCLElBQUEsS0FBQSxDQUFyQixJQUFxQixDQUFyQjtBQUNBLFlBQUksU0FBdUIsSUFBQSxLQUFBLENBQTNCLElBQTJCLENBQTNCO0FBRUEsYUFBSyxJQUFJLElBQVQsQ0FBQSxFQUFnQixJQUFoQixJQUFBLEVBQUEsR0FBQSxFQUErQjtBQUM3QixpQkFBQSxDQUFBLElBQVUsS0FBVixRQUFVLEVBQVY7QUFDQSxtQkFBQSxDQUFBLElBQVksS0FBWixRQUFZLEVBQVo7QUFDRDtBQUVELGFBQUEsU0FBQSxDQUFxQixDQUFBLElBQUEsRUFBckIsTUFBcUIsQ0FBckI7QUFDRCxLO0FBRUQ7OztpQ0FFQSxZLDJCQUFZO0FBQ1YsWUFBSSxZQUFZLEtBQUEsTUFBQSxDQUFoQixHQUFnQixFQUFoQjtBQURVLGlCQUVWLE9BQ0UscUJBREYsY0FBQSxFQUZVLHFEQUVWLENBRlU7O0FBT1YsZUFBUSxVQUFSLE1BQVEsRUFBUjtBQUNELEs7O2lDQUVELGdCLDZCQUFBLE8sRUFBMEM7QUFDeEMsWUFBSSxRQUFlLElBQUEsV0FBQSxDQUFuQixPQUFtQixDQUFuQjtBQUNBLGFBQUEsTUFBQSxDQUFBLElBQUEsQ0FBQSxLQUFBO0FBQ0QsSzs7aUNBRUQsYyw2QkFBYztBQUFBLFlBQ1IsTUFEUSxHQUNaLElBRFksQ0FDUixNQURROztBQUVaLFlBQUksUUFBUSxPQUFaLEdBQVksRUFBWjtBQUNBLGVBQU8sTUFBUCxNQUFPLEVBQVA7QUFDRCxLOztpQ0FFRCxJLGlCQUFBLEksRUFBb0I7QUFDbEIsYUFBQSxZQUFBLENBQUEsSUFBQSxDQUFBLElBQUE7QUFDRCxLOztpQ0FFRCxTLHNCQUFBLEcsRUFBc0Q7QUFDcEQsYUFBQSxNQUFBLENBQUEsSUFBQSxDQUFBLEdBQUE7QUFDQSxhQUFBLGFBQUEsQ0FBQSxJQUFBLENBQXdCLEtBQXhCLFFBQUE7QUFDRCxLOztpQ0FFRCxlLDhCQUFlO0FBQUEsaUJBQ2IsT0FBTyxLQUFBLE1BQUEsQ0FBUCxNQUFBLEVBRGEsOEJBQ2IsQ0FEYTs7QUFFYixZQUFJLFFBQVEsS0FBQSxNQUFBLENBQVosR0FBWSxFQUFaO0FBQ0EsWUFBSSxXQUFXLEtBQUEsYUFBQSxDQUFmLEdBQWUsRUFBZjtBQUVBLFlBQUksYUFBSixTQUFBLEVBQTRCO0FBQzFCLGtCQUFNLElBQUEsS0FBQSxDQUFOLGtDQUFNLENBQU47QUFDRDtBQUVELGVBQU8sRUFBQSxZQUFBLEVBQVAsa0JBQU8sRUFBUDtBQUNELEs7O2lDQUVELFEsdUJBQVE7QUFDTixlQUFPLEtBQUEsZUFBQSxHQUFQLEtBQUE7QUFDRCxLOzs7OzRCQXBWZTtBQUNkLG1CQUFjLEtBQUEsTUFBQSxDQUFkLE9BQUE7QUFDRDs7OzRCQUVtQjtBQUNsQixnQkFBSSxRQUFRLEtBQVosWUFBQTtBQUVBLGdCQUFJLGlCQUFKLGNBQUEsRUFBcUM7QUFDbkMsdUJBQUEsS0FBQTtBQURGLGFBQUEsTUFFTztBQUNMLHNCQUFNLElBQUEsS0FBQSw4Q0FBcUQsTUFBQSxXQUFBLENBQTNELElBQU0sQ0FBTjtBQUNEO0FBQ0Y7Ozs7OztlQTFDVyxrQjs7QUFxWGQsU0FBQSxLQUFBLENBQUEsUUFBQSxFQUErQztBQUM3QyxRQUFBLFFBQUEsRUFBYztBQUNaLGVBQU8sU0FBUCxLQUFBO0FBREYsS0FBQSxNQUVPO0FBQ0wsZUFBTyxDQUFQLENBQUE7QUFDRDtBQUNGO0FBRUQsU0FBQSxHQUFBLENBQUEsUUFBQSxFQUE2QztBQUMzQyxRQUFBLFFBQUEsRUFBYztBQUNaLGVBQU8sU0FBQSxHQUFBLEdBQWUsU0FBdEIsS0FBQTtBQURGLEtBQUEsTUFFTztBQUNMLGVBQU8sQ0FBUCxDQUFBO0FBQ0Q7QUFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGFzc2VydCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgU3RhY2ssIERpY3RTZXQsIE9wdGlvbiwgZXhwZWN0IH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5pbXBvcnQgeyBBU1QgfSBmcm9tICdAZ2xpbW1lci9zeW50YXgnO1xuaW1wb3J0IHsgQ29tcGlsZU9wdGlvbnMgfSBmcm9tICcuL3RlbXBsYXRlLWNvbXBpbGVyJztcbmltcG9ydCB7IGlzQXJndW1lbnQsIGlzQXR0cmlidXRlLCBpc0ZsdXNoRWxlbWVudCB9IGZyb20gJ0BnbGltbWVyL3dpcmUtZm9ybWF0JztcbmltcG9ydCB7IFByb2Nlc3NvciwgSmF2YVNjcmlwdENvbXBpbGVyT3BzLCBPcHMsIFNvdXJjZUxvY2F0aW9uIH0gZnJvbSAnLi9jb21waWxlci1vcHMnO1xuaW1wb3J0IHtcbiAgV2lyZUZvcm1hdCxcbiAgU2VyaWFsaXplZElubGluZUJsb2NrLFxuICBTdGF0ZW1lbnQsXG4gIFNlcmlhbGl6ZWRUZW1wbGF0ZUJsb2NrLFxuICBTdGF0ZW1lbnRzLFxuICBTZXhwT3Bjb2RlcyxcbiAgRXhwcmVzc2lvbixcbiAgRXhwcmVzc2lvbnMsXG4gIEV4cHJlc3Npb25Db250ZXh0LFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcblxuZXhwb3J0IHR5cGUgc3RyID0gc3RyaW5nO1xuaW1wb3J0IENvcmUgPSBXaXJlRm9ybWF0LkNvcmU7XG5leHBvcnQgdHlwZSBQYXJhbXMgPSBXaXJlRm9ybWF0LkNvcmUuUGFyYW1zO1xuZXhwb3J0IHR5cGUgQ29uY2F0UGFyYW1zID0gV2lyZUZvcm1hdC5Db3JlLkNvbmNhdFBhcmFtcztcbmV4cG9ydCB0eXBlIEhhc2ggPSBXaXJlRm9ybWF0LkNvcmUuSGFzaDtcbmV4cG9ydCB0eXBlIFBhdGggPSBXaXJlRm9ybWF0LkNvcmUuUGF0aDtcbmV4cG9ydCB0eXBlIFN0YWNrVmFsdWUgPSBXaXJlRm9ybWF0LkV4cHJlc3Npb24gfCBQYXJhbXMgfCBIYXNoIHwgc3RyO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmxvY2sge1xuICBwdWJsaWMgc3RhdGVtZW50czogV2lyZUZvcm1hdC5TdGF0ZW1lbnRbXSA9IFtdO1xuXG4gIGFic3RyYWN0IHRvSlNPTigpOiBPYmplY3Q7XG5cbiAgcHVzaChzdGF0ZW1lbnQ6IFdpcmVGb3JtYXQuU3RhdGVtZW50KSB7XG4gICAgdGhpcy5zdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW5saW5lQmxvY2sgZXh0ZW5kcyBCbG9jayB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyB0YWJsZTogQVNULkJsb2NrU3ltYm9scykge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICB0b0pTT04oKTogU2VyaWFsaXplZElubGluZUJsb2NrIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzLFxuICAgICAgcGFyYW1ldGVyczogdGhpcy50YWJsZS5zbG90cyxcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBOYW1lZEJsb2NrIGV4dGVuZHMgSW5saW5lQmxvY2sge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgbmFtZTogc3RyaW5nLCB0YWJsZTogQVNULkJsb2NrU3ltYm9scykge1xuICAgIHN1cGVyKHRhYmxlKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVGVtcGxhdGVCbG9jayBleHRlbmRzIEJsb2NrIHtcbiAgcHVibGljIHR5cGUgPSAndGVtcGxhdGUnO1xuICBwdWJsaWMgeWllbGRzID0gbmV3IERpY3RTZXQ8c3RyaW5nPigpO1xuICBwdWJsaWMgbmFtZWQgPSBuZXcgRGljdFNldDxzdHJpbmc+KCk7XG4gIHB1YmxpYyBibG9ja3M6IFNlcmlhbGl6ZWRJbmxpbmVCbG9ja1tdID0gW107XG4gIHB1YmxpYyBoYXNFdmFsID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzeW1ib2xUYWJsZTogQVNULlByb2dyYW1TeW1ib2xzKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHB1c2goc3RhdGVtZW50OiBTdGF0ZW1lbnQpIHtcbiAgICB0aGlzLnN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpO1xuICB9XG5cbiAgdG9KU09OKCk6IFNlcmlhbGl6ZWRUZW1wbGF0ZUJsb2NrIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3ltYm9sczogdGhpcy5zeW1ib2xUYWJsZS5zeW1ib2xzLFxuICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzLFxuICAgICAgaGFzRXZhbDogdGhpcy5oYXNFdmFsLFxuICAgICAgdXB2YXJzOiB0aGlzLnN5bWJvbFRhYmxlLmZyZWVWYXJpYWJsZXMsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29tcG9uZW50QmxvY2sgZXh0ZW5kcyBCbG9jayB7XG4gIHB1YmxpYyBhdHRyaWJ1dGVzOiBTdGF0ZW1lbnRzLkF0dHJpYnV0ZVtdID0gW107XG4gIHB1YmxpYyBhcmd1bWVudHM6IFN0YXRlbWVudHMuQXJndW1lbnRbXSA9IFtdO1xuICBwcml2YXRlIGluUGFyYW1zID0gdHJ1ZTtcbiAgcHVibGljIHBvc2l0aW9uYWxzOiBudW1iZXJbXSA9IFtdO1xuICBwdWJsaWMgYmxvY2tzOiBBcnJheTxbc3RyaW5nLCBTZXJpYWxpemVkSW5saW5lQmxvY2tdPiA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgdGFnOiBzdHJpbmcsIHByaXZhdGUgdGFibGU6IEFTVC5CbG9ja1N5bWJvbHMsIHByaXZhdGUgc2VsZkNsb3Npbmc6IGJvb2xlYW4pIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVzaChzdGF0ZW1lbnQ6IFN0YXRlbWVudCkge1xuICAgIGlmICh0aGlzLmluUGFyYW1zKSB7XG4gICAgICBpZiAoaXNGbHVzaEVsZW1lbnQoc3RhdGVtZW50KSkge1xuICAgICAgICB0aGlzLmluUGFyYW1zID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKGlzQXJndW1lbnQoc3RhdGVtZW50KSkge1xuICAgICAgICB0aGlzLmFyZ3VtZW50cy5wdXNoKHN0YXRlbWVudCk7XG4gICAgICB9IGVsc2UgaWYgKGlzQXR0cmlidXRlKHN0YXRlbWVudCkpIHtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVzLnB1c2goc3RhdGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ29tcGlsZSBFcnJvcjogb25seSBwYXJhbWV0ZXJzIGFsbG93ZWQgYmVmb3JlIGZsdXNoLWVsZW1lbnQnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICB9XG4gIH1cblxuICBwdXNoQmxvY2sobmFtZTogc3RyaW5nLCBibG9jazogU2VyaWFsaXplZElubGluZUJsb2NrKSB7XG4gICAgdGhpcy5ibG9ja3MucHVzaChbbmFtZSwgYmxvY2tdKTtcbiAgfVxuXG4gIHRvSlNPTigpOiBbc3RyaW5nLCBTdGF0ZW1lbnRzLkF0dHJpYnV0ZVtdLCBDb3JlLkhhc2gsIENvcmUuQmxvY2tzXSB7XG4gICAgbGV0IGJsb2NrczogQ29yZS5CbG9ja3M7XG4gICAgbGV0IGFyZ3MgPSB0aGlzLmFyZ3VtZW50cztcbiAgICBsZXQga2V5cyA9IGFyZ3MubWFwKGFyZyA9PiBhcmdbMV0pO1xuICAgIGxldCB2YWx1ZXMgPSBhcmdzLm1hcChhcmcgPT4gYXJnWzJdKTtcblxuICAgIGlmICh0aGlzLnNlbGZDbG9zaW5nKSB7XG4gICAgICBibG9ja3MgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAodGhpcy5ibG9ja3MubGVuZ3RoID4gMCkge1xuICAgICAgbGV0IGtleXM6IHN0cmluZ1tdID0gW107XG4gICAgICBsZXQgdmFsdWVzOiBTZXJpYWxpemVkSW5saW5lQmxvY2tbXSA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYmxvY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBba2V5LCB2YWx1ZV0gPSB0aGlzLmJsb2Nrc1tpXTtcbiAgICAgICAga2V5cy5wdXNoKGtleS5zbGljZSgxKSk7XG4gICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGJsb2NrcyA9IFtrZXlzLCB2YWx1ZXNdO1xuICAgIH0gZWxzZSB7XG4gICAgICBibG9ja3MgPSBbXG4gICAgICAgIFsnZGVmYXVsdCddLFxuICAgICAgICBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogdGhpcy50YWJsZS5zbG90cyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgXTtcbiAgICB9XG5cbiAgICByZXR1cm4gW3RoaXMudGFnLCB0aGlzLmF0dHJpYnV0ZXMsIFtrZXlzLCB2YWx1ZXNdLCBibG9ja3NdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZSB7XG4gIHB1YmxpYyBibG9jazogVGVtcGxhdGVCbG9jaztcblxuICBjb25zdHJ1Y3RvcihzeW1ib2xzOiBBU1QuUHJvZ3JhbVN5bWJvbHMpIHtcbiAgICB0aGlzLmJsb2NrID0gbmV3IFRlbXBsYXRlQmxvY2soc3ltYm9scyk7XG4gIH1cblxuICB0b0pTT04oKTogU2VyaWFsaXplZFRlbXBsYXRlQmxvY2sge1xuICAgIHJldHVybiB0aGlzLmJsb2NrLnRvSlNPTigpO1xuICB9XG59XG5cbnR5cGUgSW5wdXQgPSByZWFkb25seSBPcHM8SmF2YVNjcmlwdENvbXBpbGVyT3BzPltdO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBKYXZhU2NyaXB0Q29tcGlsZXIgaW1wbGVtZW50cyBQcm9jZXNzb3I8SmF2YVNjcmlwdENvbXBpbGVyT3BzPiB7XG4gIHN0YXRpYyBwcm9jZXNzKFxuICAgIG9wY29kZXM6IElucHV0LFxuICAgIGxvY2F0aW9uczogcmVhZG9ubHkgT3B0aW9uPFNvdXJjZUxvY2F0aW9uPltdLFxuICAgIHN5bWJvbHM6IEFTVC5Qcm9ncmFtU3ltYm9scyxcbiAgICBvcHRpb25zPzogQ29tcGlsZU9wdGlvbnNcbiAgKTogVGVtcGxhdGUge1xuICAgIGxldCBjb21waWxlciA9IG5ldyBKYXZhU2NyaXB0Q29tcGlsZXIob3Bjb2Rlcywgc3ltYm9scywgbG9jYXRpb25zLCBvcHRpb25zKTtcbiAgICByZXR1cm4gY29tcGlsZXIucHJvY2VzcygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSB0ZW1wbGF0ZTogVGVtcGxhdGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmxvY2tzID0gbmV3IFN0YWNrPEJsb2NrPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG9wY29kZXM6IHJlYWRvbmx5IE9wczxKYXZhU2NyaXB0Q29tcGlsZXJPcHM+W107XG4gIHByaXZhdGUgcmVhZG9ubHkgdmFsdWVzOiBTdGFja1ZhbHVlW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBDb21waWxlT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBsb2NhdGlvbjogT3B0aW9uPFNvdXJjZUxvY2F0aW9uPiA9IG51bGw7XG4gIHByaXZhdGUgbG9jYXRpb25TdGFjazogT3B0aW9uPFNvdXJjZUxvY2F0aW9uPltdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgb3Bjb2RlczogSW5wdXQsXG4gICAgc3ltYm9sczogQVNULlByb2dyYW1TeW1ib2xzLFxuICAgIHByaXZhdGUgbG9jYXRpb25zOiByZWFkb25seSBPcHRpb248U291cmNlTG9jYXRpb24+W10sXG4gICAgb3B0aW9ucz86IENvbXBpbGVPcHRpb25zXG4gICkge1xuICAgIHRoaXMub3Bjb2RlcyA9IG9wY29kZXM7XG4gICAgdGhpcy50ZW1wbGF0ZSA9IG5ldyBUZW1wbGF0ZShzeW1ib2xzKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgZ2V0IGN1cnJlbnRCbG9jaygpOiBCbG9jayB7XG4gICAgcmV0dXJuIGV4cGVjdCh0aGlzLmJsb2Nrcy5jdXJyZW50LCAnRXhwZWN0ZWQgYSBibG9jayBvbiB0aGUgc3RhY2snKTtcbiAgfVxuXG4gIGdldCBjdXJyZW50Q29tcG9uZW50KCk6IENvbXBvbmVudEJsb2NrIHtcbiAgICBsZXQgYmxvY2sgPSB0aGlzLmN1cnJlbnRCbG9jaztcblxuICAgIGlmIChibG9jayBpbnN0YW5jZW9mIENvbXBvbmVudEJsb2NrKSB7XG4gICAgICByZXR1cm4gYmxvY2s7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgQ29tcG9uZW50QmxvY2sgb24gc3RhY2ssIGZvdW5kICR7YmxvY2suY29uc3RydWN0b3IubmFtZX1gKTtcbiAgICB9XG4gIH1cblxuICBwcm9jZXNzKCk6IFRlbXBsYXRlIHtcbiAgICB0aGlzLm9wY29kZXMuZm9yRWFjaCgob3AsIGkpID0+IHtcbiAgICAgIGxldCBvcGNvZGUgPSBvcFswXTtcbiAgICAgIHRoaXMubG9jYXRpb24gPSB0aGlzLmxvY2F0aW9uc1tpXTtcblxuICAgICAgbGV0IGFyZyA9IG9wWzFdO1xuXG4gICAgICBpZiAoIXRoaXNbb3Bjb2RlXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuaW1wbGVtZW50ZWQgJHtvcGNvZGV9IG9uIEphdmFTY3JpcHRDb21waWxlcmApO1xuICAgICAgfVxuICAgICAgKHRoaXNbb3Bjb2RlXSBhcyBhbnkpKGFyZyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMudGVtcGxhdGU7XG4gIH1cblxuICAvLy8gTmVzdGluZ1xuXG4gIHN0YXJ0QmxvY2socHJvZ3JhbTogQVNULkJsb2NrKSB7XG4gICAgdGhpcy5zdGFydElubGluZUJsb2NrKHByb2dyYW0uc3ltYm9scyEpO1xuICB9XG5cbiAgZW5kQmxvY2soKSB7XG4gICAgbGV0IGJsb2NrID0gdGhpcy5lbmRJbmxpbmVCbG9jaygpO1xuICAgIHRoaXMudGVtcGxhdGUuYmxvY2suYmxvY2tzLnB1c2goYmxvY2spO1xuICB9XG5cbiAgc3RhcnRQcm9ncmFtKCkge1xuICAgIHRoaXMuYmxvY2tzLnB1c2godGhpcy50ZW1wbGF0ZS5ibG9jayk7XG4gIH1cblxuICBlbmRQcm9ncmFtKCkge31cblxuICAvLy8gU3RhdGVtZW50c1xuXG4gIHRleHQoY29udGVudDogc3RyaW5nKSB7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5BcHBlbmQsIDEsIDAsIDAsIGNvbnRlbnRdKTtcbiAgfVxuXG4gIGFwcGVuZCh0cnVzdGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5BcHBlbmQsICt0cnVzdGVkLCAwLCAwLCB0aGlzLnBvcFZhbHVlPEV4cHJlc3Npb24+KCldKTtcbiAgfVxuXG4gIGNvbW1lbnQodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuQ29tbWVudCwgdmFsdWVdKTtcbiAgfVxuXG4gIG1vZGlmaWVyKCkge1xuICAgIGxldCBuYW1lID0gdGhpcy5wb3BWYWx1ZTxFeHByZXNzaW9uPigpO1xuICAgIGxldCBwYXJhbXMgPSB0aGlzLnBvcFZhbHVlPFBhcmFtcz4oKTtcbiAgICBsZXQgaGFzaCA9IHRoaXMucG9wVmFsdWU8SGFzaD4oKTtcbiAgICB0aGlzLnB1c2goW1NleHBPcGNvZGVzLk1vZGlmaWVyLCAwLCAwLCBuYW1lLCBwYXJhbXMsIGhhc2hdKTtcbiAgfVxuXG4gIGJsb2NrKFt0ZW1wbGF0ZSwgaW52ZXJzZV06IFtudW1iZXIsIE9wdGlvbjxudW1iZXI+XSkge1xuICAgIGxldCBoZWFkID0gdGhpcy5wb3BWYWx1ZTxFeHByZXNzaW9uPigpO1xuICAgIGxldCBwYXJhbXMgPSB0aGlzLnBvcFZhbHVlPFBhcmFtcz4oKTtcbiAgICBsZXQgaGFzaCA9IHRoaXMucG9wVmFsdWU8SGFzaD4oKTtcblxuICAgIGxldCBibG9ja3MgPSB0aGlzLnRlbXBsYXRlLmJsb2NrLmJsb2NrcztcbiAgICBhc3NlcnQoXG4gICAgICB0eXBlb2YgdGVtcGxhdGUgIT09ICdudW1iZXInIHx8IGJsb2Nrc1t0ZW1wbGF0ZV0gIT09IG51bGwsXG4gICAgICAnbWlzc2luZyBibG9jayBpbiB0aGUgY29tcGlsZXInXG4gICAgKTtcbiAgICBhc3NlcnQoXG4gICAgICB0eXBlb2YgaW52ZXJzZSAhPT0gJ251bWJlcicgfHwgYmxvY2tzW2ludmVyc2VdICE9PSBudWxsLFxuICAgICAgJ21pc3NpbmcgYmxvY2sgaW4gdGhlIGNvbXBpbGVyJ1xuICAgICk7XG5cbiAgICBsZXQgbmFtZWRCbG9ja3M6IE9wdGlvbjxDb3JlLkJsb2Nrcz47XG5cbiAgICBpZiAodGVtcGxhdGUgPT09IG51bGwgJiYgaW52ZXJzZSA9PT0gbnVsbCkge1xuICAgICAgbmFtZWRCbG9ja3MgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAoaW52ZXJzZSA9PT0gbnVsbCkge1xuICAgICAgbmFtZWRCbG9ja3MgPSBbWydkZWZhdWx0J10sIFtibG9ja3NbdGVtcGxhdGVdXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWVkQmxvY2tzID0gW1snZGVmYXVsdCcsICdlbHNlJ10sIFtibG9ja3NbdGVtcGxhdGVdLCBibG9ja3NbaW52ZXJzZV1dXTtcbiAgICB9XG5cbiAgICAvLyBhc3NlcnQoaGVhZFtdKTtcblxuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuQmxvY2ssIGhlYWQsIHBhcmFtcywgaGFzaCwgbmFtZWRCbG9ja3NdKTtcbiAgfVxuXG4gIG9wZW5Db21wb25lbnQoZWxlbWVudDogQVNULkVsZW1lbnROb2RlKSB7XG4gICAgbGV0IHRhZyA9XG4gICAgICB0aGlzLm9wdGlvbnMgJiYgdGhpcy5vcHRpb25zLmN1c3RvbWl6ZUNvbXBvbmVudE5hbWVcbiAgICAgICAgPyB0aGlzLm9wdGlvbnMuY3VzdG9taXplQ29tcG9uZW50TmFtZShlbGVtZW50LnRhZylcbiAgICAgICAgOiBlbGVtZW50LnRhZztcbiAgICBsZXQgY29tcG9uZW50ID0gbmV3IENvbXBvbmVudEJsb2NrKHRhZywgZWxlbWVudC5zeW1ib2xzISwgZWxlbWVudC5zZWxmQ2xvc2luZyk7XG4gICAgdGhpcy5ibG9ja3MucHVzaChjb21wb25lbnQpO1xuICB9XG5cbiAgb3Blbk5hbWVkQmxvY2soZWxlbWVudDogQVNULkVsZW1lbnROb2RlKSB7XG4gICAgbGV0IGJsb2NrOiBCbG9jayA9IG5ldyBOYW1lZEJsb2NrKGVsZW1lbnQudGFnLCBlbGVtZW50LnN5bWJvbHMhKTtcbiAgICB0aGlzLmJsb2Nrcy5wdXNoKGJsb2NrKTtcbiAgfVxuXG4gIG9wZW5FbGVtZW50KFtlbGVtZW50LCBzaW1wbGVdOiBbQVNULkVsZW1lbnROb2RlLCBib29sZWFuXSkge1xuICAgIGxldCB0YWcgPSBlbGVtZW50LnRhZztcblxuICAgIGlmIChlbGVtZW50LmJsb2NrUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvbXBpbGUgRXJyb3I6IDwke2VsZW1lbnQudGFnfT4gaXMgbm90IGEgY29tcG9uZW50IGFuZCBkb2Vzbid0IHN1cHBvcnQgYmxvY2sgcGFyYW1ldGVyc2BcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuT3BlbkVsZW1lbnQsIHRhZywgc2ltcGxlXSk7XG4gICAgfVxuICB9XG5cbiAgZmx1c2hFbGVtZW50KCkge1xuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuRmx1c2hFbGVtZW50XSk7XG4gIH1cblxuICBjbG9zZUNvbXBvbmVudChfZWxlbWVudDogQVNULkVsZW1lbnROb2RlKSB7XG4gICAgbGV0IFt0YWcsIGF0dHJzLCBhcmdzLCBibG9ja3NdID0gdGhpcy5lbmRDb21wb25lbnQoKTtcblxuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuQ29tcG9uZW50LCB0YWcsIGF0dHJzLCBhcmdzLCBibG9ja3NdKTtcbiAgfVxuXG4gIGNsb3NlTmFtZWRCbG9jayhfZWxlbWVudDogQVNULkVsZW1lbnROb2RlKSB7XG4gICAgbGV0IHsgYmxvY2tzIH0gPSB0aGlzO1xuICAgIGxldCBibG9jayA9IGV4cGVjdChibG9ja3MucG9wKCksIGBFeHBlY3RlZCBhIG5hbWVkIGJsb2NrIG9uIHRoZSBzdGFja2ApIGFzIE5hbWVkQmxvY2s7XG5cbiAgICB0aGlzLmN1cnJlbnRDb21wb25lbnQucHVzaEJsb2NrKGJsb2NrLm5hbWUsIGJsb2NrLnRvSlNPTigpKTtcbiAgfVxuXG4gIGNsb3NlRHluYW1pY0NvbXBvbmVudChfZWxlbWVudDogQVNULkVsZW1lbnROb2RlKSB7XG4gICAgbGV0IFssIGF0dHJzLCBhcmdzLCBibG9ja10gPSB0aGlzLmVuZENvbXBvbmVudCgpO1xuXG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5Db21wb25lbnQsIHRoaXMucG9wVmFsdWU8RXhwcmVzc2lvbj4oKSwgYXR0cnMsIGFyZ3MsIGJsb2NrXSk7XG4gIH1cblxuICBjbG9zZUVsZW1lbnQoX2VsZW1lbnQ6IEFTVC5FbGVtZW50Tm9kZSkge1xuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuQ2xvc2VFbGVtZW50XSk7XG4gIH1cblxuICBzdGF0aWNBdHRyKFtuYW1lLCBuYW1lc3BhY2VdOiBbc3RyaW5nLCBPcHRpb248c3RyaW5nPl0pIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLnBvcFZhbHVlPHN0cmluZz4oKTtcbiAgICB0aGlzLnB1c2goW1NleHBPcGNvZGVzLlN0YXRpY0F0dHIsIG5hbWUsIHZhbHVlLCBuYW1lc3BhY2VdKTtcbiAgfVxuXG4gIGR5bmFtaWNBdHRyKFtuYW1lLCBuYW1lc3BhY2VdOiBbc3RyaW5nLCBPcHRpb248c3RyaW5nPl0pIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLnBvcFZhbHVlPEV4cHJlc3Npb24+KCk7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5EeW5hbWljQXR0ciwgbmFtZSwgdmFsdWUsIG5hbWVzcGFjZV0pO1xuICB9XG5cbiAgY29tcG9uZW50QXR0cihbbmFtZSwgbmFtZXNwYWNlXTogW3N0cmluZywgT3B0aW9uPHN0cmluZz5dKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5wb3BWYWx1ZTxFeHByZXNzaW9uPigpO1xuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuQ29tcG9uZW50QXR0ciwgbmFtZSwgdmFsdWUsIG5hbWVzcGFjZV0pO1xuICB9XG5cbiAgdHJ1c3RpbmdBdHRyKFtuYW1lLCBuYW1lc3BhY2VdOiBbc3RyaW5nLCBPcHRpb248c3RyaW5nPl0pIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLnBvcFZhbHVlPEV4cHJlc3Npb24+KCk7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5UcnVzdGluZ0R5bmFtaWNBdHRyLCBuYW1lLCB2YWx1ZSwgbmFtZXNwYWNlIV0pO1xuICB9XG5cbiAgdHJ1c3RpbmdDb21wb25lbnRBdHRyKFtuYW1lLCBuYW1lc3BhY2VdOiBbc3RyaW5nLCBPcHRpb248c3RyaW5nPl0pIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLnBvcFZhbHVlPEV4cHJlc3Npb24+KCk7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5UcnVzdGluZ0NvbXBvbmVudEF0dHIsIG5hbWUsIHZhbHVlLCBuYW1lc3BhY2UhXSk7XG4gIH1cblxuICBzdGF0aWNBcmcobmFtZTogc3RyKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5wb3BWYWx1ZTxFeHByZXNzaW9uPigpO1xuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuU3RhdGljQXJnLCBuYW1lLCB2YWx1ZV0pO1xuICB9XG5cbiAgZHluYW1pY0FyZyhuYW1lOiBzdHIpIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLnBvcFZhbHVlPEV4cHJlc3Npb24+KCk7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5EeW5hbWljQXJnLCBuYW1lLCB2YWx1ZV0pO1xuICB9XG5cbiAgeWllbGQodG86IG51bWJlcikge1xuICAgIGxldCBwYXJhbXMgPSB0aGlzLnBvcFZhbHVlPFBhcmFtcz4oKTtcbiAgICB0aGlzLnB1c2goW1NleHBPcGNvZGVzLllpZWxkLCB0bywgcGFyYW1zXSk7XG4gIH1cblxuICBhdHRyU3BsYXQodG86IE9wdGlvbjxudW1iZXI+KSB7XG4gICAgLy8gY29uc3VtZSAoYW5kIGRpc3JlZ2FyZCkgdGhlIHZhbHVlIHB1c2hlZCBmb3IgdGhlXG4gICAgLy8gLi4uYXR0cmlidXRlcyBhdHRyaWJ1dGVcbiAgICB0aGlzLnBvcFZhbHVlKCk7XG4gICAgdGhpcy5wdXNoKFtTZXhwT3Bjb2Rlcy5BdHRyU3BsYXQsIHRvIV0pO1xuICB9XG5cbiAgZGVidWdnZXIoZXZhbEluZm86IE9wdGlvbjxDb3JlLkV2YWxJbmZvPikge1xuICAgIHRoaXMucHVzaChbU2V4cE9wY29kZXMuRGVidWdnZXIsIGV2YWxJbmZvIV0pO1xuICAgIHRoaXMudGVtcGxhdGUuYmxvY2suaGFzRXZhbCA9IHRydWU7XG4gIH1cblxuICBoYXNCbG9jayhuYW1lOiBudW1iZXIpIHtcbiAgICB0aGlzLnB1c2hWYWx1ZTxFeHByZXNzaW9ucy5IYXNCbG9jaz4oW1NleHBPcGNvZGVzLkhhc0Jsb2NrLCBbU2V4cE9wY29kZXMuR2V0U3ltYm9sLCBuYW1lXV0pO1xuICB9XG5cbiAgaGFzQmxvY2tQYXJhbXMobmFtZTogbnVtYmVyKSB7XG4gICAgdGhpcy5wdXNoVmFsdWU8RXhwcmVzc2lvbnMuSGFzQmxvY2tQYXJhbXM+KFtcbiAgICAgIFNleHBPc