UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

549 lines (434 loc) 56 kB
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; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } import { assert } from '@glimmer/util'; import { ConcreteBounds, CursorImpl } from '../bounds'; import { CURSOR_STACK, NewElementBuilder, RemoteLiveBlock } from './element-builder'; export var SERIALIZATION_FIRST_NODE_STRING = '%+b:0%'; export function isSerializationFirstNode(node) { return node.nodeValue === SERIALIZATION_FIRST_NODE_STRING; } export var RehydratingCursor = /*#__PURE__*/function (_CursorImpl) { _inheritsLoose(RehydratingCursor, _CursorImpl); function RehydratingCursor(element, nextSibling, startingBlockDepth) { var _this; _this = _CursorImpl.call(this, element, nextSibling) || this; _this.startingBlockDepth = startingBlockDepth; _this.candidate = null; _this.injectedOmittedNode = false; _this.openBlockDepth = startingBlockDepth - 1; return _this; } return RehydratingCursor; }(CursorImpl); export var RehydrateBuilder = /*#__PURE__*/function (_NewElementBuilder) { _inheritsLoose(RehydrateBuilder, _NewElementBuilder); function RehydrateBuilder(env, parentNode, nextSibling) { var _this2; _this2 = _NewElementBuilder.call(this, env, parentNode, nextSibling) || this; _this2.unmatchedAttributes = null; _this2.blockDepth = 0; if (nextSibling) throw new Error('Rehydration with nextSibling not supported'); var node = _this2.currentCursor.element.firstChild; while (node !== null) { if (isOpenBlock(node)) { break; } node = node.nextSibling; } false && assert(node, 'Must have opening comment for rehydration.'); _this2.candidate = node; var startingBlockOffset = getBlockDepth(node); if (startingBlockOffset !== 0) { // We are rehydrating from a partial tree and not the root component // We need to add an extra block before the first block to rehydrate correctly // The extra block is needed since the renderComponent API creates a synthetic component invocation which generates the extra block var newBlockDepth = startingBlockOffset - 1; var newCandidate = _this2.dom.createComment("%+b:" + newBlockDepth + "%"); node.parentNode.insertBefore(newCandidate, _this2.candidate); var closingNode = node.nextSibling; while (closingNode !== null) { if (isCloseBlock(closingNode) && getBlockDepth(closingNode) === startingBlockOffset) { break; } closingNode = closingNode.nextSibling; } false && assert(closingNode, 'Must have closing comment for starting block comment'); var newClosingBlock = _this2.dom.createComment("%-b:" + newBlockDepth + "%"); node.parentNode.insertBefore(newClosingBlock, closingNode.nextSibling); _this2.candidate = newCandidate; _this2.startingBlockOffset = newBlockDepth; } else { _this2.startingBlockOffset = 0; } return _this2; } var _proto = RehydrateBuilder.prototype; _proto.disableRehydration = function disableRehydration(nextSibling) { var currentCursor = this.currentCursor; // rehydration will be disabled until we either: // * hit popElement (and return to using the parent elements cursor) // * hit closeBlock and the next sibling is a close block comment // matching the expected openBlockDepth currentCursor.candidate = null; currentCursor.nextSibling = nextSibling; }; _proto.enableRehydration = function enableRehydration(candidate) { var currentCursor = this.currentCursor; currentCursor.candidate = candidate; currentCursor.nextSibling = null; }; _proto.pushElement = function pushElement(element, nextSibling) { if (nextSibling === void 0) { nextSibling = null; } var cursor = new RehydratingCursor(element, nextSibling, this.blockDepth || 0); /** * <div> <--------------- currentCursor.element * <!--%+b:1%--> <------- would have been removed during openBlock * <div> <--------------- currentCursor.candidate -> cursor.element * <!--%+b:2%--> <----- currentCursor.candidate.firstChild -> cursor.candidate * Foo * <!--%-b:2%--> * </div> * <!--%-b:1%--> <------ becomes currentCursor.candidate */ if (this.candidate !== null) { cursor.candidate = element.firstChild; this.candidate = element.nextSibling; } this[CURSOR_STACK].push(cursor); } // clears until the end of the current container // either the current open block or higher ; _proto.clearMismatch = function clearMismatch(candidate) { var current = candidate; var currentCursor = this.currentCursor; if (currentCursor !== null) { var openBlockDepth = currentCursor.openBlockDepth; if (openBlockDepth >= currentCursor.startingBlockDepth) { while (current) { if (isCloseBlock(current)) { var closeBlockDepth = getBlockDepthWithOffset(current, this.startingBlockOffset); if (openBlockDepth >= closeBlockDepth) { break; } } current = this.remove(current); } } else { while (current !== null) { current = this.remove(current); } } // current cursor parentNode should be openCandidate if element // or openCandidate.parentNode if comment this.disableRehydration(current); } }; _proto.__openBlock = function __openBlock() { var currentCursor = this.currentCursor; if (currentCursor === null) return; var blockDepth = this.blockDepth; this.blockDepth++; var candidate = currentCursor.candidate; if (candidate === null) return; var tagName = currentCursor.element.tagName; if (isOpenBlock(candidate) && getBlockDepthWithOffset(candidate, this.startingBlockOffset) === blockDepth) { this.candidate = this.remove(candidate); currentCursor.openBlockDepth = blockDepth; } else if (tagName !== 'TITLE' && tagName !== 'SCRIPT' && tagName !== 'STYLE') { this.clearMismatch(candidate); } }; _proto.__closeBlock = function __closeBlock() { var currentCursor = this.currentCursor; if (currentCursor === null) return; // openBlock is the last rehydrated open block var openBlockDepth = currentCursor.openBlockDepth; // this currently is the expected next open block depth this.blockDepth--; var candidate = currentCursor.candidate; var isRehydrating = false; if (candidate !== null) { isRehydrating = true; //assert( // openBlockDepth === this.blockDepth, // 'when rehydrating, openBlockDepth should match this.blockDepth here' //); if (isCloseBlock(candidate) && getBlockDepthWithOffset(candidate, this.startingBlockOffset) === openBlockDepth) { var nextSibling = this.remove(candidate); this.candidate = nextSibling; currentCursor.openBlockDepth--; } else { // close the block and clear mismatch in parent container // we will be either at the end of the element // or at the end of our containing block this.clearMismatch(candidate); isRehydrating = false; } } if (isRehydrating === false) { // check if nextSibling matches our expected close block // if so, we remove the close block comment and // restore rehydration after clearMismatch disabled var _nextSibling = currentCursor.nextSibling; if (_nextSibling !== null && isCloseBlock(_nextSibling) && getBlockDepthWithOffset(_nextSibling, this.startingBlockOffset) === this.blockDepth) { // restore rehydration state var _candidate2 = this.remove(_nextSibling); this.enableRehydration(_candidate2); currentCursor.openBlockDepth--; } } }; _proto.__appendNode = function __appendNode(node) { var candidate = this.candidate; // This code path is only used when inserting precisely one node. It needs more // comparison logic, but we can probably lean on the cases where this code path // is actually used. if (candidate) { return candidate; } else { return _NewElementBuilder.prototype.__appendNode.call(this, node); } }; _proto.__appendHTML = function __appendHTML(html) { var candidateBounds = this.markerBounds(); if (candidateBounds) { var first = candidateBounds.firstNode(); var last = candidateBounds.lastNode(); var newBounds = new ConcreteBounds(this.element, first.nextSibling, last.previousSibling); var possibleEmptyMarker = this.remove(first); this.remove(last); if (possibleEmptyMarker !== null && isEmpty(possibleEmptyMarker)) { this.candidate = this.remove(possibleEmptyMarker); if (this.candidate !== null) { this.clearMismatch(this.candidate); } } return newBounds; } else { return _NewElementBuilder.prototype.__appendHTML.call(this, html); } }; _proto.remove = function remove(node) { var element = node.parentNode; var next = node.nextSibling; element.removeChild(node); return next; }; _proto.markerBounds = function markerBounds() { var _candidate = this.candidate; if (_candidate && isMarker(_candidate)) { var first = _candidate; var last = first.nextSibling; while (last && !isMarker(last)) { last = last.nextSibling; } return new ConcreteBounds(this.element, first, last); } else { return null; } }; _proto.__appendText = function __appendText(string) { var candidate = this.candidate; if (candidate) { if (isTextNode(candidate)) { if (candidate.nodeValue !== string) { candidate.nodeValue = string; } this.candidate = candidate.nextSibling; return candidate; } else if (isSeparator(candidate)) { this.candidate = this.remove(candidate); return this.__appendText(string); } else if (isEmpty(candidate) && string === '') { this.candidate = this.remove(candidate); return this.__appendText(string); } else { this.clearMismatch(candidate); return _NewElementBuilder.prototype.__appendText.call(this, string); } } else { return _NewElementBuilder.prototype.__appendText.call(this, string); } }; _proto.__appendComment = function __appendComment(string) { var _candidate = this.candidate; if (_candidate && isComment(_candidate)) { if (_candidate.nodeValue !== string) { _candidate.nodeValue = string; } this.candidate = _candidate.nextSibling; return _candidate; } else if (_candidate) { this.clearMismatch(_candidate); } return _NewElementBuilder.prototype.__appendComment.call(this, string); }; _proto.__openElement = function __openElement(tag) { var _candidate = this.candidate; if (_candidate && isElement(_candidate) && isSameNodeType(_candidate, tag)) { this.unmatchedAttributes = [].slice.call(_candidate.attributes); return _candidate; } else if (_candidate) { if (isElement(_candidate) && _candidate.tagName === 'TBODY') { this.pushElement(_candidate, null); this.currentCursor.injectedOmittedNode = true; return this.__openElement(tag); } this.clearMismatch(_candidate); } return _NewElementBuilder.prototype.__openElement.call(this, tag); }; _proto.__setAttribute = function __setAttribute(name, value, namespace) { var unmatched = this.unmatchedAttributes; if (unmatched) { var attr = findByName(unmatched, name); if (attr) { if (attr.value !== value) { attr.value = value; } unmatched.splice(unmatched.indexOf(attr), 1); return; } } return _NewElementBuilder.prototype.__setAttribute.call(this, name, value, namespace); }; _proto.__setProperty = function __setProperty(name, value) { var unmatched = this.unmatchedAttributes; if (unmatched) { var attr = findByName(unmatched, name); if (attr) { if (attr.value !== value) { attr.value = value; } unmatched.splice(unmatched.indexOf(attr), 1); return; } } return _NewElementBuilder.prototype.__setProperty.call(this, name, value); }; _proto.__flushElement = function __flushElement(parent, constructing) { var unmatched = this.unmatchedAttributes; if (unmatched) { for (var i = 0; i < unmatched.length; i++) { this.constructing.removeAttribute(unmatched[i].name); } this.unmatchedAttributes = null; } else { _NewElementBuilder.prototype.__flushElement.call(this, parent, constructing); } }; _proto.willCloseElement = function willCloseElement() { var candidate = this.candidate, currentCursor = this.currentCursor; if (candidate !== null) { this.clearMismatch(candidate); } if (currentCursor && currentCursor.injectedOmittedNode) { this.popElement(); } _NewElementBuilder.prototype.willCloseElement.call(this); }; _proto.getMarker = function getMarker(element, guid) { var marker = element.querySelector("script[glmr=\"" + guid + "\"]"); if (marker) { return marker; } return null; }; _proto.__pushRemoteElement = function __pushRemoteElement(element, cursorId, insertBefore) { var marker = this.getMarker(element, cursorId); false && assert(!marker || marker.parentNode === element, "expected remote element marker's parent node to match remote element"); // when insertBefore is not present, we clear the element if (insertBefore === undefined) { while (element.firstChild !== null && element.firstChild !== marker) { this.remove(element.firstChild); } insertBefore = null; } var cursor = new RehydratingCursor(element, null, this.blockDepth); this[CURSOR_STACK].push(cursor); if (marker === null) { this.disableRehydration(insertBefore); } else { this.candidate = this.remove(marker); } var block = new RemoteLiveBlock(element); return this.pushLiveBlock(block, true); }; _proto.didAppendBounds = function didAppendBounds(bounds) { _NewElementBuilder.prototype.didAppendBounds.call(this, bounds); if (this.candidate) { var last = bounds.lastNode(); this.candidate = last && last.nextSibling; } return bounds; }; _createClass(RehydrateBuilder, [{ key: "currentCursor", get: function get() { return this[CURSOR_STACK].current; } }, { key: "candidate", get: function get() { if (this.currentCursor) { return this.currentCursor.candidate; } return null; }, set: function set(node) { var currentCursor = this.currentCursor; currentCursor.candidate = node; } }]); return RehydrateBuilder; }(NewElementBuilder); function isTextNode(node) { return node.nodeType === 3; } function isComment(node) { return node.nodeType === 8; } function isOpenBlock(node) { return node.nodeType === 8 /* COMMENT_NODE */ && node.nodeValue.lastIndexOf('%+b:', 0) === 0; } function isCloseBlock(node) { return node.nodeType === 8 /* COMMENT_NODE */ && node.nodeValue.lastIndexOf('%-b:', 0) === 0; } function getBlockDepth(node) { return parseInt(node.nodeValue.slice(4), 10); } function getBlockDepthWithOffset(node, offset) { return getBlockDepth(node) - offset; } function isElement(node) { return node.nodeType === 1; } function isMarker(node) { return node.nodeType === 8 && node.nodeValue === '%glmr%'; } function isSeparator(node) { return node.nodeType === 8 && node.nodeValue === '%|%'; } function isEmpty(node) { return node.nodeType === 8 && node.nodeValue === '% %'; } function isSameNodeType(candidate, tag) { if (candidate.namespaceURI === "http://www.w3.org/2000/svg" /* SVG */ ) { return candidate.tagName === tag; } return candidate.tagName === tag.toUpperCase(); } function findByName(array, name) { for (var i = 0; i < array.length; i++) { var attr = array[i]; if (attr.name === name) return attr; } return undefined; } export function rehydrationBuilder(env, cursor) { return RehydrateBuilder.forInitialRender(env, cursor); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3JlaHlkcmF0ZS1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLFNBQUEsTUFBQSxRQUFBLGVBQUE7QUFXQSxTQUFBLGNBQUEsRUFBQSxVQUFBLFFBQUEsV0FBQTtBQUNBLFNBQUEsWUFBQSxFQUFBLGlCQUFBLEVBQUEsZUFBQSxRQUFBLG1CQUFBO0FBRUEsT0FBTyxJQUFNLCtCQUErQixHQUFyQyxRQUFBO0FBRVAsT0FBTSxTQUFBLHdCQUFBLENBQUEsSUFBQSxFQUFtRDtBQUN2RCxTQUFPLElBQUksQ0FBSixTQUFBLEtBQVAsK0JBQUE7QUFDRDtBQUVELFdBQU0saUJBQU47QUFBQTs7QUFJRSw2QkFBQSxPQUFBLEVBQUEsV0FBQSxFQUFBLGtCQUFBLEVBRzRDO0FBQUE7O0FBRTFDLG1DQUFBLE9BQUEsRUFBQSxXQUFBO0FBRmdCLFVBQUEsa0JBQUEsR0FBQSxrQkFBQTtBQU5sQixVQUFBLFNBQUEsR0FBQSxJQUFBO0FBRUEsVUFBQSxtQkFBQSxHQUFBLEtBQUE7QUFPRSxVQUFBLGNBQUEsR0FBc0Isa0JBQWtCLEdBQXhDLENBQUE7QUFIMEM7QUFJM0M7O0FBWEg7QUFBQSxFQUFNLFVBQU47QUFjQSxXQUFNLGdCQUFOO0FBQUE7O0FBTUUsNEJBQUEsR0FBQSxFQUFBLFVBQUEsRUFBQSxXQUFBLEVBQXdGO0FBQUE7O0FBQ3RGLDJDQUFBLEdBQUEsRUFBQSxVQUFBLEVBQUEsV0FBQTtBQU5NLFdBQUEsbUJBQUEsR0FBQSxJQUFBO0FBRVIsV0FBQSxVQUFBLEdBQUEsQ0FBQTtBQUtFLFFBQUEsV0FBQSxFQUFpQixNQUFNLElBQUEsS0FBQSxDQUFOLDRDQUFNLENBQU47QUFFakIsUUFBSSxJQUFJLEdBQUcsT0FBQSxhQUFBLENBQUEsT0FBQSxDQUFYLFVBQUE7O0FBRUEsV0FBTyxJQUFJLEtBQVgsSUFBQSxFQUFzQjtBQUNwQixVQUFJLFdB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Q0FBQSxFQUFnQixDQUFDLEdBQUcsS0FBSyxDQUF6QixNQUFBLEVBQWtDLENBQWxDLEVBQUEsRUFBdUM7QUFDckMsUUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFoQixDQUFnQixDQUFoQjtBQUNBLFFBQUksSUFBSSxDQUFKLElBQUEsS0FBSixJQUFBLEVBQXdCLE9BQUEsSUFBQTtBQUN6Qjs7QUFFRCxTQUFBLFNBQUE7QUFDRDs7QUFFRCxPQUFNLFNBQUEsa0JBQUEsQ0FBQSxHQUFBLEVBQUEsTUFBQSxFQUFpRTtBQUNyRSxTQUFPLGdCQUFnQixDQUFoQixnQkFBQSxDQUFBLEdBQUEsRUFBUCxNQUFPLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJvdW5kcywgRWxlbWVudEJ1aWxkZXIsIEVudmlyb25tZW50LCBPcHRpb24sIE1heWJlIH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBhc3NlcnQsIGNhc3RUb0Jyb3dzZXIsIGNhc3RUb1NpbXBsZSwgZXhwZWN0LCBTdGFjayB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHtcbiAgQXR0ck5hbWVzcGFjZSxcbiAgTmFtZXNwYWNlLFxuICBOb2RlVHlwZSxcbiAgU2ltcGxlQXR0cixcbiAgU2ltcGxlQ29tbWVudCxcbiAgU2ltcGxlRWxlbWVudCxcbiAgU2ltcGxlTm9kZSxcbiAgU2ltcGxlVGV4dCxcbn0gZnJvbSAnQHNpbXBsZS1kb20vaW50ZXJmYWNlJztcbmltcG9ydCB7IENvbmNyZXRlQm91bmRzLCBDdXJzb3JJbXBsIH0gZnJvbSAnLi4vYm91bmRzJztcbmltcG9ydCB7IENVUlNPUl9TVEFDSywgTmV3RWxlbWVudEJ1aWxkZXIsIFJlbW90ZUxpdmVCbG9jayB9IGZyb20gJy4vZWxlbWVudC1idWlsZGVyJztcblxuZXhwb3J0IGNvbnN0IFNFUklBTElaQVRJT05fRklSU1RfTk9ERV9TVFJJTkcgPSAnJStiOjAlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2VyaWFsaXphdGlvbkZpcnN0Tm9kZShub2RlOiBTaW1wbGVOb2RlKTogYm9vbGVhbiB7XG4gIHJldHVybiBub2RlLm5vZGVWYWx1ZSA9PT0gU0VSSUFMSVpBVElPTl9GSVJTVF9OT0RFX1NUUklORztcbn1cblxuZXhwb3J0IGNsYXNzIFJlaHlkcmF0aW5nQ3Vyc29yIGV4dGVuZHMgQ3Vyc29ySW1wbCB7XG4gIGNhbmRpZGF0ZTogT3B0aW9uPFNpbXBsZU5vZGU+ID0gbnVsbDtcbiAgb3BlbkJsb2NrRGVwdGg6IG51bWJlcjtcbiAgaW5qZWN0ZWRPbWl0dGVkTm9kZSA9IGZhbHNlO1xuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICAgIG5leHRTaWJsaW5nOiBPcHRpb248U2ltcGxlTm9kZT4sXG4gICAgcHVibGljIHJlYWRvbmx5IHN0YXJ0aW5nQmxvY2tEZXB0aDogbnVtYmVyXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnQsIG5leHRTaWJsaW5nKTtcbiAgICB0aGlzLm9wZW5CbG9ja0RlcHRoID0gc3RhcnRpbmdCbG9ja0RlcHRoIC0gMTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVoeWRyYXRlQnVpbGRlciBleHRlbmRzIE5ld0VsZW1lbnRCdWlsZGVyIGltcGxlbWVudHMgRWxlbWVudEJ1aWxkZXIge1xuICBwcml2YXRlIHVubWF0Y2hlZEF0dHJpYnV0ZXM6IE9wdGlvbjxTaW1wbGVBdHRyW10+ID0gbnVsbDtcbiAgW0NVUlNPUl9TVEFDS10hOiBTdGFjazxSZWh5ZHJhdGluZ0N1cnNvcj47IC8vIEhpZGVzIHByb3BlcnR5IG9uIGJhc2UgY2xhc3NcbiAgYmxvY2tEZXB0aCA9IDA7XG4gIHN0YXJ0aW5nQmxvY2tPZmZzZXQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihlbnY6IEVudmlyb25tZW50LCBwYXJlbnROb2RlOiBTaW1wbGVFbGVtZW50LCBuZXh0U2libGluZzogT3B0aW9uPFNpbXBsZU5vZGU+KSB7XG4gICAgc3VwZXIoZW52LCBwYXJlbnROb2RlLCBuZXh0U2libGluZyk7XG4gICAgaWYgKG5leHRTaWJsaW5nKSB0aHJvdyBuZXcgRXJyb3IoJ1JlaHlkcmF0aW9uIHdpdGggbmV4dFNpYmxpbmcgbm90IHN1cHBvcnRlZCcpO1xuXG4gICAgbGV0IG5vZGUgPSB0aGlzLmN1cnJlbnRDdXJzb3IhLmVsZW1lbnQuZmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgICBpZiAoaXNPcGVuQmxvY2sobm9kZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBub2RlID0gbm9kZS5uZXh0U2libGluZztcbiAgICB9XG5cbiAgICBhc3NlcnQobm9kZSwgJ011c3QgaGF2ZSBvcGVuaW5nIGNvbW1lbnQgZm9yIHJlaHlkcmF0aW9uLicpO1xuICAgIHRoaXMuY2FuZGlkYXRlID0gbm9kZTtcbiAgICBjb25zdCBzdGFydGluZ0Jsb2NrT2Zmc2V0ID0gZ2V0QmxvY2tEZXB0aChub2RlIGFzIFNpbXBsZUNvbW1lbnQpO1xuICAgIGlmIChzdGFydGluZ0Jsb2NrT2Zmc2V0ICE9PSAwKSB7XG4gICAgICAvLyBXZSBhcmUgcmVoeWRyYXRpbmcgZnJvbSBhIHBhcnRpYWwgdHJlZSBhbmQgbm90IHRoZSByb290IGNvbXBvbmVudFxuICAgICAgLy8gV2UgbmVlZCB0byBhZGQgYW4gZXh0cmEgYmxvY2sgYmVmb3JlIHRoZSBmaXJzdCBibG9jayB0byByZWh5ZHJhdGUgY29ycmVjdGx5XG4gICAgICAvLyBUaGUgZXh0cmEgYmxvY2sgaXMgbmVlZGVkIHNpbmNlIHRoZSByZW5kZXJDb21wb25lbnQgQVBJIGNyZWF0ZXMgYSBzeW50aGV0aWMgY29tcG9uZW50IGludm9jYXRpb24gd2hpY2ggZ2VuZXJhdGVzIHRoZSBleHRyYSBibG9ja1xuICAgICAgY29uc3QgbmV3QmxvY2tEZXB0aCA9IHN0YXJ0aW5nQmxvY2tPZmZzZXQgLSAxO1xuICAgICAgY29uc3QgbmV3Q2FuZGlkYXRlID0gdGhpcy5kb20uY3JlYXRlQ29tbWVudChgJStiOiR7bmV3QmxvY2tEZXB0aH0lYCk7XG5cbiAgICAgIG5vZGUhLnBhcmVudE5vZGUhLmluc2VydEJlZm9yZShuZXdDYW5kaWRhdGUsIHRoaXMuY2FuZGlkYXRlKTtcbiAgICAgIGxldCBjbG9zaW5nTm9kZSA9IG5vZGUhLm5leHRTaWJsaW5nO1xuICAgICAgd2hpbGUgKGNsb3NpbmdOb2RlICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChpc0Nsb3NlQmxvY2soY2xvc2luZ05vZGUpICYmIGdldEJsb2NrRGVwdGgoY2xvc2luZ05vZGUpID09PSBzdGFydGluZ0Jsb2NrT2Zmc2V0KSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2luZ05vZGUgPSBjbG9zaW5nTm9kZS5uZXh0U2libGluZztcbiAgICAgIH1cblxuICAgICAgYXNzZXJ0KGNsb3NpbmdOb2RlLCAnTXVzdCBoYXZlIGNsb3NpbmcgY29tbWVudCBmb3Igc3RhcnRpbmcgYmxvY2sgY29tbWVudCcpO1xuICAgICAgY29uc3QgbmV3Q2xvc2luZ0Jsb2NrID0gdGhpcy5kb20uY3JlYXRlQ29tbWVudChgJS1iOiR7bmV3QmxvY2tEZXB0aH0lYCk7XG4gICAgICBub2RlIS5wYXJlbnROb2RlIS5pbnNlcnRCZWZvcmUobmV3Q2xvc2luZ0Jsb2NrLCBjbG9zaW5nTm9kZSEubmV4dFNpYmxpbmcpO1xuICAgICAgdGhpcy5jYW5kaWRhdGUgPSBuZXdDYW5kaWRhdGU7XG4gICAgICB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQgPSBuZXdCbG9ja0RlcHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQgPSAwO1xuICAgIH1cbiAgfVxuXG4gIGdldCBjdXJyZW50Q3Vyc29yKCk6IE9wdGlvbjxSZWh5ZHJhdGluZ0N1cnNvcj4ge1xuICAgIHJldHVybiB0aGlzW0NVUlNPUl9TVEFDS10uY3VycmVudDtcbiAgfVxuXG4gIGdldCBjYW5kaWRhdGUoKTogT3B0aW9uPFNpbXBsZU5vZGU+IHtcbiAgICBpZiAodGhpcy5jdXJyZW50Q3Vyc29yKSB7XG4gICAgICByZXR1cm4gdGhpcy5jdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZSE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzZXQgY2FuZGlkYXRlKG5vZGU6IE9wdGlvbjxTaW1wbGVOb2RlPikge1xuICAgIGxldCBjdXJyZW50Q3Vyc29yID0gdGhpcy5jdXJyZW50Q3Vyc29yITtcblxuICAgIGN1cnJlbnRDdXJzb3IuY2FuZGlkYXRlID0gbm9kZTtcbiAgfVxuXG4gIGRpc2FibGVSZWh5ZHJhdGlvbihuZXh0U2libGluZzogT3B0aW9uPFNpbXBsZU5vZGU+KSB7XG4gICAgbGV0IGN1cnJlbnRDdXJzb3IgPSB0aGlzLmN1cnJlbnRDdXJzb3IhO1xuXG4gICAgLy8gcmVoeWRyYXRpb24gd2lsbCBiZSBkaXNhYmxlZCB1bnRpbCB3ZSBlaXRoZXI6XG4gICAgLy8gKiBoaXQgcG9wRWxlbWVudCAoYW5kIHJldHVybiB0byB1c2luZyB0aGUgcGFyZW50IGVsZW1lbnRzIGN1cnNvcilcbiAgICAvLyAqIGhpdCBjbG9zZUJsb2NrIGFuZCB0aGUgbmV4dCBzaWJsaW5nIGlzIGEgY2xvc2UgYmxvY2sgY29tbWVudFxuICAgIC8vICAgbWF0Y2hpbmcgdGhlIGV4cGVjdGVkIG9wZW5CbG9ja0RlcHRoXG4gICAgY3VycmVudEN1cnNvci5jYW5kaWRhdGUgPSBudWxsO1xuICAgIGN1cnJlbnRDdXJzb3IubmV4dFNpYmxpbmcgPSBuZXh0U2libGluZztcbiAgfVxuXG4gIGVuYWJsZVJlaHlkcmF0aW9uKGNhbmRpZGF0ZTogT3B0aW9uPFNpbXBsZU5vZGU+KSB7XG4gICAgbGV0IGN1cnJlbnRDdXJzb3IgPSB0aGlzLmN1cnJlbnRDdXJzb3IhO1xuXG4gICAgY3VycmVudEN1cnNvci5jYW5kaWRhdGUgPSBjYW5kaWRhdGU7XG4gICAgY3VycmVudEN1cnNvci5uZXh0U2libGluZyA9IG51bGw7XG4gIH1cblxuICBwdXNoRWxlbWVudChcbiAgICAvKiogY2FsbGVkIGZyb20gcGFyZW50IGNvbnN0cnVjdG9yIGJlZm9yZSB3ZSBpbml0aWFsaXplIHRoaXMgKi9cbiAgICB0aGlzOlxuICAgICAgfCBSZWh5ZHJhdGVCdWlsZGVyXG4gICAgICB8IChOZXdFbGVtZW50QnVpbGRlciAmIFBhcnRpYWw8UGljazxSZWh5ZHJhdGVCdWlsZGVyLCAnYmxvY2tEZXB0aCcgfCAnY2FuZGlkYXRlJz4+KSxcbiAgICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICAgIG5leHRTaWJsaW5nOiBNYXliZTxTaW1wbGVOb2RlPiA9IG51bGxcbiAgKSB7XG4gICAgbGV0IGN1cnNvciA9IG5ldyBSZWh5ZHJhdGluZ0N1cnNvcihlbGVtZW50LCBuZXh0U2libGluZywgdGhpcy5ibG9ja0RlcHRoIHx8IDApO1xuXG4gICAgLyoqXG4gICAgICogPGRpdj4gICA8LS0tLS0tLS0tLS0tLS0tICBjdXJyZW50Q3Vyc29yLmVsZW1lbnRcbiAgICAgKiAgIDwhLS0lK2I6MSUtLT4gPC0tLS0tLS0gIHdvdWxkIGhhdmUgYmVlbiByZW1vdmVkIGR1cmluZyBvcGVuQmxvY2tcbiAgICAgKiAgIDxkaXY+IDwtLS0tLS0tLS0tLS0tLS0gIGN1cnJlbnRDdXJzb3IuY2FuZGlkYXRlIC0+IGN1cnNvci5lbGVtZW50XG4gICAgICogICAgIDwhLS0lK2I6MiUtLT4gPC0tLS0tICBjdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZS5maXJzdENoaWxkIC0+IGN1cnNvci5jYW5kaWRhdGVcbiAgICAgKiAgICAgRm9vXG4gICAgICogICAgIDwhLS0lLWI6MiUtLT5cbiAgICAgKiAgIDwvZGl2PlxuICAgICAqICAgPCEtLSUtYjoxJS0tPiAgPC0tLS0tLSAgYmVjb21lcyBjdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZVxuICAgICAqL1xuICAgIGlmICh0aGlzLmNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgY3Vyc29yLmNhbmRpZGF0ZSA9IGVsZW1lbnQuZmlyc3RDaGlsZDtcbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gZWxlbWVudC5uZXh0U2libGluZztcbiAgICB9XG5cbiAgICB0aGlzW0NVUlNPUl9TVEFDS10ucHVzaChjdXJzb3IpO1xuICB9XG5cbiAgLy8gY2xlYXJzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgY29udGFpbmVyXG4gIC8vIGVpdGhlciB0aGUgY3VycmVudCBvcGVuIGJsb2NrIG9yIGhpZ2hlclxuICBwcml2YXRlIGNsZWFyTWlzbWF0Y2goY2FuZGlkYXRlOiBTaW1wbGVOb2RlKSB7XG4gICAgbGV0IGN1cnJlbnQ6IE9wdGlvbjxTaW1wbGVOb2RlPiA9IGNhbmRpZGF0ZTtcbiAgICBsZXQgY3VycmVudEN1cnNvciA9IHRoaXMuY3VycmVudEN1cnNvcjtcbiAgICBpZiAoY3VycmVudEN1cnNvciAhPT0gbnVsbCkge1xuICAgICAgbGV0IG9wZW5CbG9ja0RlcHRoID0gY3VycmVudEN1cnNvci5vcGVuQmxvY2tEZXB0aDtcbiAgICAgIGlmIChvcGVuQmxvY2tEZXB0aCA+PSBjdXJyZW50Q3Vyc29yLnN0YXJ0aW5nQmxvY2tEZXB0aCkge1xuICAgICAgICB3aGlsZSAoY3VycmVudCkge1xuICAgICAgICAgIGlmIChpc0Nsb3NlQmxvY2soY3VycmVudCkpIHtcbiAgICAgICAgICAgIGxldCBjbG9zZUJsb2NrRGVwdGggPSBnZXRCbG9ja0RlcHRoV2l0aE9mZnNldChjdXJyZW50LCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpO1xuICAgICAgICAgICAgaWYgKG9wZW5CbG9ja0RlcHRoID49IGNsb3NlQmxvY2tEZXB0aCkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY3VycmVudCA9IHRoaXMucmVtb3ZlKGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aGlsZSAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgIGN1cnJlbnQgPSB0aGlzLnJlbW92ZShjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gY3VycmVudCBjdXJzb3IgcGFyZW50Tm9kZSBzaG91bGQgYmUgb3BlbkNhbmRpZGF0ZSBpZiBlbGVtZW50XG4gICAgICAvLyBvciBvcGVuQ2FuZGlkYXRlLnBhcmVudE5vZGUgaWYgY29tbWVudFxuICAgICAgdGhpcy5kaXNhYmxlUmVoeWRyYXRpb24oY3VycmVudCk7XG4gICAgfVxuICB9XG5cbiAgX19vcGVuQmxvY2soKTogdm9pZCB7XG4gICAgbGV0IHsgY3VycmVudEN1cnNvciB9ID0gdGhpcztcbiAgICBpZiAoY3VycmVudEN1cnNvciA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgbGV0IGJsb2NrRGVwdGggPSB0aGlzLmJsb2NrRGVwdGg7XG5cbiAgICB0aGlzLmJsb2NrRGVwdGgrKztcblxuICAgIGxldCB7IGNhbmRpZGF0ZSB9ID0gY3VycmVudEN1cnNvcjtcbiAgICBpZiAoY2FuZGlkYXRlID09PSBudWxsKSByZXR1cm47XG5cbiAgICBsZXQgeyB0YWdOYW1lIH0gPSBjdXJyZW50Q3Vyc29yLmVsZW1lbnQ7XG5cbiAgICBpZiAoXG4gICAgICBpc09wZW5CbG9jayhjYW5kaWRhdGUpICYmXG4gICAgICBnZXRCbG9ja0RlcHRoV2l0aE9mZnNldChjYW5kaWRhdGUsIHRoaXMuc3RhcnRpbmdCbG9ja09mZnNldCkgPT09IGJsb2NrRGVwdGhcbiAgICApIHtcbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gdGhpcy5yZW1vdmUoY2FuZGlkYXRlKTtcbiAgICAgIGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGggPSBibG9ja0RlcHRoO1xuICAgIH0gZWxzZSBpZiAodGFnTmFtZSAhPT0gJ1RJVExFJyAmJiB0YWdOYW1lICE9PSAnU0NSSVBUJyAmJiB0YWdOYW1lICE9PSAnU1RZTEUnKSB7XG4gICAgICB0aGlzLmNsZWFyTWlzbWF0Y2goY2FuZGlkYXRlKTtcbiAgICB9XG4gIH1cblxuICBfX2Nsb3NlQmxvY2soKTogdm9pZCB7XG4gICAgbGV0IHsgY3VycmVudEN1cnNvciB9ID0gdGhpcztcbiAgICBpZiAoY3VycmVudEN1cnNvciA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgLy8gb3BlbkJsb2NrIGlzIHRoZSBsYXN0IHJlaHlkcmF0ZWQgb3BlbiBibG9ja1xuICAgIGxldCBvcGVuQmxvY2tEZXB0aCA9IGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGg7XG5cbiAgICAvLyB0aGlzIGN1cnJlbnRseSBpcyB0aGUgZXhwZWN0ZWQgbmV4dCBvcGVuIGJsb2NrIGRlcHRoXG4gICAgdGhpcy5ibG9ja0RlcHRoLS07XG5cbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IGN1cnJlbnRDdXJzb3I7XG5cbiAgICBsZXQgaXNSZWh5ZHJhdGluZyA9IGZhbHNlO1xuXG4gICAgaWYgKGNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgaXNSZWh5ZHJhdGluZyA9IHRydWU7XG4gICAgICAvL2Fzc2VydChcbiAgICAgIC8vICBvcGVuQmxvY2tEZXB0aCA9PT0gdGhpcy5ibG9ja0RlcHRoLFxuICAgICAgLy8gICd3aGVuIHJlaHlkcmF0aW5nLCBvcGVuQmxvY2tEZXB0aCBzaG91bGQgbWF0Y2ggdGhpcy5ibG9ja0RlcHRoIGhlcmUnXG4gICAgICAvLyk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNDbG9zZUJsb2NrKGNhbmRpZGF0ZSkgJiZcbiAgICAgICAgZ2V0QmxvY2tEZXB0aFdpdGhPZmZzZXQoY2FuZGlkYXRlLCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpID09PSBvcGVuQmxvY2tEZXB0aFxuICAgICAgKSB7XG4gICAgICAgIGxldCBuZXh0U2libGluZyA9IHRoaXMucmVtb3ZlKGNhbmRpZGF0ZSk7XG4gICAgICAgIHRoaXMuY2FuZGlkYXRlID0gbmV4dFNpYmxpbmc7XG4gICAgICAgIGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGgtLTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNsb3NlIHRoZSBibG9jayBhbmQgY2xlYXIgbWlzbWF0Y2ggaW4gcGFyZW50IGNvbnRhaW5lclxuICAgICAgICAvLyB3ZSB3aWxsIGJlIGVpdGhlciBhdCB0aGUgZW5kIG9mIHRoZSBlbGVtZW50XG4gICAgICAgIC8vIG9yIGF0IHRoZSBlbmQgb2Ygb3VyIGNvbnRhaW5pbmcgYmxvY2tcbiAgICAgICAgdGhpcy5jbGVhck1pc21hdGNoKGNhbmRpZGF0ZSk7XG4gICAgICAgIGlzUmVoeWRyYXRpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNSZWh5ZHJhdGluZyA9PT0gZmFsc2UpIHtcbiAgICAgIC8vIGNoZWNrIGlmIG5leHRTaWJsaW5nIG1hdGNoZXMgb3VyIGV4cGVjdGVkIGNsb3NlIGJsb2NrXG4gICAgICAvLyBpZiBzbywgd2UgcmVtb3ZlIHRoZSBjbG9zZSBibG9jayBjb21tZW50IGFuZFxuICAgICAgLy8gcmVzdG9yZSByZWh5ZHJhdGlvbiBhZnRlciBjbGVhck1pc21hdGNoIGRpc2FibGVkXG4gICAgICBsZXQgbmV4dFNpYmxpbmcgPSBjdXJyZW50Q3Vyc29yLm5leHRTaWJsaW5nO1xuICAgICAgaWYgKFxuICAgICAgICBuZXh0U2libGluZyAhPT0gbnVsbCAmJlxuICAgICAgICBpc0Nsb3NlQmxvY2sobmV4dFNpYmxpbmcpICYmXG4gICAgICAgIGdldEJsb2NrRGVwdGhXaXRoT2Zmc2V0KG5leHRTaWJsaW5nLCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpID09PSB0aGlzLmJsb2NrRGVwdGhcbiAgICAgICkge1xuICAgICAgICAvLyByZXN0b3JlIHJlaHlkcmF0aW9uIHN0YXRlXG4gICAgICAgIGxldCBjYW5kaWRhdGUgPSB0aGlzLnJlbW92ZShuZXh0U2libGluZyk7XG4gICAgICAgIHRoaXMuZW5hYmxlUmVoeWRyYXRpb24oY2FuZGlkYXRlKTtcblxuICAgICAgICBjdXJyZW50Q3Vyc29yLm9wZW5CbG9ja0RlcHRoLS07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX19hcHBlbmROb2RlKG5vZGU6IFNpbXBsZU5vZGUpOiBTaW1wbGVOb2RlIHtcbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IHRoaXM7XG5cbiAgICAvLyBUaGlzIGNvZGUgcGF0aCBpcyBvbmx5IHVzZWQgd2hlbiBpbnNlcnRpbmcgcHJlY2lzZWx5IG9uZSBub2RlLiBJdCBuZWVkcyBtb3JlXG4gICAgLy8gY29tcGFyaXNvbiBsb2dpYywgYnV0IHdlIGNhbiBwcm9iYWJseSBsZWFuIG9uIHRoZSBjYXNlcyB3aGVyZSB0aGlzIGNvZGUgcGF0aFxuICAgIC8vIGlzIGFjdHVhbGx5IHVzZWQuXG4gICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgcmV0dXJuIGNhbmRpZGF0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN1cGVyLl9fYXBwZW5kTm9kZShub2RlKTtcbiAgICB9XG4gIH1cblxuICBfX2FwcGVuZEhUTUwoaHRtbDogc3RyaW5nKTogQm91bmRzIHtcbiAgICBsZXQgY2FuZGlkYXRlQm91bmRzID0gdGhpcy5tYXJrZXJCb3VuZHMoKTtcblxuICAgIGlmIChjYW5kaWRhdGVCb3VuZHMpIHtcbiAgICAgIGxldCBmaXJzdCA9IGNhbmRpZGF0ZUJvdW5kcy5maXJzdE5vZGUoKSE7XG4gICAgICBsZXQgbGFzdCA9IGNhbmRpZGF0ZUJvdW5kcy5sYXN0Tm9kZSgpITtcblxuICAgICAgbGV0IG5ld0JvdW5kcyA9IG5ldyBDb25jcmV0ZUJvdW5kcyh0aGlzLmVsZW1lbnQsIGZpcnN0Lm5leHRTaWJsaW5nISwgbGFzdC5wcmV2aW91c1NpYmxpbmchKTtcblxuICAgICAgbGV0IHBvc3NpYmxlRW1wdHlNYXJrZXIgPSB0aGlzLnJlbW92ZShmaXJzdCk7XG4gICAgICB0aGlzLnJlbW92ZShsYXN0KTtcblxuICAgICAgaWYgKHBvc3NpYmxlRW1wdHlNYXJrZXIgIT09IG51bGwgJiYgaXNFbXB0eShwb3NzaWJsZUVtcHR5TWFya2VyKSkge1xuICAgICAgICB0aGlzLmNhbmRpZGF0ZSA9IHRoaXMucmVtb3ZlKHBvc3NpYmxlRW1wdHlNYXJrZXIpO1xuXG4gICAgICAgIGlmICh0aGlzLmNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuY2xlYXJNaXNtYXRjaCh0aGlzLmNhbmRpZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ld0JvdW5kcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN1cGVyLl9fYXBwZW5kSFRNTChodG1sKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlKG5vZGU6IFNpbXBsZU5vZGUpOiBPcHRpb248U2ltcGxlTm9kZT4ge1xuICAgIGxldCBlbGVtZW50ID0gZXhwZWN0KG5vZGUucGFyZW50Tm9kZSwgYGNhbm5vdCByZW1vdmUgYSBkZXRhY2hlZCBub2RlYCkgYXMgU2ltcGxlRWxlbWVudDtcbiAgICBsZXQgbmV4dCA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgZWxlbWVudC5yZW1vdmVDaGlsZChub2RlKTtcbiAgICByZXR1cm4gbmV4dDtcbiAgfVxuXG4gIHByaXZhdGUgbWFya2VyQm91bmRzKCk6IE9wdGlvbjxCb3VuZHM+IHtcbiAgICBsZXQgX2NhbmRpZGF0ZSA9IHRoaXMuY2FuZGlkYXRlO1xuXG4gICAgaWYgKF9jYW5kaWRhdGUgJiYgaXNNYXJrZXIoX2NhbmRpZGF0ZSkpIHtcbiAgICAgIGxldCBmaXJzdCA9IF9jYW5kaWRhdGU7XG4gICAgICBsZXQgbGFzdCA9IGV4cGVjdChmaXJzdC5uZXh0U2libGluZywgYEJVRzogc2VyaWFsaXphdGlvbiBtYXJrZXJzIG11c3QgYmUgcGFpcmVkYCk7XG5cbiAgICAgIHdoaWxlIChsYXN0ICYmICFpc01hcmtlcihsYXN0KSkge1xuICAgICAgICBsYXN0ID0gZXhwZWN0KGxhc3QubmV4dFNpYmxpbmcsIGBCVUc6IHNlcmlhbGl6YXRpb24gbWFya2VycyBtdXN0IGJlIHBhaXJlZGApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IENvbmNyZXRlQm91bmRzKHRoaXMuZWxlbWVudCwgZmlyc3QsIGxhc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBfX2FwcGVuZFRleHQoc3RyaW5nOiBzdHJpbmcpOiBTaW1wbGVUZXh0IHtcbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IHRoaXM7XG5cbiAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICBpZiAoaXNUZXh0Tm9kZShjYW5kaWRhdGUpKSB7XG4gICAgICAgIGlmIChjYW5kaWRhdGUubm9kZVZhbHVlICE9PSBzdHJpbmcpIHtcbiAgICAgICAgICBjYW5kaWRhdGUubm9kZVZhbHVlID0gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FuZGlkYXRlID0gY2FuZGlkYXRlLm5leHRTaWJsaW5nO1xuXG4gICAgICAgIHJldHVybiBjYW5kaWRhdGU7XG4gICAgICB9IGVsc2UgaWYgKGlzU2VwYXJhdG9yKGNhbmRpZGF0ZSkpIHtcbiAgICAgICAgdGhpcy5jYW5kaWRhdGUgPSB0aGlzLnJlbW92ZShjYW5kaWRhdGUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9fYXBwZW5kVGV4dChzdHJpbmcpO1xuICAgICAgfSBlbHNlIGlmIChpc0VtcHR5KGNhbmRpZGF0ZSkgJiYgc3RyaW5nID09PSAnJykge1xuICAgICAgICB0aGlzLmNhbmRpZGF0ZSA9IHRoaXMucmVtb3ZlKGNhbmRpZGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX19hcHBlbmRUZXh0KHN0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNsZWFyTWlzbWF0Y2goY2FuZGlkYXRlKTtcblxuICAgICAgICByZXR1cm4gc3VwZXIuX19hcHBlbmRUZXh0KHN0cmluZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdXBlci5fX2FwcGVuZFRleHQoc3RyaW5nKTtcbiAgICB9XG4gIH1cblxuICBfX2FwcGVuZENvbW1lbnQoc3RyaW5nOiBzdHJpbmcpOiBTaW1wbGVDb21tZW50IHtcbiAgICBsZXQgX2NhbmRpZGF0ZSA9IHRoaXMuY2FuZGlkYXRlO1xuICAgIGlmIChfY2FuZGlkYXRlICYmIGlzQ29tbWVudChfY2FuZGlkYXRlKSkge1xuICAgICAgaWYgKF9jYW5kaWRhdGUubm9kZVZhbHVlICE9PSBzdHJpbmcpIHtcbiAgICAgICAgX2NhbmRpZGF0ZS5ub2RlVmFsdWUgPSBzdHJpbmc7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gX2NhbmRpZGF0ZS5uZXh0U2libGluZztcbiAgICAgIHJldHVybiBfY2FuZGlkYXRlO1xuICAgIH0gZWxzZSBpZiAoX2NhbmRpZGF0ZSkge1xuICAgICAgdGhpcy5jbGVhck1pc21hdGNoKF9jYW5kaWRhdGUpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5fX2FwcGVuZENvbW1lbnQoc3RyaW5nKTtcbiAgfVxuXG4gIF9fb3BlbkVsZW1lbnQodGFnOiBzdHJpbmcpOiBTaW1wbGVFbGVtZW50IHtcbiAgICBsZXQgX2NhbmRpZGF0ZSA9IHRoaXMuY2FuZGlkYXRlO1xuXG4gICAgaWYgKF9jYW5kaWRhdGUgJiYgaXNFbGVtZW50KF9jYW5kaWRhdGUpICYmIGlzU2FtZU5vZGVUeXBlKF9jYW5kaWRhdGUsIHRhZykpIHtcbiAgICAgIHRoaXMudW5tYXRjaGVkQXR0cmlidXRlcyA9IFtdLnNsaWNlLmNhbGwoX2NhbmRpZGF0ZS5hdHRyaWJ1dGVzKTtcbiAgICAgIHJldHVybiBfY2FuZGlkYXRlO1xuICAgIH0gZWxzZSBpZiAoX2NhbmRpZGF0ZSkge1xuICAgICAgaWYgKGlzRWxlbWVudChfY2FuZGlkYXRlKSAmJiBfY2FuZGlkYXRlLnRhZ05hbWUgPT09ICdUQk9EWScpIHtcbiAgICAgICAgdGhpcy5wdXNoRWxlbWVudChfY2FuZGlkYXRlLCBudWxsKTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q3Vyc29yIS5pbmplY3RlZE9taXR0ZWROb2RlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19vcGVuRWxlbWVudCh0YWcpO1xuICAgICAgfVxuICAgICAgdGhpcy5jbGVhck1pc21hdGNoKF9jYW5kaWRhdGUpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5fX29wZW5FbGVtZW50KHRhZyk7XG4gIH1cblxuICBfX3NldEF0dHJpYnV0ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIG5hbWVzcGFjZTogT3B0aW9uPEF0dHJOYW1lc3BhY2U+KTogdm9pZCB7XG4gICAgbGV0IHVubWF0Y2hlZCA9IHRoaXMudW5tYXRjaGVkQXR0cmlidXRlcztcblxuICAgIGlmICh1bm1hdGNoZWQpIHtcbiAgICAgIGxldCBhdHRyID0gZmluZEJ5TmFtZSh1bm1hdGNoZWQsIG5hbWUpO1xuICAgICAgaWYgKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIudmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgYXR0ci52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG4g