@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
480 lines (379 loc) • 43.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ListBlockOpcode = exports.ListItemOpcode = exports.TryOpcode = exports.BlockOpcode = exports.ResumableVMStateImpl = exports.default = void 0;
var _env = require("@glimmer/env");
var _reference = require("@glimmer/reference");
var _destroyable = require("@glimmer/destroyable");
var _util = require("@glimmer/util");
var _validator = require("@glimmer/validator");
var _bounds = require("../bounds");
var _elementBuilder = require("./element-builder");
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var UpdatingVMImpl = /*#__PURE__*/function () {
function UpdatingVMImpl(env, _ref) {
var _ref$alwaysRevalidate = _ref.alwaysRevalidate,
alwaysRevalidate = _ref$alwaysRevalidate === void 0 ? false : _ref$alwaysRevalidate;
this.frameStack = new _util.Stack();
this.env = env;
this.dom = env.getDOM();
this.alwaysRevalidate = alwaysRevalidate;
}
var _proto = UpdatingVMImpl.prototype;
_proto.execute = function execute(opcodes, handler) {
var _this = this;
if (_env.DEBUG) {
var hasErrored = true;
try {
(0, _validator.runInTrackingTransaction)(function () {
return _this._execute(opcodes, handler);
}, '- While rendering:'); // using a boolean here to avoid breaking ergonomics of "pause on uncaught exceptions"
// which would happen with a `catch` + `throw`
hasErrored = false;
} finally {
if (hasErrored) {
// eslint-disable-next-line no-console
console.error("\n\nError occurred:\n\n" + (0, _validator.resetTracking)() + "\n\n");
}
}
} else {
this._execute(opcodes, handler);
}
};
_proto._execute = function _execute(opcodes, handler) {
var frameStack = this.frameStack;
this["try"](opcodes, handler);
while (true) {
if (frameStack.isEmpty()) break;
var opcode = this.frame.nextStatement();
if (opcode === undefined) {
frameStack.pop();
continue;
}
opcode.evaluate(this);
}
};
_proto["goto"] = function goto(index) {
this.frame["goto"](index);
};
_proto["try"] = function _try(ops, handler) {
this.frameStack.push(new UpdatingVMFrame(ops, handler));
};
_proto["throw"] = function _throw() {
this.frame.handleException();
this.frameStack.pop();
};
_createClass(UpdatingVMImpl, [{
key: "frame",
get: function get() {
return this.frameStack.current;
}
}]);
return UpdatingVMImpl;
}();
exports.default = UpdatingVMImpl;
var ResumableVMStateImpl = /*#__PURE__*/function () {
function ResumableVMStateImpl(state, resumeCallback) {
this.state = state;
this.resumeCallback = resumeCallback;
}
var _proto2 = ResumableVMStateImpl.prototype;
_proto2.resume = function resume(runtime, builder) {
return this.resumeCallback(runtime, this.state, builder);
};
return ResumableVMStateImpl;
}();
exports.ResumableVMStateImpl = ResumableVMStateImpl;
var BlockOpcode = /*#__PURE__*/function () {
function BlockOpcode(state, runtime, bounds, children) {
this.state = state;
this.runtime = runtime;
this.children = children;
this.bounds = bounds;
}
var _proto3 = BlockOpcode.prototype;
_proto3.parentElement = function parentElement() {
return this.bounds.parentElement();
};
_proto3.firstNode = function firstNode() {
return this.bounds.firstNode();
};
_proto3.lastNode = function lastNode() {
return this.bounds.lastNode();
};
_proto3.evaluate = function evaluate(vm) {
vm["try"](this.children, null);
};
return BlockOpcode;
}();
exports.BlockOpcode = BlockOpcode;
var TryOpcode = /*#__PURE__*/function (_BlockOpcode) {
_inheritsLoose(TryOpcode, _BlockOpcode);
function TryOpcode() {
var _this2;
_this2 = _BlockOpcode.apply(this, arguments) || this;
_this2.type = 'try';
return _this2;
}
var _proto4 = TryOpcode.prototype;
_proto4.evaluate = function evaluate(vm) {
vm["try"](this.children, this);
};
_proto4.handleException = function handleException() {
var _this3 = this;
var state = this.state,
bounds = this.bounds,
runtime = this.runtime;
(0, _destroyable.destroyChildren)(this);
var elementStack = _elementBuilder.NewElementBuilder.resume(runtime.env, bounds);
var vm = state.resume(runtime, elementStack);
var updating = [];
var children = this.children = [];
var result = vm.execute(function (vm) {
vm.pushUpdating(updating);
vm.updateWith(_this3);
vm.pushUpdating(children);
});
(0, _destroyable.associateDestroyableChild)(this, result.drop);
};
return TryOpcode;
}(BlockOpcode);
exports.TryOpcode = TryOpcode;
var ListItemOpcode = /*#__PURE__*/function (_TryOpcode) {
_inheritsLoose(ListItemOpcode, _TryOpcode);
function ListItemOpcode(state, runtime, bounds, key, memo, value) {
var _this4;
_this4 = _TryOpcode.call(this, state, runtime, bounds, []) || this;
_this4.key = key;
_this4.memo = memo;
_this4.value = value;
_this4.retained = false;
_this4.index = -1;
return _this4;
}
var _proto5 = ListItemOpcode.prototype;
_proto5.updateReferences = function updateReferences(item) {
this.retained = true;
(0, _reference.updateRef)(this.value, item.value);
(0, _reference.updateRef)(this.memo, item.memo);
};
_proto5.shouldRemove = function shouldRemove() {
return !this.retained;
};
_proto5.reset = function reset() {
this.retained = false;
};
return ListItemOpcode;
}(TryOpcode);
exports.ListItemOpcode = ListItemOpcode;
var ListBlockOpcode = /*#__PURE__*/function (_BlockOpcode2) {
_inheritsLoose(ListBlockOpcode, _BlockOpcode2);
function ListBlockOpcode(state, runtime, bounds, children, iterableRef) {
var _this5;
_this5 = _BlockOpcode2.call(this, state, runtime, bounds, children) || this;
_this5.iterableRef = iterableRef;
_this5.type = 'list-block';
_this5.opcodeMap = new Map();
_this5.marker = null;
_this5.lastIterator = (0, _reference.valueForRef)(iterableRef);
return _this5;
}
var _proto6 = ListBlockOpcode.prototype;
_proto6.initializeChild = function initializeChild(opcode) {
opcode.index = this.children.length - 1;
this.opcodeMap.set(opcode.key, opcode);
};
_proto6.evaluate = function evaluate(vm) {
var iterator = (0, _reference.valueForRef)(this.iterableRef);
if (this.lastIterator !== iterator) {
var bounds = this.bounds;
var dom = vm.dom;
var marker = this.marker = dom.createComment('');
dom.insertAfter(bounds.parentElement(), marker, bounds.lastNode());
this.sync(iterator);
this.parentElement().removeChild(marker);
this.marker = null;
this.lastIterator = iterator;
} // Run now-updated updating opcodes
_BlockOpcode2.prototype.evaluate.call(this, vm);
};
_proto6.sync = function sync(iterator) {
var itemMap = this.opcodeMap,
children = this.children;
var currentOpcodeIndex = 0;
var seenIndex = 0;
this.children = this.bounds.boundList = [];
while (true) {
var item = iterator.next();
if (item === null) break;
var opcode = children[currentOpcodeIndex];
var key = item.key; // Items that have already been found and moved will already be retained,
// we can continue until we find the next unretained item
while (opcode !== undefined && opcode.retained === true) {
opcode = children[++currentOpcodeIndex];
}
if (opcode !== undefined && opcode.key === key) {
this.retainItem(opcode, item);
currentOpcodeIndex++;
} else if (itemMap.has(key)) {
var itemOpcode = itemMap.get(key); // The item opcode was seen already, so we should move it.
if (itemOpcode.index < seenIndex) {
this.moveItem(itemOpcode, item, opcode);
} else {
// Update the seen index, we are going to be moving this item around
// so any other items that come before it will likely need to move as
// well.
seenIndex = itemOpcode.index;
var seenUnretained = false; // iterate through all of the opcodes between the current position and
// the position of the item's opcode, and determine if they are all
// retained.
for (var i = currentOpcodeIndex + 1; i < seenIndex; i++) {
if (children[i].retained === false) {
seenUnretained = true;
break;
}
} // If we have seen only retained opcodes between this and the matching
// opcode, it means that all the opcodes in between have been moved
// already, and we can safely retain this item's opcode.
if (seenUnretained === false) {
this.retainItem(itemOpcode, item);
currentOpcodeIndex = seenIndex + 1;
} else {
this.moveItem(itemOpcode, item, opcode);
currentOpcodeIndex++;
}
}
} else {
this.insertItem(item, opcode);
}
}
for (var _i = 0; _i < children.length; _i++) {
var _opcode = children[_i];
if (_opcode.retained === false) {
this.deleteItem(_opcode);
} else {
_opcode.reset();
}
}
};
_proto6.retainItem = function retainItem(opcode, item) {
if (false
/* LOCAL_DEBUG */
) {
(0, _util.logStep)('list-updates', ['retain', item.key]);
}
var children = this.children;
(0, _reference.updateRef)(opcode.memo, item.memo);
(0, _reference.updateRef)(opcode.value, item.value);
opcode.retained = true;
opcode.index = children.length;
children.push(opcode);
};
_proto6.insertItem = function insertItem(item, before) {
var _this6 = this;
if (false
/* LOCAL_DEBUG */
) {
(0, _util.logStep)('list-updates', ['insert', item.key]);
}
var opcodeMap = this.opcodeMap,
bounds = this.bounds,
state = this.state,
runtime = this.runtime,
children = this.children;
var key = item.key;
var nextSibling = before === undefined ? this.marker : before.firstNode();
var elementStack = _elementBuilder.NewElementBuilder.forInitialRender(runtime.env, {
element: bounds.parentElement(),
nextSibling: nextSibling
});
var vm = state.resume(runtime, elementStack);
vm.execute(function (vm) {
vm.pushUpdating();
var opcode = vm.enterItem(item);
opcode.index = children.length;
children.push(opcode);
opcodeMap.set(key, opcode);
(0, _destroyable.associateDestroyableChild)(_this6, opcode);
});
};
_proto6.moveItem = function moveItem(opcode, item, before) {
var children = this.children;
(0, _reference.updateRef)(opcode.memo, item.memo);
(0, _reference.updateRef)(opcode.value, item.value);
opcode.retained = true;
var currentSibling, nextSibling;
if (before === undefined) {
(0, _bounds.move)(opcode, this.marker);
} else {
currentSibling = opcode.lastNode().nextSibling;
nextSibling = before.firstNode(); // Items are moved throughout the algorithm, so there are cases where the
// the items already happen to be siblings (e.g. an item in between was
// moved before this move happened). Check to see if they are siblings
// first before doing the move.
if (currentSibling !== nextSibling) {
(0, _bounds.move)(opcode, nextSibling);
}
}
opcode.index = children.length;
children.push(opcode);
if (false
/* LOCAL_DEBUG */
) {
var type = currentSibling && currentSibling === nextSibling ? 'move-retain' : 'move';
(0, _util.logStep)('list-updates', [type, item.key]);
}
};
_proto6.deleteItem = function deleteItem(opcode) {
if (false
/* LOCAL_DEBUG */
) {
(0, _util.logStep)('list-updates', ['delete', opcode.key]);
}
(0, _destroyable.destroy)(opcode);
(0, _bounds.clear)(opcode);
this.opcodeMap["delete"](opcode.key);
};
return ListBlockOpcode;
}(BlockOpcode);
exports.ListBlockOpcode = ListBlockOpcode;
var UpdatingVMFrame = /*#__PURE__*/function () {
function UpdatingVMFrame(ops, exceptionHandler) {
this.ops = ops;
this.exceptionHandler = exceptionHandler;
this.current = 0;
}
var _proto7 = UpdatingVMFrame.prototype;
_proto7["goto"] = function goto(index) {
this.current = index;
};
_proto7.nextStatement = function nextStatement() {
return this.ops[this.current++];
};
_proto7.handleException = function handleException() {
if (this.exceptionHandler) {
this.exceptionHandler.handleException();
}
};
return UpdatingVMFrame;
}();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3VwZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBaUJBOztBQU9BOztBQUNBOztBQUNBOztBQUVBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFFYyxjO0FBT1osV0FBQSxjQUFBLENBQUEsR0FBQSxFQUFBLElBQUEsRUFBMEQ7QUFBQSxRQUFBLHFCQUFBLEdBQUEsSUFBQSxDQUExQixnQkFBMEI7QUFBQSxRQUExQixnQkFBMEIsR0FBQSxxQkFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFQLEtBQU8sR0FBQSxxQkFBQTtBQUZsRCxTQUFBLFVBQUEsR0FBcUMsSUFBckMsV0FBcUMsRUFBckM7QUFHTixTQUFBLEdBQUEsR0FBQSxHQUFBO0FBQ0EsU0FBQSxHQUFBLEdBQVcsR0FBRyxDQUFkLE1BQVcsRUFBWDtBQUNBLFNBQUEsZ0JBQUEsR0FBQSxnQkFBQTtBQUNEOzs7O1NBRUQsTyxHQUFBLFNBQUEsT0FBQSxDQUFBLE9BQUEsRUFBQSxPQUFBLEVBQTREO0FBQUEsUUFBQSxLQUFBLEdBQUEsSUFBQTs7QUFDMUQsUUFBQSxVQUFBLEVBQVc7QUFDVCxVQUFJLFVBQVUsR0FBZCxJQUFBOztBQUNBLFVBQUk7QUFDRixpREFBMEIsWUFBQTtBQUFBLGlCQUFNLEtBQUEsQ0FBQSxRQUFBLENBQUEsT0FBQSxFQUFQLE9BQU8sQ0FBTjtBQUFELFNBQXpCLEVBREUsb0JBQ0YsRUFERSxDQUdGO0FBQ0E7O0FBQ0EsUUFBQSxVQUFVLEdBQVYsS0FBQTtBQUxGLE9BQUEsU0FNVTtBQUNSLFlBQUEsVUFBQSxFQUFnQjtBQUNkO0FBQ0EsVUFBQSxPQUFPLENBQVAsS0FBQSxDQUFBLDRCQUFBLCtCQUFBLEdBQUEsTUFBQTtBQUNEO0FBQ0Y7QUFiSCxLQUFBLE1BY087QUFDTCxXQUFBLFFBQUEsQ0FBQSxPQUFBLEVBQUEsT0FBQTtBQUNEOzs7U0FHSyxRLEdBQUEsU0FBQSxRQUFBLENBQUEsT0FBQSxFQUFBLE9BQUEsRUFBNkQ7QUFBQSxRQUM3RCxVQUQ2RCxHQUFBLEtBQUEsVUFBQTtBQUduRSxTQUFBLEtBQUEsRUFBQSxPQUFBLEVBQUEsT0FBQTs7QUFFQSxXQUFBLElBQUEsRUFBYTtBQUNYLFVBQUksVUFBVSxDQUFkLE9BQUksRUFBSixFQUEwQjtBQUUxQixVQUFJLE1BQU0sR0FBRyxLQUFBLEtBQUEsQ0FBYixhQUFhLEVBQWI7O0FBRUEsVUFBSSxNQUFNLEtBQVYsU0FBQSxFQUEwQjtBQUN4QixRQUFBLFVBQVUsQ0FBVixHQUFBO0FBQ0E7QUFDRDs7QUFFRCxNQUFBLE1BQU0sQ0FBTixRQUFBLENBQUEsSUFBQTtBQUNEOzs7bUJBT0gsU0FBQSxJQUFBLENBQUEsS0FBQSxFQUFrQjtBQUNoQixTQUFBLEtBQUEsQ0FBQSxNQUFBLEVBQUEsS0FBQTs7O2tCQUdGLFNBQUEsSUFBQSxDQUFBLEdBQUEsRUFBQSxPQUFBLEVBQTREO0FBQzFELFNBQUEsVUFBQSxDQUFBLElBQUEsQ0FBcUIsSUFBQSxlQUFBLENBQUEsR0FBQSxFQUFyQixPQUFxQixDQUFyQjs7O29CQUdGLFNBQUEsTUFBQSxHQUFLO0FBQ0gsU0FBQSxLQUFBLENBQUEsZUFBQTtBQUNBLFNBQUEsVUFBQSxDQUFBLEdBQUE7Ozs7O3dCQWRlO0FBQ2YsYUFBYyxLQUFBLFVBQUEsQ0FBZCxPQUFBO0FBQ0Q7Ozs7Ozs7O0FBMkJILElBQU0sb0JBQU4sR0FBQSxhQUFBLFlBQUE7QUFDRSxXQUFBLG9CQUFBLENBQUEsS0FBQSxFQUFBLGNBQUEsRUFBMkU7QUFBdEQsU0FBQSxLQUFBLEdBQUEsS0FBQTtBQUF3QixTQUFBLGNBQUEsR0FBQSxjQUFBO0FBQWtDOztBQURqRixNQUFBLE9BQUEsR0FBQSxvQkFBQSxDQUFBLFNBQUE7O0FBQUEsRUFBQSxPQUFBLENBQUEsTUFBQSxHQUdFLFNBQUEsTUFBQSxDQUFBLE9BQUEsRUFBQSxPQUFBLEVBQXVEO0FBQ3JELFdBQU8sS0FBQSxjQUFBLENBQUEsT0FBQSxFQUE2QixLQUE3QixLQUFBLEVBQVAsT0FBTyxDQUFQO0FBSkosR0FBQTs7QUFBQSxTQUFBLG9CQUFBO0FBQUEsQ0FBQSxFQUFBOzs7O0FBUUEsSUFBTSxXQUFOLEdBQUEsYUFBQSxZQUFBO0FBS0UsV0FBQSxXQUFBLENBQUEsS0FBQSxFQUFBLE9BQUEsRUFBQSxNQUFBLEVBQUEsUUFBQSxFQUk0QjtBQUhoQixTQUFBLEtBQUEsR0FBQSxLQUFBO0FBQ0EsU0FBQSxPQUFBLEdBQUEsT0FBQTtBQUlWLFNBQUEsUUFBQSxHQUFBLFFBQUE7QUFDQSxTQUFBLE1BQUEsR0FBQSxNQUFBO0FBQ0Q7O0FBYkgsTUFBQSxPQUFBLEdBQUEsV0FBQSxDQUFBLFNBQUE7O0FBQUEsRUFBQSxPQUFBLENBQUEsYUFBQSxHQWVFLFNBQUEsYUFBQSxHQUFhO0FBQ1gsV0FBTyxLQUFBLE1BQUEsQ0FBUCxhQUFPLEVBQVA7QUFoQkosR0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxTQUFBLEdBbUJFLFNBQUEsU0FBQSxHQUFTO0FBQ1AsV0FBTyxLQUFBLE1BQUEsQ0FBUCxTQUFPLEVBQVA7QUFwQkosR0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxRQUFBLEdBdUJFLFNBQUEsUUFBQSxHQUFRO0FBQ04sV0FBTyxLQUFBLE1BQUEsQ0FBUCxRQUFPLEVBQVA7QUF4QkosR0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxRQUFBLEdBMkJFLFNBQUEsUUFBQSxDQUFBLEVBQUEsRUFBMkI7QUFDekIsSUFBQSxFQUFBLENBQUEsS0FBQSxDQUFBLENBQU8sS0FBUCxRQUFBLEVBQUEsSUFBQTtBQTVCSixHQUFBOztBQUFBLFNBQUEsV0FBQTtBQUFBLENBQUEsRUFBQTs7OztBQWdDQSxJQUFNLFNBQU4sR0FBQSxhQUFBLFVBQUEsWUFBQSxFQUFBO0FBQUEsRUFBQSxjQUFBLENBQUEsU0FBQSxFQUFBLFlBQUEsQ0FBQTs7QUFBQSxXQUFBLFNBQUEsR0FBQTtBQUFBLFFBQUEsTUFBQTs7O0FBQ1MsSUFBQSxNQUFBLENBQUEsSUFBQSxHQUFBLEtBQUE7QUFEVCxXQUFBLE1BQUE7QUE0QkM7O0FBNUJELE1BQUEsT0FBQSxHQUFBLFNBQUEsQ0FBQSxTQUFBOztBQUFBLEVBQUEsT0FBQSxDQUFBLFFBQUEsR0FLRSxTQUFBLFFBQUEsQ0FBQSxFQUFBLEVBQTJCO0FBQ3pCLElBQUEsRUFBQSxDQUFBLEtBQUEsQ0FBQSxDQUFPLEtBQVAsUUFBQSxFQUFBLElBQUE7QUFOSixHQUFBOztBQUFBLEVBQUEsT0FBQSxDQUFBLGVBQUEsR0FTRSxTQUFBLGVBQUEsR0FBZTtBQUFBLFFBQUEsTUFBQSxHQUFBLElBQUE7O0FBQUEsUUFDVCxLQURTLEdBQUEsS0FBQSxLQUFBO0FBQUEsUUFDVCxNQURTLEdBQUEsS0FBQSxNQUFBO0FBQUEsUUFDUSxPQURSLEdBQUEsS0FBQSxPQUFBO0FBR2Isc0NBQUEsSUFBQTs7QUFFQSxRQUFJLFlBQVksR0FBRyxrQ0FBQSxNQUFBLENBQXlCLE9BQU8sQ0FBaEMsR0FBQSxFQUFuQixNQUFtQixDQUFuQjs7QUFDQSxRQUFJLEVBQUUsR0FBRyxLQUFLLENBQUwsTUFBQSxDQUFBLE9BQUEsRUFBVCxZQUFTLENBQVQ7QUFFQSxRQUFJLFFBQVEsR0FBWixFQUFBO0FBQ0EsUUFBSSxRQUFRLEdBQUksS0FBQSxRQUFBLEdBQWhCLEVBQUE7QUFFQSxRQUFJLE1BQU0sR0FBRyxFQUFFLENBQUYsT0FBQSxDQUFZLFVBQUQsRUFBQyxFQUFNO0FBQzdCLE1BQUEsRUFBRSxDQUFGLFlBQUEsQ0FBQSxRQUFBO0FBQ0EsTUFBQSxFQUFFLENBQUYsVUFBQSxDQUFBLE1BQUE7QUFDQSxNQUFBLEVBQUUsQ0FBRixZQUFBLENBQUEsUUFBQTtBQUhGLEtBQWEsQ0FBYjtBQU1BLGdEQUF5QixJQUF6QixFQUFnQyxNQUFNLENBQXRDLElBQUE7QUExQkosR0FBQTs7QUFBQSxTQUFBLFNBQUE7QUFBQSxDQUFBLENBQUEsV0FBQSxDQUFBOzs7O0FBOEJBLElBQU0sY0FBTixHQUFBLGFBQUEsVUFBQSxVQUFBLEVBQUE7QUFBQSxFQUFBLGNBQUEsQ0FBQSxjQUFBLEVBQUEsVUFBQSxDQUFBOztBQUlFLFdBQUEsY0FBQSxDQUFBLEtBQUEsRUFBQSxPQUFBLEVBQUEsTUFBQSxFQUFBLEdBQUEsRUFBQSxJQUFBLEVBQUEsS0FBQSxFQU15QjtBQUFBLFFBQUEsTUFBQTs7QUFFdkIsSUFBQSxNQUFBLEdBQUEsVUFBQSxDQUFBLElBQUEsQ0FBQSxJQUFBLEVBQUEsS0FBQSxFQUFBLE9BQUEsRUFBQSxNQUFBLEVBQUEsRUFBQSxLQUFBLElBQUE7QUFKTyxJQUFBLE1BQUEsQ0FBQSxHQUFBLEdBQUEsR0FBQTtBQUNBLElBQUEsTUFBQSxDQUFBLElBQUEsR0FBQSxJQUFBO0FBQ0EsSUFBQSxNQUFBLENBQUEsS0FBQSxHQUFBLEtBQUE7QUFURixJQUFBLE1BQUEsQ0FBQSxRQUFBLEdBQUEsS0FBQTtBQUNBLElBQUEsTUFBQSxDQUFBLEtBQUEsR0FBUSxDQUFSLENBQUE7QUFRa0IsV0FBQSxNQUFBO0FBR3hCOztBQWJILE1BQUEsT0FBQSxHQUFBLGNBQUEsQ0FBQSxTQUFBOztBQUFBLEVBQUEsT0FBQSxDQUFBLGdCQUFBLEdBZUUsU0FBQSxnQkFBQSxDQUFBLElBQUEsRUFBMEM7QUFDeEMsU0FBQSxRQUFBLEdBQUEsSUFBQTtBQUNBLDhCQUFVLEtBQUQsS0FBVCxFQUFzQixJQUFJLENBQTFCLEtBQUE7QUFDQSw4QkFBVSxLQUFELElBQVQsRUFBcUIsSUFBSSxDQUF6QixJQUFBO0FBbEJKLEdBQUE7O0FBQUEsRUFBQSxPQUFBLENBQUEsWUFBQSxHQXFCRSxTQUFBLFlBQUEsR0FBWTtBQUNWLFdBQU8sQ0FBQyxLQUFSLFFBQUE7QUF0QkosR0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxLQUFBLEdBeUJFLFNBQUEsS0FBQSxHQUFLO0FBQ0gsU0FBQSxRQUFBLEdBQUEsS0FBQTtBQTFCSixHQUFBOztBQUFBLFNBQUEsY0FBQTtBQUFBLENBQUEsQ0FBQSxTQUFBLENBQUE7Ozs7QUE4QkEsSUFBTSxlQUFOLEdBQUEsYUFBQSxVQUFBLGFBQUEsRUFBQTtBQUFBLEVBQUEsY0FBQSxDQUFBLGVBQUEsRUFBQSxhQUFBLENBQUE7O0FBVUUsV0FBQSxlQUFBLENBQUEsS0FBQSxFQUFBLE9BQUEsRUFBQSxNQUFBLEVBQUEsUUFBQSxFQUFBLFdBQUEsRUFLZ0Q7QUFBQSxRQUFBLE1BQUE7O0FBRTlDLElBQUEsTUFBQSxHQUFBLGFBQUEsQ0FBQSxJQUFBLENBQUEsSUFBQSxFQUFBLEtBQUEsRUFBQSxPQUFBLEVBQUEsTUFBQSxFQUFBLFFBQUEsS0FBQSxJQUFBO0FBRlEsSUFBQSxNQUFBLENBQUEsV0FBQSxHQUFBLFdBQUE7QUFkSCxJQUFBLE1BQUEsQ0FBQSxJQUFBLEdBQUEsWUFBQTtBQUdDLElBQUEsTUFBQSxDQUFBLFNBQUEsR0FBWSxJQUFaLEdBQVksRUFBWjtBQUNBLElBQUEsTUFBQSxDQUFBLE1BQUEsR0FBQSxJQUFBO0FBYU4sSUFBQSxNQUFBLENBQUEsWUFBQSxHQUFvQiw0QkFBcEIsV0FBb0IsQ0FBcEI7QUFIOEMsV0FBQSxNQUFBO0FBSS9DOztBQW5CSCxNQUFBLE9BQUEsR0FBQSxlQUFBLENBQUEsU0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxlQUFBLEdBcUJFLFNBQUEsZUFBQSxDQUFBLE1BQUEsRUFBc0M7QUFDcEMsSUFBQSxNQUFNLENBQU4sS0FBQSxHQUFlLEtBQUEsUUFBQSxDQUFBLE1BQUEsR0FBZixDQUFBO0FBQ0EsU0FBQSxTQUFBLENBQUEsR0FBQSxDQUFtQixNQUFNLENBQXpCLEdBQUEsRUFBQSxNQUFBO0FBdkJKLEdBQUE7O0FBQUEsRUFBQSxPQUFBLENBQUEsUUFBQSxHQTBCRSxTQUFBLFFBQUEsQ0FBQSxFQUFBLEVBQTJCO0FBQ3pCLFFBQUksUUFBUSxHQUFHLDRCQUFZLEtBQTNCLFdBQWUsQ0FBZjs7QUFFQSxRQUFJLEtBQUEsWUFBQSxLQUFKLFFBQUEsRUFBb0M7QUFBQSxVQUM1QixNQUQ0QixHQUFBLEtBQUEsTUFBQTtBQUFBLFVBRTVCLEdBRjRCLEdBRWxDLEVBRmtDLENBQUEsR0FBQTtBQUlsQyxVQUFJLE1BQU0sR0FBSSxLQUFBLE1BQUEsR0FBYyxHQUFHLENBQUgsYUFBQSxDQUE1QixFQUE0QixDQUE1QjtBQUNBLE1BQUEsR0FBRyxDQUFILFdBQUEsQ0FDRSxNQUFNLENBRFIsYUFDRSxFQURGLEVBQUEsTUFBQSxFQUdTLE1BQU0sQ0FIZixRQUdTLEVBSFQ7QUFNQSxXQUFBLElBQUEsQ0FBQSxRQUFBO0FBRUEsV0FBQSxhQUFBLEdBQUEsV0FBQSxDQUFBLE1BQUE7QUFDQSxXQUFBLE1BQUEsR0FBQSxJQUFBO0FBQ0EsV0FBQSxZQUFBLEdBQUEsUUFBQTtBQWxCdUIsS0FBQSxDQXFCekI7OztBQUNBLElBQUEsYUFBQSxDQUFBLFNBQUEsQ0FBQSxRQUFBLENBQUEsSUFBQSxDQUFBLElBQUEsRUFBQSxFQUFBO0FBaERKLEdBQUE7O0FBQUEsRUFBQSxPQUFBLENBQUEsSUFBQSxHQW1EVSxTQUFBLElBQUEsQ0FBQSxRQUFBLEVBQTZCO0FBQUEsUUFDL0IsT0FEK0IsR0FBQSxLQUFBLFNBQUE7QUFBQSxRQUNULFFBRFMsR0FBQSxLQUFBLFFBQUE7QUFHbkMsUUFBSSxrQkFBa0IsR0FBdEIsQ0FBQTtBQUNBLFFBQUksU0FBUyxHQUFiLENBQUE7QUFFQSxTQUFBLFFBQUEsR0FBZ0IsS0FBQSxNQUFBLENBQUEsU0FBQSxHQUFoQixFQUFBOztBQUVBLFdBQUEsSUFBQSxFQUFhO0FBQ1gsVUFBSSxJQUFJLEdBQUcsUUFBUSxDQUFuQixJQUFXLEVBQVg7QUFFQSxVQUFJLElBQUksS0FBUixJQUFBLEVBQW1CO0FBRW5CLFVBQUksTUFBTSxHQUFHLFFBQVEsQ0FBckIsa0JBQXFCLENBQXJCO0FBTFcsVUFNTCxHQU5LLEdBQUEsSUFBQSxDQUFBLEdBQUEsQ0FBQSxDQVFYO0FBQ0E7O0FBQ0EsYUFBTyxNQUFNLEtBQU4sU0FBQSxJQUF3QixNQUFNLENBQU4sUUFBQSxLQUEvQixJQUFBLEVBQXlEO0FBQ3ZELFFBQUEsTUFBTSxHQUFHLFFBQVEsQ0FBQyxFQUFsQixrQkFBaUIsQ0FBakI7QUFDRDs7QUFFRCxVQUFJLE1BQU0sS0FBTixTQUFBLElBQXdCLE1BQU0sQ0FBTixHQUFBLEtBQTVCLEdBQUEsRUFBZ0Q7QUFDOUMsYUFBQSxVQUFBLENBQUEsTUFBQSxFQUFBLElBQUE7QUFDQSxRQUFBLGtCQUFrQjtBQUZwQixPQUFBLE1BR08sSUFBSSxPQUFPLENBQVAsR0FBQSxDQUFKLEdBQUksQ0FBSixFQUFzQjtBQUMzQixZQUFJLFVBQVUsR0FBRyxPQUFPLENBQVAsR0FBQSxDQURVLEdBQ1YsQ0FBakIsQ0FEMkIsQ0FHM0I7O0FBQ0EsWUFBSSxVQUFVLENBQVYsS0FBQSxHQUFKLFNBQUEsRUFBa0M7QUFDaEMsZUFBQSxRQUFBLENBQUEsVUFBQSxFQUFBLElBQUEsRUFBQSxNQUFBO0FBREYsU0FBQSxNQUVPO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsVUFBQSxTQUFTLEdBQUcsVUFBVSxDQUF0QixLQUFBO0FBRUEsY0FBSSxjQUFjLEdBTmIsS0FNTCxDQU5LLENBUUw7QUFDQTtBQUNBOztBQUNBLGVBQUssSUFBSSxDQUFDLEdBQUcsa0JBQWtCLEdBQS9CLENBQUEsRUFBcUMsQ0FBQyxHQUF0QyxTQUFBLEVBQW9ELENBQXBELEVBQUEsRUFBeUQ7QUFDdkQsZ0JBQUksUUFBUSxDQUFSLENBQVEsQ0FBUixDQUFBLFFBQUEsS0FBSixLQUFBLEVBQW9DO0FBQ2xDLGNBQUEsY0FBYyxHQUFkLElBQUE7QUFDQTtBQUNEO0FBZkUsV0FBQSxDQWtCTDtBQUNBO0FBQ0E7OztBQUNBLGNBQUksY0FBYyxLQUFsQixLQUFBLEVBQThCO0FBQzVCLGlCQUFBLFVBQUEsQ0FBQSxVQUFBLEVBQUEsSUFBQTtBQUNBLFlBQUEsa0JBQWtCLEdBQUcsU0FBUyxHQUE5QixDQUFBO0FBRkYsV0FBQSxNQUdPO0FBQ0wsaUJBQUEsUUFBQSxDQUFBLFVBQUEsRUFBQSxJQUFBLEVBQUEsTUFBQTtBQUNBLFlBQUEsa0JBQWtCO0FBQ25CO0FBQ0Y7QUFsQ0ksT0FBQSxNQW1DQTtBQUNMLGFBQUEsVUFBQSxDQUFBLElBQUEsRUFBQSxNQUFBO0FBQ0Q7QUFDRjs7QUFFRCxTQUFLLElBQUksRUFBQyxHQUFWLENBQUEsRUFBZ0IsRUFBQyxHQUFHLFFBQVEsQ0FBNUIsTUFBQSxFQUFxQyxFQUFyQyxFQUFBLEVBQTBDO0FBQ3hDLFVBQUksT0FBTSxHQUFHLFFBQVEsQ0FBckIsRUFBcUIsQ0FBckI7O0FBRUEsVUFBSSxPQUFNLENBQU4sUUFBQSxLQUFKLEtBQUEsRUFBK0I7QUFDN0IsYUFBQSxVQUFBLENBQUEsT0FBQTtBQURGLE9BQUEsTUFFTztBQUNMLFFBQUEsT0FBTSxDQUFOLEtBQUE7QUFDRDtBQUNGO0FBNUhMLEdBQUE7O0FBQUEsRUFBQSxPQUFBLENBQUEsVUFBQSxHQStIVSxTQUFBLFVBQUEsQ0FBQSxNQUFBLEVBQUEsSUFBQSxFQUE0RDtBQUNsRSxRQUFBO0FBQUE7QUFBQSxNQUFpQjtBQUNmLDJCQUFRLGNBQVIsRUFBeUIsQ0FBQSxRQUFBLEVBQVcsSUFBSSxDQUF4QyxHQUF5QixDQUF6QjtBQUNEOztBQUhpRSxRQUs1RCxRQUw0RCxHQUFBLEtBQUEsUUFBQTtBQU9sRSw4QkFBVSxNQUFNLENBQVAsSUFBVCxFQUF1QixJQUFJLENBQTNCLElBQUE7QUFDQSw4QkFBVSxNQUFNLENBQVAsS0FBVCxFQUF3QixJQUFJLENBQTVCLEtBQUE7QUFDQSxJQUFBLE1BQU0sQ0FBTixRQUFBLEdBQUEsSUFBQTtBQUVBLElBQUEsTUFBTSxDQUFOLEtBQUEsR0FBZSxRQUFRLENBQXZCLE1BQUE7QUFDQSxJQUFBLFFBQVEsQ0FBUixJQUFBLENBQUEsTUFBQTtBQTNJSixHQUFBOztBQUFBLEVBQUEsT0FBQSxDQUFBLFVBQUEsR0E4SVUsU0FBQSxVQUFBLENBQUEsSUFBQSxFQUFBLE1BQUEsRUFBNEQ7QUFBQSxRQUFBLE1BQUEsR0FBQSxJQUFBOztBQUNsRSxRQUFBO0FBQUE7QUFBQSxNQUFpQjtBQUNmLDJCQUFRLGNBQVIsRUFBeUIsQ0FBQSxRQUFBLEVBQVcsSUFBSSxDQUF4QyxHQUF5QixDQUF6QjtBQUNEOztBQUhpRSxRQUs5RCxTQUw4RCxHQUFBLEtBQUEsU0FBQTtBQUFBLFFBSzlELE1BTDhELEdBQUEsS0FBQSxNQUFBO0FBQUEsUUFLOUQsS0FMOEQsR0FBQSxLQUFBLEtBQUE7QUFBQSxRQUs5RCxPQUw4RCxHQUFBLEtBQUEsT0FBQTtBQUFBLFFBS3pCLFFBTHlCLEdBQUEsS0FBQSxRQUFBO0FBQUEsUUFNNUQsR0FONEQsR0FNbEUsSUFOa0UsQ0FBQSxHQUFBO0FBT2xFLFFBQUksV0FBVyxHQUFHLE1BQU0sS0FBTixTQUFBLEdBQXVCLEtBQXZCLE1BQUEsR0FBcUMsTUFBTSxDQUE3RCxTQUF1RCxFQUF2RDs7QUFFQSxRQUFJLFlBQVksR0FBRyxrQ0FBQSxnQkFBQSxDQUFtQyxPQUFPLENBQTFDLEdBQUEsRUFBZ0Q7QUFDakUsTUFBQSxPQUFPLEVBQUUsTUFBTSxDQURrRCxhQUN4RCxFQUR3RDtBQUVqRSxNQUFBLFdBQUEsRUFBQTtBQUZpRSxLQUFoRCxDQUFuQjs7QUFLQSxRQUFJLEVBQUUsR0FBRyxLQUFLLENBQUwsTUFBQSxDQUFBLE9BQUEsRUFBVCxZQUFTLENBQVQ7QUFFQSxJQUFBLEVBQUUsQ0FBRixPQUFBLENBQVksVUFBRCxFQUFDLEVBQU07QUFDaEIsTUFBQSxFQUFFLENBQUYsWUFBQTtBQUNBLFVBQUksTUFBTSxHQUFHLEVBQUUsQ0FBRixTQUFBLENBQWIsSUFBYSxDQUFiO0FBRUEsTUFBQSxNQUFNLENBQU4sS0FBQSxHQUFlLFFBQVEsQ0FBdkIsTUFBQTtBQUNBLE1BQUEsUUFBUSxDQUFSLElBQUEsQ0FBQSxNQUFBO0FBQ0EsTUFBQSxTQUFTLENBQVQsR0FBQSxDQUFBLEdBQUEsRUFBQSxNQUFBO0FBQ0Esa0RBQXlCLE1BQXpCLEVBQUEsTUFBQTtBQVBGLEtBQUE7QUE5SkosR0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxRQUFBLEdBeUtVLFNBQUEsUUFBQSxDQUFBLE1BQUEsRUFBQSxJQUFBLEVBQUEsTUFBQSxFQUFrRjtBQUFBLFFBQ2xGLFFBRGtGLEdBQUEsS0FBQSxRQUFBO0FBR3hGLDhCQUFVLE1BQU0sQ0FBUCxJQUFULEVBQXVCLElBQUksQ0FBM0IsSUFBQTtBQUNBLDhCQUFVLE1BQU0sQ0FBUCxLQUFULEVBQXdCLElBQUksQ0FBNUIsS0FBQTtBQUNBLElBQUEsTUFBTSxDQUFOLFFBQUEsR0FBQSxJQUFBO0FBRUEsUUFBQSxjQUFBLEVBQUEsV0FBQTs7QUFFQSxRQUFJLE1BQU0sS0FBVixTQUFBLEVBQTBCO0FBQ3hCLHdCQUFVLE1BQVYsRUFBbUIsS0FBbkIsTUFBQTtBQURGLEtBQUEsTUFFTztBQUNMLE1BQUEsY0FBYyxHQUFHLE1BQU0sQ0FBTixRQUFBLEdBQWpCLFdBQUE7QUFDQSxNQUFBLFdBQVcsR0FBRyxNQUFNLENBRmYsU0FFUyxFQUFkLENBRkssQ0FJTDtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxVQUFJLGNBQWMsS0FBbEIsV0FBQSxFQUFvQztBQUNsQywwQkFBVSxNQUFWLEVBQUEsV0FBQTtBQUNEO0FBQ0Y7O0FBRUQsSUFBQSxNQUFNLENBQU4sS0FBQSxHQUFlLFFBQVEsQ0FBdkIsTUFBQTtBQUNBLElBQUEsUUFBUSxDQUFSLElBQUEsQ0FBQSxNQUFBOztBQUVBLFFBQUE7QUFBQTtBQUFBLE1BQWlCO0FBQ2YsWUFBSSxJQUFJLEdBQUcsY0FBYyxJQUFJLGNBQWMsS0FBaEMsV0FBQSxHQUFBLGFBQUEsR0FBWCxNQUFBO0FBQ0EsMkJBQVEsY0FBUixFQUF5QixDQUFBLElBQUEsRUFBTyxJQUFJLENBQXBDLEdBQXlCLENBQXpCO0FBQ0Q7QUF2TUwsR0FBQTs7QUFBQSxFQUFBLE9BQUEsQ0FBQSxVQUFBLEdBME1VLFNBQUEsVUFBQSxDQUFBLE1BQUEsRUFBaUM7QUFDdkMsUUFBQTtBQUFBO0FBQUEsTUFBaUI7QUFDZiwyQkFBUSxjQUFSLEVBQXlCLENBQUEsUUFBQSxFQUFXLE1BQU0sQ0FBMUMsR0FBeUIsQ0FBekI7QUFDRDs7QUFFRCw4QkFBQSxNQUFBO0FBQ0EsdUJBQUEsTUFBQTtBQUNBLFNBQUEsU0FBQSxDQUFBLFFBQUEsRUFBc0IsTUFBTSxDQUE1QixHQUFBO0FBak5KLEdBQUE7O0FBQUEsU0FBQSxlQUFBO0FBQUEsQ0FBQSxDQUFBLFdBQUEsQ0FBQTs7OztJQXFOQSxlO0FBR0UsV0FBQSxlQUFBLENBQUEsR0FBQSxFQUFBLGdCQUFBLEVBQTZGO0FBQXpFLFNBQUEsR0FBQSxHQUFBLEdBQUE7QUFBK0IsU0FBQSxnQkFBQSxHQUFBLGdCQUFBO0FBRjNDLFNBQUEsT0FBQSxHQUFBLENBQUE7QUFFeUY7Ozs7b0JBRWpHLFNBQUEsSUFBQSxDQUFBLEtBQUEsRUFBa0I7QUFDaEIsU0FBQSxPQUFBLEdBQUEsS0FBQTs7O1VBR0YsYSxHQUFBLFNBQUEsYUFBQSxHQUFhO0FBQ1gsV0FBTyxLQUFBLEdBQUEsQ0FBUyxLQUFoQixPQUFnQixFQUFULENBQVA7OztVQUdGLGUsR0FBQSxTQUFBLGVBQUEsR0FBZTtBQUNiLFFBQUksS0FBSixnQkFBQSxFQUEyQjtBQUN6QixXQUFBLGdCQUFBLENBQUEsZUFBQTtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgREVCVUcgfSBmcm9tICdAZ2xpbW1lci9lbnYnO1xuaW1wb3J0IHtcbiAgQm91bmRzLFxuICBEeW5hbWljU2NvcGUsXG4gIEVsZW1lbnRCdWlsZGVyLFxuICBFbnZpcm9ubWVudCxcbiAgRXhjZXB0aW9uSGFuZGxlcixcbiAgR2xpbW1lclRyZWVDaGFuZ2VzLFxuICBMaXZlQmxvY2ssXG4gIE9wdGlvbixcbiAgUnVudGltZUNvbnRleHQsXG4gIFNjb3BlLFxuICBVcGRhdGFibGVCbG9jayxcbiAgVXBkYXRpbmdWTSxcbiAgVXBkYXRpbmdPcGNvZGUsXG59IGZyb20gJ0BnbGltbWVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9DQUxfREVCVUcgfSBmcm9tICdAZ2xpbW1lci9sb2NhbC1kZWJ1Zy1mbGFncyc7XG5pbXBvcnQge1xuICBPcGFxdWVJdGVyYXRpb25JdGVtLFxuICBPcGFxdWVJdGVyYXRvcixcbiAgUmVmZXJlbmNlLFxuICB1cGRhdGVSZWYsXG4gIHZhbHVlRm9yUmVmLFxufSBmcm9tICdAZ2xpbW1lci9yZWZlcmVuY2UnO1xuaW1wb3J0IHsgYXNzb2NpYXRlRGVzdHJveWFibGVDaGlsZCwgZGVzdHJveSwgZGVzdHJveUNoaWxkcmVuIH0gZnJvbSAnQGdsaW1tZXIvZGVzdHJveWFibGUnO1xuaW1wb3J0IHsgZXhwZWN0LCBTdGFjaywgbG9nU3RlcCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgcmVzZXRUcmFja2luZywgcnVuSW5UcmFja2luZ1RyYW5zYWN0aW9uIH0gZnJvbSAnQGdsaW1tZXIvdmFsaWRhdG9yJztcbmltcG9ydCB7IFNpbXBsZUNvbW1lbnQgfSBmcm9tICdAc2ltcGxlLWRvbS9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgY2xlYXIsIG1vdmUgYXMgbW92ZUJvdW5kcyB9IGZyb20gJy4uL2JvdW5kcyc7XG5pbXBvcnQgeyBJbnRlcm5hbFZNLCBWbUluaXRDYWxsYmFjayB9IGZyb20gJy4vYXBwZW5kJztcbmltcG9ydCB7IExpdmVCbG9ja0xpc3QsIE5ld0VsZW1lbnRCdWlsZGVyIH0gZnJvbSAnLi9lbGVtZW50LWJ1aWxkZXInO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBVcGRhdGluZ1ZNSW1wbCBpbXBsZW1lbnRzIFVwZGF0aW5nVk0ge1xuICBwdWJsaWMgZW52OiBFbnZpcm9ubWVudDtcbiAgcHVibGljIGRvbTogR2xpbW1lclRyZWVDaGFuZ2VzO1xuICBwdWJsaWMgYWx3YXlzUmV2YWxpZGF0ZTogYm9vbGVhbjtcblxuICBwcml2YXRlIGZyYW1lU3RhY2s6IFN0YWNrPFVwZGF0aW5nVk1GcmFtZT4gPSBuZXcgU3RhY2s8VXBkYXRpbmdWTUZyYW1lPigpO1xuXG4gIGNvbnN0cnVjdG9yKGVudjogRW52aXJvbm1lbnQsIHsgYWx3YXlzUmV2YWxpZGF0ZSA9IGZhbHNlIH0pIHtcbiAgICB0aGlzLmVudiA9IGVudjtcbiAgICB0aGlzLmRvbSA9IGVudi5nZXRET00oKTtcbiAgICB0aGlzLmFsd2F5c1JldmFsaWRhdGUgPSBhbHdheXNSZXZhbGlkYXRlO1xuICB9XG5cbiAgZXhlY3V0ZShvcGNvZGVzOiBVcGRhdGluZ09wY29kZVtdLCBoYW5kbGVyOiBFeGNlcHRpb25IYW5kbGVyKSB7XG4gICAgaWYgKERFQlVHKSB7XG4gICAgICBsZXQgaGFzRXJyb3JlZCA9IHRydWU7XG4gICAgICB0cnkge1xuICAgICAgICBydW5JblRyYWNraW5nVHJhbnNhY3Rpb24hKCgpID0+IHRoaXMuX2V4ZWN1dGUob3Bjb2RlcywgaGFuZGxlciksICctIFdoaWxlIHJlbmRlcmluZzonKTtcblxuICAgICAgICAvLyB1c2luZyBhIGJvb2xlYW4gaGVyZSB0byBhdm9pZCBicmVha2luZyBlcmdvbm9taWNzIG9mIFwicGF1c2Ugb24gdW5jYXVnaHQgZXhjZXB0aW9uc1wiXG4gICAgICAgIC8vIHdoaWNoIHdvdWxkIGhhcHBlbiB3aXRoIGEgYGNhdGNoYCArIGB0aHJvd2BcbiAgICAgICAgaGFzRXJyb3JlZCA9IGZhbHNlO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKGhhc0Vycm9yZWQpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcblxcbkVycm9yIG9jY3VycmVkOlxcblxcbiR7cmVzZXRUcmFja2luZygpfVxcblxcbmApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2V4ZWN1dGUob3Bjb2RlcywgaGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZXhlY3V0ZShvcGNvZGVzOiBVcGRhdGluZ09wY29kZVtdLCBoYW5kbGVyOiBFeGNlcHRpb25IYW5kbGVyKSB7XG4gICAgbGV0IHsgZnJhbWVTdGFjayB9ID0gdGhpcztcblxuICAgIHRoaXMudHJ5KG9wY29kZXMsIGhhbmRsZXIpO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChmcmFtZVN0YWNrLmlzRW1wdHkoKSkgYnJlYWs7XG5cbiAgICAgIGxldCBvcGNvZGUgPSB0aGlzLmZyYW1lLm5leHRTdGF0ZW1lbnQoKTtcblxuICAgICAgaWYgKG9wY29kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZyYW1lU3RhY2sucG9wKCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBvcGNvZGUuZXZhbHVhdGUodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgZnJhbWUoKSB7XG4gICAgcmV0dXJuIGV4cGVjdCh0aGlzLmZyYW1lU3RhY2suY3VycmVudCwgJ2J1ZzogZXhwZWN0ZWQgYSBmcmFtZScpO1xuICB9XG5cbiAgZ290byhpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5mcmFtZS5nb3RvKGluZGV4KTtcbiAgfVxuXG4gIHRyeShvcHM6IFVwZGF0aW5nT3Bjb2RlW10sIGhhbmRsZXI6IE9wdGlvbjxFeGNlcHRpb25IYW5kbGVyPikge1xuICAgIHRoaXMuZnJhbWVTdGFjay5wdXNoKG5ldyBVcGRhdGluZ1ZNRnJhbWUob3BzLCBoYW5kbGVyKSk7XG4gIH1cblxuICB0aHJvdygpIHtcbiAgICB0aGlzLmZyYW1lLmhhbmRsZUV4Y2VwdGlvbigpO1xuICAgIHRoaXMuZnJhbWVTdGFjay5wb3AoKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZNU3RhdGUge1xuICByZWFkb25seSBwYzogbnVtYmVyO1xuICByZWFkb25seSBzY29wZTogU2NvcGU7XG4gIHJlYWRvbmx5IGR5bmFtaWNTY29wZTogRHluYW1pY1Njb3BlO1xuICByZWFkb25seSBzdGFjazogdW5rbm93bltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc3VtYWJsZVZNU3RhdGUge1xuICByZXN1bWUocnVudGltZTogUnVudGltZUNvbnRleHQsIGJ1aWxkZXI6IEVsZW1lbnRCdWlsZGVyKTogSW50ZXJuYWxWTTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlc3VtYWJsZVZNU3RhdGVJbXBsIGltcGxlbWVudHMgUmVzdW1hYmxlVk1TdGF0ZSB7XG4gIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHN0YXRlOiBWTVN0YXRlLCBwcml2YXRlIHJlc3VtZUNhbGxiYWNrOiBWbUluaXRDYWxsYmFjaykge31cblxuICByZXN1bWUocnVudGltZTogUnVudGltZUNvbnRleHQsIGJ1aWxkZXI6IEVsZW1lbnRCdWlsZGVyKTogSW50ZXJuYWxWTSB7XG4gICAgcmV0dXJuIHRoaXMucmVzdW1lQ2FsbGJhY2socnVudGltZSwgdGhpcy5zdGF0ZSwgYnVpbGRlcik7XG4gIH1cbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJsb2NrT3Bjb2RlIGltcGxlbWVudHMgVXBkYXRpbmdPcGNvZGUsIEJvdW5kcyB7XG4gIHB1YmxpYyBjaGlsZHJlbjogVXBkYXRpbmdPcGNvZGVbXTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYm91bmRzOiBMaXZlQmxvY2s7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHN0YXRlOiBSZXN1bWFibGVWTVN0YXRlLFxuICAgIHByb3RlY3RlZCBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICBib3VuZHM6IExpdmVCbG9jayxcbiAgICBjaGlsZHJlbjogVXBkYXRpbmdPcGNvZGVbXVxuICApIHtcbiAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gICAgdGhpcy5ib3VuZHMgPSBib3VuZHM7XG4gIH1cblxuICBwYXJlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLmJvdW5kcy5wYXJlbnRFbGVtZW50KCk7XG4gIH1cblxuICBmaXJzdE5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm91bmRzLmZpcnN0Tm9kZSgpO1xuICB9XG5cbiAgbGFzdE5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm91bmRzLmxhc3ROb2RlKCk7XG4gIH1cblxuICBldmFsdWF0ZSh2bTogVXBkYXRpbmdWTUltcGwpIHtcbiAgICB2bS50cnkodGhpcy5jaGlsZHJlbiwgbnVsbCk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRyeU9wY29kZSBleHRlbmRzIEJsb2NrT3Bjb2RlIGltcGxlbWVudHMgRXhjZXB0aW9uSGFuZGxlciB7XG4gIHB1YmxpYyB0eXBlID0gJ3RyeSc7XG5cbiAgcHJvdGVjdGVkIGJvdW5kcyE6IFVwZGF0YWJsZUJsb2NrOyAvLyBIaWRlcyBwcm9wZXJ0eSBvbiBiYXNlIGNsYXNzXG5cbiAgZXZhbHVhdGUodm06IFVwZGF0aW5nVk1JbXBsKSB7XG4gICAgdm0udHJ5KHRoaXMuY2hpbGRyZW4sIHRoaXMpO1xuICB9XG5cbiAgaGFuZGxlRXhjZXB0aW9uKCkge1xuICAgIGxldCB7IHN0YXRlLCBib3VuZHMsIHJ1bnRpbWUgfSA9IHRoaXM7XG5cbiAgICBkZXN0cm95Q2hpbGRyZW4odGhpcyk7XG5cbiAgICBsZXQgZWxlbWVudFN0YWNrID0gTmV3RWxlbWVudEJ1aWxkZXIucmVzdW1lKHJ1bnRpbWUuZW52LCBib3VuZHMpO1xuICAgIGxldCB2bSA9IHN0YXRlLnJlc3VtZShydW50aW1lLCBlbGVtZW50U3RhY2spO1xuXG4gICAgbGV0IHVwZGF0aW5nOiBVcGRhdGluZ09wY29kZVtdID0gW107XG4gICAgbGV0IGNoaWxkcmVuID0gKHRoaXMuY2hpbGRyZW4gPSBbXSk7XG5cbiAgICBsZXQgcmVzdWx0ID0gdm0uZXhlY3V0ZSgodm0pID0+IHtcbiAgICAgIHZtLnB1c2hVcGRhdGluZyh1cGRhdGluZyk7XG4gICAgICB2bS51cGRhdGVXaXRoKHRoaXMpO1xuICAgICAgdm0ucHVzaFVwZGF0aW5nKGNoaWxkcmVuKTtcbiAgICB9KTtcblxuICAgIGFzc29jaWF0ZURlc3Ryb3lhYmxlQ2hpbGQodGhpcywgcmVzdWx0LmRyb3ApO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMaXN0SXRlbU9wY29kZSBleHRlbmRzIFRyeU9wY29kZSB7XG4gIHB1YmxpYyByZXRhaW5lZCA9IGZhbHNlO1xuICBwdWJsaWMgaW5kZXggPSAtMTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzdGF0ZTogUmVzdW1hYmxlVk1TdGF0ZSxcbiAgICBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICBib3VuZHM6IFVwZGF0YWJsZUJsb2NrLFxuICAgIHB1YmxpYyBrZXk6IHVua25vd24sXG4gICAgcHVibGljIG1lbW86IFJlZmVyZW5jZSxcbiAgICBwdWJsaWMgdmFsdWU6IFJlZmVyZW5jZVxuICApIHtcbiAgICBzdXBlcihzdGF0ZSwgcnVudGltZSwgYm91bmRzLCBbXSk7XG4gIH1cblxuICB1cGRhdGVSZWZlcmVuY2VzKGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0pIHtcbiAgICB0aGlzLnJldGFpbmVkID0gdHJ1ZTtcbiAgICB1cGRhdGVSZWYodGhpcy52YWx1ZSwgaXRlbS52YWx1ZSk7XG4gICAgdXBkYXRlUmVmKHRoaXMubWVtbywgaXRlbS5tZW1vKTtcbiAgfVxuXG4gIHNob3VsZFJlbW92ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMucmV0YWluZWQ7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLnJldGFpbmVkID0gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIExpc3RCbG9ja09wY29kZSBleHRlbmRzIEJsb2NrT3Bjb2RlIHtcbiAgcHVibGljIHR5cGUgPSAnbGlzdC1ibG9jayc7XG4gIHB1YmxpYyBjaGlsZHJlbiE6IExpc3RJdGVtT3Bjb2RlW107XG5cbiAgcHJpdmF0ZSBvcGNvZGVNYXAgPSBuZXcgTWFwPHVua25vd24sIExpc3RJdGVtT3Bjb2RlPigpO1xuICBwcml2YXRlIG1hcmtlcjogU2ltcGxlQ29tbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxhc3RJdGVyYXRvcjogT3BhcXVlSXRlcmF0b3I7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGJvdW5kcyE6IExpdmVCbG9ja0xpc3Q7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc3RhdGU6IFJlc3VtYWJsZVZNU3RhdGUsXG4gICAgcnVudGltZTogUnVudGltZUNvbnRleHQsXG4gICAgYm91bmRzOiBMaXZlQmxvY2tMaXN0LFxuICAgIGNoaWxkcmVuOiBMaXN0SXRlbU9wY29kZVtdLFxuICAgIHByaXZhdGUgaXRlcmFibGVSZWY6IFJlZmVyZW5jZTxPcGFxdWVJdGVyYXRvcj5cbiAgKSB7XG4gICAgc3VwZXIoc3RhdGUsIHJ1bnRpbWUsIGJvdW5kcywgY2hpbGRyZW4pO1xuICAgIHRoaXMubGFzdEl0ZXJhdG9yID0gdmFsdWVGb3JSZWYoaXRlcmFibGVSZWYpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZUNoaWxkKG9wY29kZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBvcGNvZGUuaW5kZXggPSB0aGlzLmNoaWxkcmVuLmxlbmd0aCAtIDE7XG4gICAgdGhpcy5vcGNvZGVNYXAuc2V0KG9wY29kZS5rZXksIG9wY29kZSk7XG4gIH1cblxuICBldmFsdWF0ZSh2bTogVXBkYXRpbmdWTUltcGwpIHtcbiAgICBsZXQgaXRlcmF0b3IgPSB2YWx1ZUZvclJlZih0aGlzLml0ZXJhYmxlUmVmKTtcblxuICAgIGlmICh0aGlzLmxhc3RJdGVyYXRvciAhPT0gaXRlcmF0b3IpIHtcbiAgICAgIGxldCB7IGJvdW5kcyB9ID0gdGhpcztcbiAgICAgIGxldCB7IGRvbSB9ID0gdm07XG5cbiAgICAgIGxldCBtYXJrZXIgPSAodGhpcy5tYXJrZXIgPSBkb20uY3JlYXRlQ29tbWVudCgnJykpO1xuICAgICAgZG9tLmluc2VydEFmdGVyKFxuICAgICAgICBib3VuZHMucGFyZW50RWxlbWVudCgpLFxuICAgICAgICBtYXJrZXIsXG4gICAgICAgIGV4cGVjdChib3VuZHMubGFzdE5vZGUoKSwgXCJjYW4ndCBpbnNlcnQgYWZ0ZXIgYW4gZW1wdHkgYm91bmRzXCIpXG4gICAgICApO1xuXG4gICAgICB0aGlzLnN5bmMoaXRlcmF0b3IpO1xuXG4gICAgICB0aGlzLnBhcmVudEVsZW1lbnQoKS5yZW1vdmVDaGlsZChtYXJrZXIpO1xuICAgICAgdGhpcy5tYXJrZXIgPSBudWxsO1xuICAgICAgdGhpcy5sYXN0SXRlcmF0b3IgPSBpdGVyYXRvcjtcbiAgICB9XG5cbiAgICAvLyBSdW4gbm93LXVwZGF0ZWQgdXBkYXRpbmcgb3Bjb2Rlc1xuICAgIHN1cGVyLmV2YWx1YXRlKHZtKTtcbiAgfVxuXG4gIHByaXZhdGUgc3luYyhpdGVyYXRvcjogT3BhcXVlSXRlcmF0b3IpIHtcbiAgICBsZXQgeyBvcGNvZGVNYXA6IGl0ZW1NYXAsIGNoaWxkcmVuIH0gPSB0aGlzO1xuXG4gICAgbGV0IGN1cnJlbnRPcGNvZGVJbmRleCA9IDA7XG4gICAgbGV0IHNlZW5JbmRleCA9IDA7XG5cbiAgICB0aGlzLmNoaWxkcmVuID0gdGhpcy5ib3VuZHMuYm91bmRMaXN0ID0gW107XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgbGV0IGl0ZW0gPSBpdGVyYXRvci5uZXh0KCk7XG5cbiAgICAgIGlmIChpdGVtID09PSBudWxsKSBicmVhaztcblxuICAgICAgbGV0IG9wY29kZSA9IGNoaWxkcmVuW2N1cnJlbnRPcGNvZGVJbmRleF07XG4gICAgICBsZXQgeyBrZXkgfSA9IGl0ZW07XG5cbiAgICAgIC8vIEl0ZW1zIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gZm91bmQgYW5kIG1vdmVkIHdpbGwgYWxyZWFkeSBiZSByZXRhaW5lZCxcbiAgICAgIC8vIHdlIGNhbiBjb250aW51ZSB1bnRpbCB3ZSBmaW5kIHRoZSBuZXh0IHVucmV0YWluZWQgaXRlbVxuICAgICAgd2hpbGUgKG9wY29kZSAhPT0gdW5kZWZpbmVkICYmIG9wY29kZS5yZXRhaW5lZCA9PT0gdHJ1ZSkge1xuICAgICAgICBvcGNvZGUgPSBjaGlsZHJlblsrK2N1cnJlbnRPcGNvZGVJbmRleF07XG4gICAgICB9XG5cbiAgICAgIGlmIChvcGNvZGUgIT09IHVuZGVmaW5lZCAmJiBvcGNvZGUua2V5ID09PSBrZXkpIHtcbiAgICAgICAgdGhpcy5yZXRhaW5JdGVtKG9wY29kZSwgaXRlbSk7XG4gICAgICAgIGN1cnJlbnRPcGNvZGVJbmRleCsrO1xuICAgICAgfSBlbHNlIGlmIChpdGVtTWFwLmhhcyhrZXkpKSB7XG4gICAgICAgIGxldCBpdGVtT3Bjb2RlID0gaXRlbU1hcC5nZXQoa2V5KSE7XG5cbiAgICAgICAgLy8gVGhlIGl0ZW0gb3Bjb2RlIHdhcyBzZWVuIGFscmVhZHksIHNvIHdlIHNob3VsZCBtb3ZlIGl0LlxuICAgICAgICBpZiAoaXRlbU9wY29kZS5pbmRleCA8IHNlZW5JbmRleCkge1xuICAgICAgICAgIHRoaXMubW92ZUl0ZW0oaXRlbU9wY29kZSwgaXRlbSwgb3Bjb2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBVcGRhdGUgdGhlIHNlZW4gaW5kZXgsIHdlIGFyZSBnb2luZyB0byBiZSBtb3ZpbmcgdGhpcyBpdGVtIGFyb3VuZFxuICAgICAgICAgIC8vIHNvIGFueSBvdGhlciBpdGVtcyB0aGF0IGNvbWUgYmVmb3JlIGl0IHdpbGwgbGlrZWx5IG5lZWQgdG8gbW92ZSBhc1xuICAgICAgICAgIC8vIHdlbGwuXG4gICAgICAgICAgc2VlbkluZGV4ID0gaXRlbU9wY29kZS5pbmRleDtcblxuICAgICAgICAgIGxldCBzZWVuVW5yZXRhaW5lZCA9IGZhbHNlO1xuXG4gICAgICAgICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGFsbCBvZiB0aGUgb3Bjb2RlcyBiZXR3ZWVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZFxuICAgICAgICAgIC8vIHRoZSBwb3NpdGlvbiBvZiB0aGUgaXRlbSdzIG9wY29kZSwgYW5kIGRldGVybWluZSBpZiB0aGV5IGFyZSBhbGxcbiAgICAgICAgICAvLyByZXRhaW5lZC5cbiAgICAgICAgICBmb3IgKGxldCBpID0gY3VycmVudE9wY29kZUluZGV4ICsgMTsgaSA8IHNlZW5JbmRleDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5baV0ucmV0YWluZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIHNlZW5VbnJldGFpbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgd2UgaGF2ZSBzZWVuIG9ubHkgcmV0YWluZWQgb3Bjb2RlcyBiZXR3ZWVuIHRoaXMgYW5kIHRoZSBtYXRjaGluZ1xuICAgICAgICAgIC8vIG9wY29kZSwgaXQgbWVhbnMgdGhhdCBhbGwgdGhlIG9wY29kZXMgaW4gYmV0d2VlbiBoYXZlIGJlZW4gbW92ZWRcbiAgICAgICAgICAvLyBhbHJlYWR5LCBhbmQgd2UgY2FuIHNhZmVseSByZXRhaW4gdGhpcyBpdGVtJ3Mgb3Bjb2RlLlxuICAgICAgICAgIGlmIChzZWVuVW5yZXRhaW5lZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMucmV0YWluSXRlbShpdGVtT3Bjb2RlLCBpdGVtKTtcbiAgICAgICAgICAgIGN1cnJlbnRPcGNvZGVJbmRleCA9IHNlZW5JbmRleCArIDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubW92ZUl0ZW0oaXRlbU9wY29kZSwgaXRlbSwgb3Bjb2RlKTtcbiAgICAgICAgICAgIGN1cnJlbnRPcGNvZGVJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbnNlcnRJdGVtKGl0ZW0sIG9wY29kZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IG9wY29kZSA9IGNoaWxkcmVuW2ldO1xuXG4gICAgICBpZiAob3Bjb2RlLnJldGFpbmVkID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmRlbGV0ZUl0ZW0ob3Bjb2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wY29kZS5yZXNldCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmV0YWluSXRlbShvcGNvZGU6IExpc3RJdGVtT3Bjb2RlLCBpdGVtOiBPcGFxdWVJdGVyYXRpb25JdGVtKSB7XG4gICAgaWYgKExPQ0FMX0RFQlVHKSB7XG4gICAgICBsb2dTdGVwISgnbGlzdC11cGRhdGVzJywgWydyZXRhaW4nLCBpdGVtLmtleV0pO1xuICAgIH1cblxuICAgIGxldCB7IGNoaWxkcmVuIH0gPSB0aGlzO1xuXG4gICAgdXBkYXRlUmVmKG9wY29kZS5tZW1vLCBpdGVtLm1lbW8pO1xuICAgIHVwZGF0ZVJlZihvcGNvZGUudmFsdWUsIGl0ZW0udmFsdWUpO1xuICAgIG9wY29kZS5yZXRhaW5lZCA9IHRydWU7XG5cbiAgICBvcGNvZGUuaW5kZXggPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgY2hpbGRyZW4ucHVzaChvcGNvZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRJdGVtKGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0sIGJlZm9yZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxvZ1N0ZXAhKCdsaXN0LXVwZGF0ZXMnLCBbJ2luc2VydCcsIGl0ZW0ua2V5XSk7XG4gICAgfVxuXG4gICAgbGV0IHsgb3Bjb2RlTWFwLCBib3VuZHMsIHN0YXRlLCBydW50aW1lLCBjaGlsZHJlbiB9ID0gdGhpcztcbiAgICBsZXQgeyBrZXkgfSA9IGl0ZW07XG4gICAgbGV0IG5leHRTaWJsaW5nID0gYmVmb3JlID09PSB1bmRlZmluZWQgPyB0aGlzLm1hcmtlciA6IGJlZm9yZS5maXJzdE5vZGUoKTtcblxuICAgIGxldCBlbGVtZW50U3RhY2sgPSBOZXdFbGVtZW50QnVpbGRlci5mb3JJbml0aWFsUmVuZGVyKHJ1bnRpbWUuZW52LCB7XG4gICAgICBlbGVtZW50OiBib3VuZHMucGFyZW50RWxlbWVudCgpLFxuICAgICAgbmV4dFNpYmxpbmcsXG4gICAgfSk7XG5cbiAgICBsZXQgdm0gPSBzdGF0ZS5yZXN1bWUocnVudGltZSwgZWxlbWVudFN0YWNrKTtcblxuICAgIHZtLmV4ZWN1dGUoKHZtKSA9PiB7XG4gICAgICB2bS5wdXNoVXBkYXRpbmcoKTtcbiAgICAgIGxldCBvcGNvZGUgPSB2bS5lbnRlckl0ZW0oaXRlbSk7XG5cbiAgICAgIG9wY29kZS5pbmRleCA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgICAgIGNoaWxkcmVuLnB1c2gob3Bjb2RlKTtcbiAgICAgIG9wY29kZU1hcC5zZXQoa2V5LCBvcGNvZGUpO1xuICAgICAgYXNzb2NpYXRlRGVzdHJveWFibGVDaGlsZCh0aGlzLCBvcGNvZGUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBtb3ZlSXRlbShvcGNvZGU6IExpc3RJdGVtT3Bjb2RlLCBpdGVtOiBPcGFxdWVJdGVyYXRpb25JdGVtLCBiZWZvcmU6IExpc3RJdGVtT3Bjb2RlKSB7XG4gICAgbGV0IHsgY2hpbGRyZW4gfSA9IHRoaXM7XG5cbiAgICB1cGRhdGVSZWYob3Bjb2RlLm1lbW8sIGl0ZW0ubWVtbyk7XG4gICAgdXBkYXRlUmVmKG9wY29kZS52YWx1ZSwgaXRlbS52YWx1ZSk7XG4gICAgb3Bjb2RlLnJldGFpbmVkID0gdHJ1ZTtcblxuICAgIGxldCBjdXJyZW50U2libGluZywgbmV4dFNpYmxpbmc7XG5cbiAgICBpZiAoYmVmb3JlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG1vdmVCb3VuZHMob3Bjb2RlLCB0aGlzLm1hcmtlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnRTaWJsaW5nID0gb3Bjb2RlLmxhc3ROb2RlKCkubmV4dFNpYmxpbmc7XG4gICAgICBuZXh0U2libGluZyA9IGJlZm9yZS5maXJzdE5vZGUoKTtcblxuICAgICAgLy8gSXRlbXMgYXJlIG1vdmVkIHRocm91Z2hvdXQgdGhlIGFsZ29yaXRobSwgc28gdGhlcmUgYXJlIGNhc2VzIHdoZXJlIHRoZVxuICAgICAgLy8gdGhlIGl0ZW1zIGFscmVhZHkgaGFwcGVuIHRvIGJlIHNpYmxpbmdzIChlLmcuIGFuIGl0ZW0gaW4gYmV0d2VlbiB3YXNcbiAgICAgIC8vIG1vdmVkIGJlZm9yZSB0aGlzIG1vdmUgaGFwcGVuZWQpLiBDaGVjayB0byBzZWUgaWYgdGhleSBhcmUgc2libGluZ3NcbiAgICAgIC8vIGZpcnN0IGJlZm9yZSBkb2luZyB0aGUgbW92ZS5cbiAgICAgIGlmIChjdXJyZW50U2libGluZyAhPT0gbmV4dFNpYmxpbmcpIHtcbiAgICAgICAgbW92ZUJvdW5kcyhvcGNvZGUsIG5leHRTaWJsaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBvcGNvZGUuaW5kZXggPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgY2hpbGRyZW4ucHVzaChvcGNvZGUpO1xuXG4gICAgaWYgKExPQ0FMX0RFQlVHKSB7XG4gICAgICBsZXQgdHlwZSA9IGN1cnJlbnRTaWJsaW5nICYmIGN1cnJlbnRTaWJsaW5nID09PSBuZXh0U2libGluZyA/ICdtb3ZlLXJldGFpbicgOiAnbW92ZSc7XG4gICAgICBsb2dTdGVwISgnbGlzdC11cGRhdGVzJywgW3R5cGUsIGl0ZW0ua2V5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVJdGVtKG9wY29kZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxvZ1N0ZXAhKCdsaXN0LXVwZGF0ZXMnLCBbJ2RlbGV0ZScsIG9wY29kZS5rZXldKTtcbiAgICB9XG5cbiAgICBkZXN0cm95KG9wY29kZSk7XG4gICAgY2xlYXIob3Bjb2RlKTtcbiAgICB0aGlzLm9wY29kZU1hcC5kZWxldGUob3Bjb2RlLmtleSk7XG4gIH1cbn1cblxuY2xhc3MgVXBkYXRpbmdWTUZyYW1lIHtcbiAgcHJpdmF0ZSBjdXJyZW50ID0gMDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG9wczogVXBkYXRpbmdPcGNvZGVbXSwgcHJpdmF0ZSBleGNlcHRpb25IYW5kbGVyOiBPcHRpb248RXhjZXB0aW9uSGFuZGxlcj4pIHt9XG5cbiAgZ290byhpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5jdXJyZW50ID0gaW5kZXg7XG4gIH1cblxuICBuZXh0U3RhdGVtZW50KCk6IFVwZGF0aW5nT3Bjb2RlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vcHNbdGhpcy5jdXJyZW50KytdO1xuICB9XG5cbiAgaGFuZGxlRXhjZXB0aW9uKCkge1xuICAgIGlmICh0aGlzLmV4Y2VwdGlvbkhhbmRsZXIpIHtcbiAgICAgIHRoaXMuZXhjZXB0aW9uSGFuZGxlci5oYW5kbGVFeGNlcHRpb24oKTtcbiAgICB9XG4gIH1cbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=