UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

480 lines (379 loc) 43.7 kB
"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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3VwZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBaUJBOztBQU9BOztBQUNBOztBQUNBOztBQUVBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFFYyxjO0FBT1osV0FBQSxjQUFBLENBQUEsR0FBQSxFQUFBLElBQUEsRUFBMEQ7QUFBQSxRQUFBLHFCQUFBLEdBQUEsSUFBQSxDQUExQixnQkFBMEI7QUFBQSxRQUExQixnQkFBMEIsR0FBQSxxQkFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFQLEtBQU8sR0FBQSxxQkFBQTtBQUZsRCxTQUFBLFVBQUEsR0FBcUMsSUFBckMsV0FBcUMsRUFBckM7QUFHTixTQUFBLEdBQUEsR0FBQSxHQUFBO0FBQ0EsU0FBQSxHQUFBLEdBQVcsR0FBRyxDQUFkLE1BQVcsRUFBWDtBQUNBLFNBQUEsZ0JBQUEsR0FBQSxnQkFBQTtBQUNEOzs7O1NBRUQsTyxHQUFBLFNBQUEsT0FBQSxDQUFBLE9BQUEsRUFBQSxPQUFBLEVBQTREO0FBQUEsUUFBQSxLQUFBLEdBQUEsSUFBQTs7QUFDMUQsUUFBQSxVQUFBLEVBQVc7QUFDVCxVQUFJLFVBQVUsR0FBZCxJQUFBOztBQUNBLFVBQUk7QUFDRixpREFBMEIsWUFBQTtBQUFBLGlCQUFNLEtBQUEsQ0FBQSxRQUFBLENBQUEsT0FBQSxFQUFQLE9BQU8sQ0FBTjtBQUFELFNBQXpCLEVBREUsb0JBQ0YsRUFERSxDQUdGO0FBQ0E7O0FBQ0EsUUFBQSxVQUFVLEdBQVYsS0FBQTtBQUxGLE9BQUEsU0FNVTtBQUNSLFlBQUEsVUFBQSxFQUFnQjtBQUNkO0FBQ0EsVUFBQSxPQUFPLENBQVAsS0FBQSxDQUFBLDRCQUFBLCtCQUFBLEdBQUEsTUFBQTtBQUNEO0FBQ0Y7QUFiSCxLQUFBLE1BY087QUFDTCxXQUFBLFFBQUEsQ0FBQSxPQUFBLEVBQUEsT0FBQTtBQUNEOzs7U0FHSyxR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QUFBLGdCQUFBLEVBQTZGO0FBQXpFLFNBQUEsR0FBQSxHQUFBLEdBQUE7QUFBK0IsU0FBQSxnQkFBQSxHQUFBLGdCQUFBO0FBRjNDLFNBQUEsT0FBQSxHQUFBLENBQUE7QUFFeUY7Ozs7b0JBRWpHLFNBQUEsSUFBQSxDQUFBLEtBQUEsRUFBa0I7QUFDaEIsU0FBQSxPQUFBLEdBQUEsS0FBQTs7O1VBR0YsYSxHQUFBLFNBQUEsYUFBQSxHQUFhO0FBQ1gsV0FBTyxLQUFBLEdBQUEsQ0FBUyxLQUFoQixPQUFnQixFQUFULENBQVA7OztVQUdGLGUsR0FBQSxTQUFBLGVBQUEsR0FBZTtBQUNiLFFBQUksS0FBSixnQkFBQSxFQUEyQjtBQUN6QixXQUFBLGdCQUFBLENBQUEsZUFBQTtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgREVCVUcgfSBmcm9tICdAZ2xpbW1lci9lbnYnO1xuaW1wb3J0IHtcbiAgQm91bmRzLFxuICBEeW5hbWljU2NvcGUsXG4gIEVsZW1lbnRCdWlsZGVyLFxuICBFbnZpcm9ubWVudCxcbiAgRXhjZXB0aW9uSGFuZGxlcixcbiAgR2xpbW1lclRyZWVDaGFuZ2VzLFxuICBMaXZlQmxvY2ssXG4gIE9wdGlvbixcbiAgUnVudGltZUNvbnRleHQsXG4gIFNjb3BlLFxuICBVcGRhdGFibGVCbG9jayxcbiAgVXBkYXRpbmdWTSxcbiAgVXBkYXRpbmdPcGNvZGUsXG59IGZyb20gJ0BnbGltbWVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9DQUxfREVCVUcgfSBmcm9tICdAZ2xpbW1lci9sb2NhbC1kZWJ1Zy1mbGFncyc7XG5pbXBvcnQge1xuICBPcGFxdWVJdGVyYXRpb25JdGVtLFxuICBPcGFxdWVJdGVyYXRvcixcbiAgUmVmZXJlbmNlLFxuICB1cGRhdGVSZWYsXG4gIHZhbHVlRm9yUmVmLFxufSBmcm9tICdAZ2xpbW1lci9yZWZlcmVuY2UnO1xuaW1wb3J0IHsgYXNzb2NpYXRlRGVzdHJveWFibGVDaGlsZCwgZGVzdHJveSwgZGVzdHJveUNoaWxkcmVuIH0gZnJvbSAnQGdsaW1tZXIvZGVzdHJveWFibGUnO1xuaW1wb3J0IHsgZXhwZWN0LCBTdGFjaywgbG9nU3RlcCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgcmVzZXRUcmFja2luZywgcnVuSW5UcmFja2luZ1RyYW5zYWN0aW9uIH0gZnJvbSAnQGdsaW1tZXIvdmFsaWRhdG9yJztcbmltcG9ydCB7IFNpbXBsZUNvbW1lbnQgfSBmcm9tICdAc2ltcGxlLWRvbS9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgY2xlYXIsIG1vdmUgYXMgbW92ZUJvdW5kcyB9IGZyb20gJy4uL2JvdW5kcyc7XG5pbXBvcnQgeyBJbnRlcm5hbFZNLCBWbUluaXRDYWxsYmFjayB9IGZyb20gJy4vYXBwZW5kJztcbmltcG9ydCB7IExpdmVCbG9ja0xpc3QsIE5ld0VsZW1lbnRCdWlsZGVyIH0gZnJvbSAnLi9lbGVtZW50LWJ1aWxkZXInO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBVcGRhdGluZ1ZNSW1wbCBpbXBsZW1lbnRzIFVwZGF0aW5nVk0ge1xuICBwdWJsaWMgZW52OiBFbnZpcm9ubWVudDtcbiAgcHVibGljIGRvbTogR2xpbW1lclRyZWVDaGFuZ2VzO1xuICBwdWJsaWMgYWx3YXlzUmV2YWxpZGF0ZTogYm9vbGVhbjtcblxuICBwcml2YXRlIGZyYW1lU3RhY2s6IFN0YWNrPFVwZGF0aW5nVk1GcmFtZT4gPSBuZXcgU3RhY2s8VXBkYXRpbmdWTUZyYW1lPigpO1xuXG4gIGNvbnN0cnVjdG9yKGVudjogRW52aXJvbm1lbnQsIHsgYWx3YXlzUmV2YWxpZGF0ZSA9IGZhbHNlIH0pIHtcbiAgICB0aGlzLmVudiA9IGVudjtcbiAgICB0aGlzLmRvbSA9IGVudi5nZXRET00oKTtcbiAgICB0aGlzLmFsd2F5c1JldmFsaWRhdGUgPSBhbHdheXNSZXZhbGlkYXRlO1xuICB9XG5cbiAgZXhlY3V0ZShvcGNvZGVzOiBVcGRhdGluZ09wY29kZVtdLCBoYW5kbGVyOiBFeGNlcHRpb25IYW5kbGVyKSB7XG4gICAgaWYgKERFQlVHKSB7XG4gICAgICBsZXQgaGFzRXJyb3JlZCA9IHRydWU7XG4gICAgICB0cnkge1xuICAgICAgICBydW5JblRyYWNraW5nVHJhbnNhY3Rpb24hKCgpID0+IHRoaXMuX2V4ZWN1dGUob3Bjb2RlcywgaGFuZGxlciksICctIFdoaWxlIHJlbmRlcmluZzonKTtcblxuICAgICAgICAvLyB1c2luZyBhIGJvb2xlYW4gaGVyZSB0byBhdm9pZCBicmVha2luZyBlcmdvbm9taWNzIG9mIFwicGF1c2Ugb24gdW5jYXVnaHQgZXhjZXB0aW9uc1wiXG4gICAgICAgIC8vIHdoaWNoIHdvdWxkIGhhcHBlbiB3aXRoIGEgYGNhdGNoYCArIGB0aHJvd2BcbiAgICAgICAgaGFzRXJyb3JlZCA9IGZhbHNlO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKGhhc0Vycm9yZWQpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFxcblxcbkVycm9yIG9jY3VycmVkOlxcblxcbiR7cmVzZXRUcmFja2luZygpfVxcblxcbmApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2V4ZWN1dGUob3Bjb2RlcywgaGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZXhlY3V0ZShvcGNvZGVzOiBVcGRhdGluZ09wY29kZVtdLCBoYW5kbGVyOiBFeGNlcHRpb25IYW5kbGVyKSB7XG4gICAgbGV0IHsgZnJhbWVTdGFjayB9ID0gdGhpcztcblxuICAgIHRoaXMudHJ5KG9wY29kZXMsIGhhbmRsZXIpO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChmcmFtZVN0YWNrLmlzRW1wdHkoKSkgYnJlYWs7XG5cbiAgICAgIGxldCBvcGNvZGUgPSB0aGlzLmZyYW1lLm5leHRTdGF0ZW1lbnQoKTtcblxuICAgICAgaWYgKG9wY29kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZyYW1lU3RhY2sucG9wKCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBvcGNvZGUuZXZhbHVhdGUodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgZnJhbWUoKSB7XG4gICAgcmV0dXJuIGV4cGVjdCh0aGlzLmZyYW1lU3RhY2suY3VycmVudCwgJ2J1ZzogZXhwZWN0ZWQgYSBmcmFtZScpO1xuICB9XG5cbiAgZ290byhpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5mcmFtZS5nb3RvKGluZGV4KTtcbiAgfVxuXG4gIHRyeShvcHM6IFVwZGF0aW5nT3Bjb2RlW10sIGhhbmRsZXI6IE9wdGlvbjxFeGNlcHRpb25IYW5kbGVyPikge1xuICAgIHRoaXMuZnJhbWVTdGFjay5wdXNoKG5ldyBVcGRhdGluZ1ZNRnJhbWUob3BzLCBoYW5kbGVyKSk7XG4gIH1cblxuICB0aHJvdygpIHtcbiAgICB0aGlzLmZyYW1lLmhhbmRsZUV4Y2VwdGlvbigpO1xuICAgIHRoaXMuZnJhbWVTdGFjay5wb3AoKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZNU3RhdGUge1xuICByZWFkb25seSBwYzogbnVtYmVyO1xuICByZWFkb25seSBzY29wZTogU2NvcGU7XG4gIHJlYWRvbmx5IGR5bmFtaWNTY29wZTogRHluYW1pY1Njb3BlO1xuICByZWFkb25seSBzdGFjazogdW5rbm93bltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc3VtYWJsZVZNU3RhdGUge1xuICByZXN1bWUocnVudGltZTogUnVudGltZUNvbnRleHQsIGJ1aWxkZXI6IEVsZW1lbnRCdWlsZGVyKTogSW50ZXJuYWxWTTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlc3VtYWJsZVZNU3RhdGVJbXBsIGltcGxlbWVudHMgUmVzdW1hYmxlVk1TdGF0ZSB7XG4gIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHN0YXRlOiBWTVN0YXRlLCBwcml2YXRlIHJlc3VtZUNhbGxiYWNrOiBWbUluaXRDYWxsYmFjaykge31cblxuICByZXN1bWUocnVudGltZTogUnVudGltZUNvbnRleHQsIGJ1aWxkZXI6IEVsZW1lbnRCdWlsZGVyKTogSW50ZXJuYWxWTSB7XG4gICAgcmV0dXJuIHRoaXMucmVzdW1lQ2FsbGJhY2socnVudGltZSwgdGhpcy5zdGF0ZSwgYnVpbGRlcik7XG4gIH1cbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJsb2NrT3Bjb2RlIGltcGxlbWVudHMgVXBkYXRpbmdPcGNvZGUsIEJvdW5kcyB7XG4gIHB1YmxpYyBjaGlsZHJlbjogVXBkYXRpbmdPcGNvZGVbXTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYm91bmRzOiBMaXZlQmxvY2s7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHN0YXRlOiBSZXN1bWFibGVWTVN0YXRlLFxuICAgIHByb3RlY3RlZCBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICBib3VuZHM6IExpdmVCbG9jayxcbiAgICBjaGlsZHJlbjogVXBkYXRpbmdPcGNvZGVbXVxuICApIHtcbiAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gICAgdGhpcy5ib3VuZHMgPSBib3VuZHM7XG4gIH1cblxuICBwYXJlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLmJvdW5kcy5wYXJlbnRFbGVtZW50KCk7XG4gIH1cblxuICBmaXJzdE5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm91bmRzLmZpcnN0Tm9kZSgpO1xuICB9XG5cbiAgbGFzdE5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm91bmRzLmxhc3ROb2RlKCk7XG4gIH1cblxuICBldmFsdWF0ZSh2bTogVXBkYXRpbmdWTUltcGwpIHtcbiAgICB2bS50cnkodGhpcy5jaGlsZHJlbiwgbnVsbCk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRyeU9wY29kZSBleHRlbmRzIEJsb2NrT3Bjb2RlIGltcGxlbWVudHMgRXhjZXB0aW9uSGFuZGxlciB7XG4gIHB1YmxpYyB0eXBlID0gJ3RyeSc7XG5cbiAgcHJvdGVjdGVkIGJvdW5kcyE6IFVwZGF0YWJsZUJsb2NrOyAvLyBIaWRlcyBwcm9wZXJ0eSBvbiBiYXNlIGNsYXNzXG5cbiAgZXZhbHVhdGUodm06IFVwZGF0aW5nVk1JbXBsKSB7XG4gICAgdm0udHJ5KHRoaXMuY2hpbGRyZW4sIHRoaXMpO1xuICB9XG5cbiAgaGFuZGxlRXhjZXB0aW9uKCkge1xuICAgIGxldCB7IHN0YXRlLCBib3VuZHMsIHJ1bnRpbWUgfSA9IHRoaXM7XG5cbiAgICBkZXN0cm95Q2hpbGRyZW4odGhpcyk7XG5cbiAgICBsZXQgZWxlbWVudFN0YWNrID0gTmV3RWxlbWVudEJ1aWxkZXIucmVzdW1lKHJ1bnRpbWUuZW52LCBib3VuZHMpO1xuICAgIGxldCB2bSA9IHN0YXRlLnJlc3VtZShydW50aW1lLCBlbGVtZW50U3RhY2spO1xuXG4gICAgbGV0IHVwZGF0aW5nOiBVcGRhdGluZ09wY29kZVtdID0gW107XG4gICAgbGV0IGNoaWxkcmVuID0gKHRoaXMuY2hpbGRyZW4gPSBbXSk7XG5cbiAgICBsZXQgcmVzdWx0ID0gdm0uZXhlY3V0ZSgodm0pID0+IHtcbiAgICAgIHZtLnB1c2hVcGRhdGluZyh1cGRhdGluZyk7XG4gICAgICB2bS51cGRhdGVXaXRoKHRoaXMpO1xuICAgICAgdm0ucHVzaFVwZGF0aW5nKGNoaWxkcmVuKTtcbiAgICB9KTtcblxuICAgIGFzc29jaWF0ZURlc3Ryb3lhYmxlQ2hpbGQodGhpcywgcmVzdWx0LmRyb3ApO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMaXN0SXRlbU9wY29kZSBleHRlbmRzIFRyeU9wY29kZSB7XG4gIHB1YmxpYyByZXRhaW5lZCA9IGZhbHNlO1xuICBwdWJsaWMgaW5kZXggPSAtMTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzdGF0ZTogUmVzdW1hYmxlVk1TdGF0ZSxcbiAgICBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICBib3VuZHM6IFVwZGF0YWJsZUJsb2NrLFxuICAgIHB1YmxpYyBrZXk6IHVua25vd24sXG4gICAgcHVibGljIG1lbW86IFJlZmVyZW5jZSxcbiAgICBwdWJsaWMgdmFsdWU6IFJlZmVyZW5jZVxuICApIHtcbiAgICBzdXBlcihzdGF0ZSwgcnVudGltZSwgYm91bmRzLCBbXSk7XG4gIH1cblxuICB1cGRhdGVSZWZlcmVuY2VzKGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0pIHtcbiAgICB0aGlzLnJldGFpbmVkID0gdHJ1ZTtcbiAgICB1cGRhdGVSZWYodGhpcy52YWx1ZSwgaXRlbS52YWx1ZSk7XG4gICAgdXBkYXRlUmVmKHRoaXMubWVtbywgaXRlbS5tZW1vKTtcbiAgfVxuXG4gIHNob3VsZFJlbW92ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMucmV0YWluZWQ7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLnJldGFpbmVkID0gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIExpc3RCbG9ja09wY29kZSBleHRlbmRzIEJsb2NrT3Bjb2RlIHtcbiAgcHVibGljIHR5cGUgPSAnbGlzdC1ibG9jayc7XG4gIHB1YmxpYyBjaGlsZHJlbiE6IExpc3RJdGVtT3Bjb2RlW107XG5cbiAgcHJpdmF0ZSBvcGNvZGVNYXAgPSBuZXcgTWFwPHVua25vd24sIExpc3RJdGVtT3Bjb2RlPigpO1xuICBwcml2YXRlIG1hcmtlcjogU2ltcGxlQ29tbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxhc3RJdGVyYXRvcjogT3BhcXVlSXRlcmF0b3I7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGJvdW5kcyE6IExpdmVCbG9ja0xpc3Q7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc3RhdGU6IFJlc3VtYWJsZVZNU3RhdGUsXG4gICAgcnVudGltZTogUnVudGltZUNvbnRleHQsXG4gICAgYm91bmRzOiBMaXZlQmxvY2tMaXN0LFxuICAgIGNoaWxkcmVuOiBMaXN0SXRlbU9wY29kZVtdLFxuICAgIHByaXZhdGUgaXRlcmFibGVSZWY6IFJlZmVyZW5jZTxPcGFxdWVJdGVyYXRvcj5cbiAgKSB7XG4gICAgc3VwZXIoc3RhdGUsIHJ1bnRpbWUsIGJvdW5kcywgY2hpbGRyZW4pO1xuICAgIHRoaXMubGFzdEl0ZXJhdG9yID0gdmFsdWVGb3JSZWYoaXRlcmFibGVSZWYpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZUNoaWxkKG9wY29kZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBvcGNvZGUuaW5kZXggPSB0aGlzLmNoaWxkcmVuLmxlbmd0aCAtIDE7XG4gICAgdGhpcy5vcGNvZGVNYXAuc2V0KG9wY29kZS5rZXksIG9wY29kZSk7XG4gIH1cblxuICBldmFsdWF0ZSh2bTogVXBkYXRpbmdWTUltcGwpIHtcbiAgICBsZXQgaXRlcmF0b3IgPSB2YWx1ZUZvclJlZih0aGlzLml0ZXJhYmxlUmVmKTtcblxuICAgIGlmICh0aGlzLmxhc3RJdGVyYXRvciAhPT0gaXRlcmF0b3IpIHtcbiAgICAgIGxldCB7IGJvdW5kcyB9ID0gdGhpcztcbiAgICAgIGxldCB7IGRvbSB9ID0gdm07XG5cbiAgICAgIGxldCBtYXJrZXIgPSAodGhpcy5tYXJrZXIgPSBkb20uY3JlYXRlQ29tbWVudCgnJykpO1xuICAgICAgZG9tLmluc2VydEFmdGVyKFxuICAgICAgICBib3VuZHMucGFyZW50RWxlbWVudCgpLFxuICAgICAgICBtYXJrZXIsXG4gICAgICAgIGV4cGVjdChib3VuZHMubGFzdE5vZGUoKSwgXCJjYW4ndCBpbnNlcnQgYWZ0ZXIgYW4gZW1wdHkgYm91bmRzXCIpXG4gICAgICApO1xuXG4gICAgICB0aGlzLnN5bmMoaXRlcmF0b3IpO1xuXG4gICAgICB0aGlzLnBhcmVudEVsZW1lbnQoKS5yZW1vdmVDaGlsZChtYXJrZXIpO1xuICAgICAgdGhpcy5tYXJrZXIgPSBudWxsO1xuICAgICAgdGhpcy5sYXN0SXRlcmF0b3IgPSBpdGVyYXRvcjtcbiAgICB9XG5cbiAgICAvLyBSdW4gbm93LXVwZGF0ZWQgdXBkYXRpbmcgb3Bjb2Rlc1xuICAgIHN1cGVyLmV2YWx1YXRlKHZtKTtcbiAgfVxuXG4gIHByaXZhdGUgc3luYyhpdGVyYXRvcjogT3BhcXVlSXRlcmF0b3IpIHtcbiAgICBsZXQgeyBvcGNvZGVNYXA6IGl0ZW1NYXAsIGNoaWxkcmVuIH0gPSB0aGlzO1xuXG4gICAgbGV0IGN1cnJlbnRPcGNvZGVJbmRleCA9IDA7XG4gICAgbGV0IHNlZW5JbmRleCA9IDA7XG5cbiAgICB0aGlzLmNoaWxkcmVuID0gdGhpcy5ib3VuZHMuYm91bmRMaXN0ID0gW107XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgbGV0IGl0ZW0gPSBpdGVyYXRvci5uZXh0KCk7XG5cbiAgICAgIGlmIChpdGVtID09PSBudWxsKSBicmVhaztcblxuICAgICAgbGV0IG9wY29kZSA9IGNoaWxkcmVuW2N1cnJlbnRPcGNvZGVJbmRleF07XG4gICAgICBsZXQgeyBrZXkgfSA9IGl0ZW07XG5cbiAgICAgIC8vIEl0ZW1zIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gZm91bmQgYW5kIG1vdmVkIHdpbGwgYWxyZWFkeSBiZSByZXRhaW5lZCxcbiAgICAgIC8vIHdlIGNhbiBjb250aW51ZSB1bnRpbCB3ZSBmaW5kIHRoZSBuZXh0IHVucmV0YWluZWQgaXRlbVxuICAgICAgd2hpbGUgKG9wY29kZSAhPT0gdW5kZWZpbmVkICYmIG9wY29kZS5yZXRhaW5lZCA9PT0gdHJ1ZSkge1xuICAgICAgICBvcGNvZGUgPSBjaGlsZHJlblsrK2N1cnJlbnRPcGNvZGVJbmRleF07XG4gICAgICB9XG5cbiAgICAgIGlmIChvcGNvZGUgIT09IHVuZGVmaW5lZCAmJiBvcGNvZGUua2V5ID09PSBrZXkpIHtcbiAgICAgICAgdGhpcy5yZXRhaW5JdGVtKG9wY29kZSwgaXRlbSk7XG4gICAgICAgIGN1cnJlbnRPcGNvZGVJbmRleCsrO1xuICAgICAgfSBlbHNlIGlmIChpdGVtTWFwLmhhcyhrZXkpKSB7XG4gICAgICAgIGxldCBpdGVtT3Bjb2RlID0gaXRlbU1hcC5nZXQoa2V5KSE7XG5cbiAgICAgICAgLy8gVGhlIGl0ZW0gb3Bjb2RlIHdhcyBzZWVuIGFscmVhZHksIHNvIHdlIHNob3VsZCBtb3ZlIGl0LlxuICAgICAgICBpZiAoaXRlbU9wY29kZS5pbmRleCA8IHNlZW5JbmRleCkge1xuICAgICAgICAgIHRoaXMubW92ZUl0ZW0oaXRlbU9wY29kZSwgaXRlbSwgb3Bjb2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBVcGRhdGUgdGhlIHNlZW4gaW5kZXgsIHdlIGFyZSBnb2luZyB0byBiZSBtb3ZpbmcgdGhpcyBpdGVtIGFyb3VuZFxuICAgICAgICAgIC8vIHNvIGFueSBvdGhlciBpdGVtcyB0aGF0IGNvbWUgYmVmb3JlIGl0IHdpbGwgbGlrZWx5IG5lZWQgdG8gbW92ZSBhc1xuICAgICAgICAgIC8vIHdlbGwuXG4gICAgICAgICAgc2VlbkluZGV4ID0gaXRlbU9wY29kZS5pbmRleDtcblxuICAgICAgICAgIGxldCBzZWVuVW5yZXRhaW5lZCA9IGZhbHNlO1xuXG4gICAgICAgICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGFsbCBvZiB0aGUgb3Bjb2RlcyBiZXR3ZWVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZFxuICAgICAgICAgIC8vIHRoZSBwb3NpdGlvbiBvZiB0aGUgaXRlbSdzIG9wY29kZSwgYW5kIGRldGVybWluZSBpZiB0aGV5IGFyZSBhbGxcbiAgICAgICAgICAvLyByZXRhaW5lZC5cbiAgICAgICAgICBmb3IgKGxldCBpID0gY3VycmVudE9wY29kZUluZGV4ICsgMTsgaSA8IHNlZW5JbmRleDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5baV0ucmV0YWluZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIHNlZW5VbnJldGFpbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgd2UgaGF2ZSBzZWVuIG9ubHkgcmV0YWluZWQgb3Bjb2RlcyBiZXR3ZWVuIHRoaXMgYW5kIHRoZSBtYXRjaGluZ1xuICAgICAgICAgIC8vIG9wY29kZSwgaXQgbWVhbnMgdGhhdCBhbGwgdGhlIG9wY29kZXMgaW4gYmV0d2VlbiBoYXZlIGJlZW4gbW92ZWRcbiAgICAgICAgICAvLyBhbHJlYWR5LCBhbmQgd2UgY2FuIHNhZmVseSByZXRhaW4gdGhpcyBpdGVtJ3Mgb3Bjb2RlLlxuICAgICAgICAgIGlmIChzZWVuVW5yZXRhaW5lZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMucmV0YWluSXRlbShpdGVtT3Bjb2RlLCBpdGVtKTtcbiAgICAgICAgICAgIGN1cnJlbnRPcGNvZGVJbmRleCA9IHNlZW5JbmRleCArIDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubW92ZUl0ZW0oaXRlbU9wY29kZSwgaXRlbSwgb3Bjb2RlKTtcbiAgICAgICAgICAgIGN1cnJlbnRPcGNvZGVJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbnNlcnRJdGVtKGl0ZW0sIG9wY29kZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IG9wY29kZSA9IGNoaWxkcmVuW2ldO1xuXG4gICAgICBpZiAob3Bjb2RlLnJldGFpbmVkID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmRlbGV0ZUl0ZW0ob3Bjb2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wY29kZS5yZXNldCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmV0YWluSXRlbShvcGNvZGU6IExpc3RJdGVtT3Bjb2RlLCBpdGVtOiBPcGFxdWVJdGVyYXRpb25JdGVtKSB7XG4gICAgaWYgKExPQ0FMX0RFQlVHKSB7XG4gICAgICBsb2dTdGVwISgnbGlzdC11cGRhdGVzJywgWydyZXRhaW4nLCBpdGVtLmtleV0pO1xuICAgIH1cblxuICAgIGxldCB7IGNoaWxkcmVuIH0gPSB0aGlzO1xuXG4gICAgdXBkYXRlUmVmKG9wY29kZS5tZW1vLCBpdGVtLm1lbW8pO1xuICAgIHVwZGF0ZVJlZihvcGNvZGUudmFsdWUsIGl0ZW0udmFsdWUpO1xuICAgIG9wY29kZS5yZXRhaW5lZCA9IHRydWU7XG5cbiAgICBvcGNvZGUuaW5kZXggPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgY2hpbGRyZW4ucHVzaChvcGNvZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRJdGVtKGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0sIGJlZm9yZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxvZ1N0ZXAhKCdsaXN0LXVwZGF0ZXMnLCBbJ2luc2VydCcsIGl0ZW0ua2V5XSk7XG4gICAgfVxuXG4gICAgbGV0IHsgb3Bjb2RlTWFwLCBib3VuZHMsIHN0YXRlLCBydW50aW1lLCBjaGlsZHJlbiB9ID0gdGhpcztcbiAgICBsZXQgeyBrZXkgfSA9IGl0ZW07XG4gICAgbGV0IG5leHRTaWJsaW5nID0gYmVmb3JlID09PSB1bmRlZmluZWQgPyB0aGlzLm1hcmtlciA6IGJlZm9yZS5maXJzdE5vZGUoKTtcblxuICAgIGxldCBlbGVtZW50U3RhY2sgPSBOZXdFbGVtZW50QnVpbGRlci5mb3JJbml0aWFsUmVuZGVyKHJ1bnRpbWUuZW52LCB7XG4gICAgICBlbGVtZW50OiBib3VuZHMucGFyZW50RWxlbWVudCgpLFxuICAgICAgbmV4dFNpYmxpbmcsXG4gICAgfSk7XG5cbiAgICBsZXQgdm0gPSBzdGF0ZS5yZXN1bWUocnVudGltZSwgZWxlbWVudFN0YWNrKTtcblxuICAgIHZtLmV4ZWN1dGUoKHZtKSA9PiB7XG4gICAgICB2bS5wdXNoVXBkYXRpbmcoKTtcbiAgICAgIGxldCBvcGNvZGUgPSB2bS5lbnRlckl0ZW0oaXRlbSk7XG5cbiAgICAgIG9wY29kZS5pbmRleCA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgICAgIGNoaWxkcmVuLnB1c2gob3Bjb2RlKTtcbiAgICAgIG9wY29kZU1hcC5zZXQoa2V5LCBvcGNvZGUpO1xuICAgICAgYXNzb2NpYXRlRGVzdHJveWFibGVDaGlsZCh0aGlzLCBvcGNvZGUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBtb3ZlSXRlbShvcGNvZGU6IExpc3RJdGVtT3Bjb2RlLCBpdGVtOiBPcGFxdWVJdGVyYXRpb25JdGVtLCBiZWZvcmU6IExpc3RJdGVtT3Bjb2RlKSB7XG4gICAgbGV0IHsgY2hpbGRyZW4gfSA9IHRoaXM7XG5cbiAgICB1cGRhdGVSZWYob3Bjb2RlLm1lbW8sIGl0ZW0ubWVtbyk7XG4gICAgdXBkYXRlUmVmKG9wY29kZS52YWx1ZSwgaXRlbS52YWx1ZSk7XG4gICAgb3Bjb2RlLnJldGFpbmVkID0gdHJ1ZTtcblxuICAgIGxldCBjdXJyZW50U2libGluZywgbmV4dFNpYmxpbmc7XG5cbiAgICBpZiAoYmVmb3JlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG1vdmVCb3VuZHMob3Bjb2RlLCB0aGlzLm1hcmtlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnRTaWJsaW5nID0gb3Bjb2RlLmxhc3ROb2RlKCkubmV4dFNpYmxpbmc7XG4gICAgICBuZXh0U2libGluZyA9IGJlZm9yZS5maXJzdE5vZGUoKTtcblxuICAgICAgLy8gSXRlbXMgYXJlIG1vdmVkIHRocm91Z2hvdXQgdGhlIGFsZ29yaXRobSwgc28gdGhlcmUgYXJlIGNhc2VzIHdoZXJlIHRoZVxuICAgICAgLy8gdGhlIGl0ZW1zIGFscmVhZHkgaGFwcGVuIHRvIGJlIHNpYmxpbmdzIChlLmcuIGFuIGl0ZW0gaW4gYmV0d2VlbiB3YXNcbiAgICAgIC8vIG1vdmVkIGJlZm9yZSB0aGlzIG1vdmUgaGFwcGVuZWQpLiBDaGVjayB0byBzZWUgaWYgdGhleSBhcmUgc2libGluZ3NcbiAgICAgIC8vIGZpcnN0IGJlZm9yZSBkb2luZyB0aGUgbW92ZS5cbiAgICAgIGlmIChjdXJyZW50U2libGluZyAhPT0gbmV4dFNpYmxpbmcpIHtcbiAgICAgICAgbW92ZUJvdW5kcyhvcGNvZGUsIG5leHRTaWJsaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBvcGNvZGUuaW5kZXggPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgY2hpbGRyZW4ucHVzaChvcGNvZGUpO1xuXG4gICAgaWYgKExPQ0FMX0RFQlVHKSB7XG4gICAgICBsZXQgdHlwZSA9IGN1cnJlbnRTaWJsaW5nICYmIGN1cnJlbnRTaWJsaW5nID09PSBuZXh0U2libGluZyA/ICdtb3ZlLXJldGFpbicgOiAnbW92ZSc7XG4gICAgICBsb2dTdGVwISgnbGlzdC11cGRhdGVzJywgW3R5cGUsIGl0ZW0ua2V5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVJdGVtKG9wY29kZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxvZ1N0ZXAhKCdsaXN0LXVwZGF0ZXMnLCBbJ2RlbGV0ZScsIG9wY29kZS5rZXldKTtcbiAgICB9XG5cbiAgICBkZXN0cm95KG9wY29kZSk7XG4gICAgY2xlYXIob3Bjb2RlKTtcbiAgICB0aGlzLm9wY29kZU1hcC5kZWxldGUob3Bjb2RlLmtleSk7XG4gIH1cbn1cblxuY2xhc3MgVXBkYXRpbmdWTUZyYW1lIHtcbiAgcHJpdmF0ZSBjdXJyZW50ID0gMDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG9wczogVXBkYXRpbmdPcGNvZGVbXSwgcHJpdmF0ZSBleGNlcHRpb25IYW5kbGVyOiBPcHRpb248RXhjZXB0aW9uSGFuZGxlcj4pIHt9XG5cbiAgZ290byhpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5jdXJyZW50ID0gaW5kZXg7XG4gIH1cblxuICBuZXh0U3RhdGVtZW50KCk6IFVwZGF0aW5nT3Bjb2RlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vcHNbdGhpcy5jdXJyZW50KytdO1xuICB9XG5cbiAgaGFuZGxlRXhjZXB0aW9uKCkge1xuICAgIGlmICh0aGlzLmV4Y2VwdGlvbkhhbmRsZXIpIHtcbiAgICAgIHRoaXMuZXhjZXB0aW9uSGFuZGxlci5oYW5kbGVFeGNlcHRpb24oKTtcbiAgICB9XG4gIH1cbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=