@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
515 lines (398 loc) • 43.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clientBuilder = clientBuilder;
exports.LiveBlockList = exports.UpdatableBlockImpl = exports.RemoteLiveBlock = exports.SimpleLiveBlock = exports.NewElementBuilder = exports.CURSOR_STACK = exports.Fragment = void 0;
var _util = require("@glimmer/util");
var _bounds2 = require("../bounds");
var _destroyable = require("@glimmer/destroyable");
var _dynamic = require("./attributes/dynamic");
var _a;
class First {
constructor(node) {
this.node = node;
}
firstNode() {
return this.node;
}
}
class Last {
constructor(node) {
this.node = node;
}
lastNode() {
return this.node;
}
}
class Fragment {
constructor(bounds) {
this.bounds = bounds;
}
parentElement() {
return this.bounds.parentElement();
}
firstNode() {
return this.bounds.firstNode();
}
lastNode() {
return this.bounds.lastNode();
}
}
exports.Fragment = Fragment;
const CURSOR_STACK = (0, _util.symbol)('CURSOR_STACK');
exports.CURSOR_STACK = CURSOR_STACK;
class NewElementBuilder {
constructor(env, parentNode, nextSibling) {
this.constructing = null;
this.operations = null;
this[_a] = new _util.Stack();
this.modifierStack = new _util.Stack();
this.blockStack = new _util.Stack();
this.pushElement(parentNode, nextSibling);
this.env = env;
this.dom = env.getAppendOperations();
this.updateOperations = env.getDOM();
}
static forInitialRender(env, cursor) {
return new this(env, cursor.element, cursor.nextSibling).initialize();
}
static resume(env, block) {
let parentNode = block.parentElement();
let nextSibling = block.reset(env);
let stack = new this(env, parentNode, nextSibling).initialize();
stack.pushLiveBlock(block);
return stack;
}
initialize() {
this.pushSimpleBlock();
return this;
}
debugBlocks() {
return this.blockStack.toArray();
}
get element() {
return this[CURSOR_STACK].current.element;
}
get nextSibling() {
return this[CURSOR_STACK].current.nextSibling;
}
get hasBlocks() {
return this.blockStack.size > 0;
}
block() {
return this.blockStack.current;
}
popElement() {
this[CURSOR_STACK].pop();
this[CURSOR_STACK].current;
}
pushSimpleBlock() {
return this.pushLiveBlock(new SimpleLiveBlock(this.element));
}
pushUpdatableBlock() {
return this.pushLiveBlock(new UpdatableBlockImpl(this.element));
}
pushBlockList(list) {
return this.pushLiveBlock(new LiveBlockList(this.element, list));
}
pushLiveBlock(block, isRemote = false) {
let current = this.blockStack.current;
if (current !== null) {
if (!isRemote) {
current.didAppendBounds(block);
}
}
this.__openBlock();
this.blockStack.push(block);
return block;
}
popBlock() {
this.block().finalize(this);
this.__closeBlock();
return this.blockStack.pop();
}
__openBlock() {}
__closeBlock() {} // todo return seems unused
openElement(tag) {
let element = this.__openElement(tag);
this.constructing = element;
return element;
}
__openElement(tag) {
return this.dom.createElement(tag, this.element);
}
flushElement(modifiers) {
let parent = this.element;
let element = this.constructing;
this.__flushElement(parent, element);
this.constructing = null;
this.operations = null;
this.pushModifiers(modifiers);
this.pushElement(element, null);
this.didOpenElement(element);
}
__flushElement(parent, constructing) {
this.dom.insertBefore(parent, constructing, this.nextSibling);
}
closeElement() {
this.willCloseElement();
this.popElement();
return this.popModifiers();
}
pushRemoteElement(element, guid, insertBefore) {
return this.__pushRemoteElement(element, guid, insertBefore);
}
__pushRemoteElement(element, _guid, insertBefore) {
this.pushElement(element, insertBefore);
if (insertBefore === undefined) {
while (element.lastChild) {
element.removeChild(element.lastChild);
}
}
let block = new RemoteLiveBlock(element);
return this.pushLiveBlock(block, true);
}
popRemoteElement() {
this.popBlock();
this.popElement();
}
pushElement(element, nextSibling = null) {
this[CURSOR_STACK].push(new _bounds2.CursorImpl(element, nextSibling));
}
pushModifiers(modifiers) {
this.modifierStack.push(modifiers);
}
popModifiers() {
return this.modifierStack.pop();
}
didAppendBounds(bounds) {
this.block().didAppendBounds(bounds);
return bounds;
}
didAppendNode(node) {
this.block().didAppendNode(node);
return node;
}
didOpenElement(element) {
this.block().openElement(element);
return element;
}
willCloseElement() {
this.block().closeElement();
}
appendText(string) {
return this.didAppendNode(this.__appendText(string));
}
__appendText(text) {
let {
dom,
element,
nextSibling
} = this;
let node = dom.createTextNode(text);
dom.insertBefore(element, node, nextSibling);
return node;
}
__appendNode(node) {
this.dom.insertBefore(this.element, node, this.nextSibling);
return node;
}
__appendFragment(fragment) {
let first = fragment.firstChild;
if (first) {
let ret = new _bounds2.ConcreteBounds(this.element, first, fragment.lastChild);
this.dom.insertBefore(this.element, fragment, this.nextSibling);
return ret;
} else {
return new _bounds2.SingleNodeBounds(this.element, this.__appendComment(''));
}
}
__appendHTML(html) {
return this.dom.insertHTMLBefore(this.element, this.nextSibling, html);
}
appendDynamicHTML(value) {
let bounds = this.trustedContent(value);
this.didAppendBounds(bounds);
}
appendDynamicText(value) {
let node = this.untrustedContent(value);
this.didAppendNode(node);
return node;
}
appendDynamicFragment(value) {
let bounds = this.__appendFragment(value);
this.didAppendBounds(bounds);
}
appendDynamicNode(value) {
let node = this.__appendNode(value);
let bounds = new _bounds2.SingleNodeBounds(this.element, node);
this.didAppendBounds(bounds);
}
trustedContent(value) {
return this.__appendHTML(value);
}
untrustedContent(value) {
return this.__appendText(value);
}
appendComment(string) {
return this.didAppendNode(this.__appendComment(string));
}
__appendComment(string) {
let {
dom,
element,
nextSibling
} = this;
let node = dom.createComment(string);
dom.insertBefore(element, node, nextSibling);
return node;
}
__setAttribute(name, value, namespace) {
this.dom.setAttribute(this.constructing, name, value, namespace);
}
__setProperty(name, value) {
this.constructing[name] = value;
}
setStaticAttribute(name, value, namespace) {
this.__setAttribute(name, value, namespace);
}
setDynamicAttribute(name, value, trusting, namespace) {
let element = this.constructing;
let attribute = (0, _dynamic.dynamicAttribute)(element, name, namespace, trusting);
attribute.set(this, value, this.env);
return attribute;
}
}
exports.NewElementBuilder = NewElementBuilder;
_a = CURSOR_STACK;
class SimpleLiveBlock {
constructor(parent) {
this.parent = parent;
this.first = null;
this.last = null;
this.nesting = 0;
}
parentElement() {
return this.parent;
}
firstNode() {
let first = this.first;
return first.firstNode();
}
lastNode() {
let last = this.last;
return last.lastNode();
}
openElement(element) {
this.didAppendNode(element);
this.nesting++;
}
closeElement() {
this.nesting--;
}
didAppendNode(node) {
if (this.nesting !== 0) return;
if (!this.first) {
this.first = new First(node);
}
this.last = new Last(node);
}
didAppendBounds(bounds) {
if (this.nesting !== 0) return;
if (!this.first) {
this.first = bounds;
}
this.last = bounds;
}
finalize(stack) {
if (this.first === null) {
stack.appendComment('');
}
}
}
exports.SimpleLiveBlock = SimpleLiveBlock;
class RemoteLiveBlock extends SimpleLiveBlock {
constructor(parent) {
super(parent);
(0, _destroyable.registerDestructor)(this, () => {
// In general, you only need to clear the root of a hierarchy, and should never
// need to clear any child nodes. This is an important constraint that gives us
// a strong guarantee that clearing a subtree is a single DOM operation.
//
// Because remote blocks are not normally physically nested inside of the tree
// that they are logically nested inside, we manually clear remote blocks when
// a logical parent is cleared.
//
// HOWEVER, it is currently possible for a remote block to be physically nested
// inside of the block it is logically contained inside of. This happens when
// the remote block is appended to the end of the application's entire element.
//
// The problem with that scenario is that Glimmer believes that it owns more of
// the DOM than it actually does. The code is attempting to write past the end
// of the Glimmer-managed root, but Glimmer isn't aware of that.
//
// The correct solution to that problem is for Glimmer to be aware of the end
// of the bounds that it owns, and once we make that change, this check could
// be removed.
//
// For now, a more targeted fix is to check whether the node was already removed
// and avoid clearing the node if it was. In most cases this shouldn't happen,
// so this might hide bugs where the code clears nested nodes unnecessarily,
// so we should eventually try to do the correct fix.
if (this.parentElement() === this.firstNode().parentNode) {
(0, _bounds2.clear)(this);
}
});
}
}
exports.RemoteLiveBlock = RemoteLiveBlock;
class UpdatableBlockImpl extends SimpleLiveBlock {
reset() {
(0, _destroyable.destroy)(this);
let nextSibling = (0, _bounds2.clear)(this);
this.first = null;
this.last = null;
this.nesting = 0;
return nextSibling;
}
} // FIXME: All the noops in here indicate a modelling problem
exports.UpdatableBlockImpl = UpdatableBlockImpl;
class LiveBlockList {
constructor(parent, boundList) {
this.parent = parent;
this.boundList = boundList;
this.parent = parent;
this.boundList = boundList;
}
parentElement() {
return this.parent;
}
firstNode() {
let head = this.boundList[0];
return head.firstNode();
}
lastNode() {
let boundList = this.boundList;
let tail = boundList[boundList.length - 1];
return tail.lastNode();
}
openElement(_element) {
false && (0, _util.assert)(false, 'Cannot openElement directly inside a block list');
}
closeElement() {
false && (0, _util.assert)(false, 'Cannot closeElement directly inside a block list');
}
didAppendNode(_node) {
false && (0, _util.assert)(false, 'Cannot create a new node directly inside a block list');
}
didAppendBounds(_bounds) {}
finalize(_stack) {
false && (0, _util.assert)(this.boundList.length > 0, 'boundsList cannot be empty');
}
}
exports.LiveBlockList = LiveBlockList;
function clientBuilder(env, cursor) {
return NewElementBuilder.forInitialRender(env, cursor);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL2VsZW1lbnQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQWVBOztBQVNBOztBQUNBOztBQUNBOzs7O0FBVUEsTUFBQSxLQUFBLENBQVc7QUFDVCxFQUFBLFdBQUEsQ0FBQSxJQUFBLEVBQW9DO0FBQWhCLFNBQUEsSUFBQSxHQUFBLElBQUE7QUFBb0I7O0FBRXhDLEVBQUEsU0FBUyxHQUFBO0FBQ1AsV0FBTyxLQUFQLElBQUE7QUFDRDs7QUFMUTs7QUFRWCxNQUFBLElBQUEsQ0FBVTtBQUNSLEVBQUEsV0FBQSxDQUFBLElBQUEsRUFBb0M7QUFBaEIsU0FBQSxJQUFBLEdBQUEsSUFBQTtBQUFvQjs7QUFFeEMsRUFBQSxRQUFRLEdBQUE7QUFDTixXQUFPLEtBQVAsSUFBQTtBQUNEOztBQUxPOztBQVFKLE1BQUEsUUFBQSxDQUFlO0FBR25CLEVBQUEsV0FBQSxDQUFBLE1BQUEsRUFBMEI7QUFDeEIsU0FBQSxNQUFBLEdBQUEsTUFBQTtBQUNEOztBQUVELEVBQUEsYUFBYSxHQUFBO0FBQ1gsV0FBTyxLQUFBLE1BQUEsQ0FBUCxhQUFPLEVBQVA7QUFDRDs7QUFFRCxFQUFBLFNBQVMsR0FBQTtBQUNQLFdBQU8sS0FBQSxNQUFBLENBQVAsU0FBTyxFQUFQO0FBQ0Q7O0FBRUQsRUFBQSxRQUFRLEdBQUE7QUFDTixXQUFPLEtBQUEsTUFBQSxDQUFQLFFBQU8sRUFBUDtBQUNEOztBQWpCa0I7OztBQW9CZCxNQUFNLFlBQVksR0FBc0Isa0JBQXhDLGNBQXdDLENBQXhDOzs7QUFFRCxNQUFBLGlCQUFBLENBQXdCO0FBeUI1QixFQUFBLFdBQUEsQ0FBQSxHQUFBLEVBQUEsVUFBQSxFQUFBLFdBQUEsRUFBd0Y7QUF0QmpGLFNBQUEsWUFBQSxHQUFBLElBQUE7QUFDQSxTQUFBLFVBQUEsR0FBQSxJQUFBO0FBR1AsU0FBQSxFQUFBLElBQWlCLElBQWpCLFdB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QUVELEVBQUEsV0FBVyxDQUFBLFFBQUEsRUFBd0I7QUFBQSxhQUNqQyxrQkFBTSxLQUFOLEVBRGlDLGlEQUNqQyxDQURpQztBQUVsQzs7QUFFRCxFQUFBLFlBQVksR0FBQTtBQUFBLGFBQ1Ysa0JBQU0sS0FBTixFQURVLGtEQUNWLENBRFU7QUFFWDs7QUFFRCxFQUFBLGFBQWEsQ0FBQSxLQUFBLEVBQWtCO0FBQUEsYUFDN0Isa0JBQU0sS0FBTixFQUQ2Qix1REFDN0IsQ0FENkI7QUFFOUI7O0FBRUQsRUFBQSxlQUFlLENBQUEsT0FBQSxFQUFnQixDQUFJOztBQUVuQyxFQUFBLFFBQVEsQ0FBQSxNQUFBLEVBQXVCO0FBQUEsYUFDN0Isa0JBQU8sS0FBQSxTQUFBLENBQUEsTUFBQSxHQUFELENBQU4sRUFENkIsNEJBQzdCLENBRDZCO0FBRTlCOztBQTlDdUI7Ozs7QUFpRHBCLFNBQUEsYUFBQSxDQUFBLEdBQUEsRUFBQSxNQUFBLEVBQTREO0FBQ2hFLFNBQU8saUJBQWlCLENBQWpCLGdCQUFBLENBQUEsR0FBQSxFQUFQLE1BQU8sQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQm91bmRzLFxuICBDdXJzb3IsXG4gIEN1cnNvclN0YWNrU3ltYm9sLFxuICBFbGVtZW50QnVpbGRlcixcbiAgRWxlbWVudE9wZXJhdGlvbnMsXG4gIEVudmlyb25tZW50LFxuICBHbGltbWVyVHJlZUNoYW5nZXMsXG4gIEdsaW1tZXJUcmVlQ29uc3RydWN0aW9uLFxuICBMaXZlQmxvY2ssXG4gIE1heWJlLFxuICBPcHRpb24sXG4gIFVwZGF0YWJsZUJsb2NrLFxuICBNb2RpZmllckluc3RhbmNlLFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IGFzc2VydCwgZXhwZWN0LCBTdGFjaywgc3ltYm9sIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5pbXBvcnQge1xuICBBdHRyTmFtZXNwYWNlLFxuICBTaW1wbGVDb21tZW50LFxuICBTaW1wbGVEb2N1bWVudEZyYWdtZW50LFxuICBTaW1wbGVFbGVtZW50LFxuICBTaW1wbGVOb2RlLFxuICBTaW1wbGVUZXh0LFxufSBmcm9tICdAc2ltcGxlLWRvbS9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgY2xlYXIsIENvbmNyZXRlQm91bmRzLCBDdXJzb3JJbXBsLCBTaW5nbGVOb2RlQm91bmRzIH0gZnJvbSAnLi4vYm91bmRzJztcbmltcG9ydCB7IGRlc3Ryb3ksIHJlZ2lzdGVyRGVzdHJ1Y3RvciB9IGZyb20gJ0BnbGltbWVyL2Rlc3Ryb3lhYmxlJztcbmltcG9ydCB7IER5bmFtaWNBdHRyaWJ1dGUsIGR5bmFtaWNBdHRyaWJ1dGUgfSBmcm9tICcuL2F0dHJpYnV0ZXMvZHluYW1pYyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlyc3ROb2RlIHtcbiAgZmlyc3ROb2RlKCk6IFNpbXBsZU5vZGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGFzdE5vZGUge1xuICBsYXN0Tm9kZSgpOiBTaW1wbGVOb2RlO1xufVxuXG5jbGFzcyBGaXJzdCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbm9kZTogU2ltcGxlTm9kZSkge31cblxuICBmaXJzdE5vZGUoKTogU2ltcGxlTm9kZSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZTtcbiAgfVxufVxuXG5jbGFzcyBMYXN0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBub2RlOiBTaW1wbGVOb2RlKSB7fVxuXG4gIGxhc3ROb2RlKCk6IFNpbXBsZU5vZGUge1xuICAgIHJldHVybiB0aGlzLm5vZGU7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZyYWdtZW50IGltcGxlbWVudHMgQm91bmRzIHtcbiAgcHJpdmF0ZSBib3VuZHM6IEJvdW5kcztcblxuICBjb25zdHJ1Y3Rvcihib3VuZHM6IEJvdW5kcykge1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICB9XG5cbiAgcGFyZW50RWxlbWVudCgpOiBTaW1wbGVFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5ib3VuZHMucGFyZW50RWxlbWVudCgpO1xuICB9XG5cbiAgZmlyc3ROb2RlKCk6IFNpbXBsZU5vZGUge1xuICAgIHJldHVybiB0aGlzLmJvdW5kcy5maXJzdE5vZGUoKTtcbiAgfVxuXG4gIGxhc3ROb2RlKCk6IFNpbXBsZU5vZGUge1xuICAgIHJldHVybiB0aGlzLmJvdW5kcy5sYXN0Tm9kZSgpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBDVVJTT1JfU1RBQ0s6IEN1cnNvclN0YWNrU3ltYm9sID0gc3ltYm9sKCdDVVJTT1JfU1RBQ0snKTtcblxuZXhwb3J0IGNsYXNzIE5ld0VsZW1lbnRCdWlsZGVyIGltcGxlbWVudHMgRWxlbWVudEJ1aWxkZXIge1xuICBwdWJsaWMgZG9tOiBHbGltbWVyVHJlZUNvbnN0cnVjdGlvbjtcbiAgcHVibGljIHVwZGF0ZU9wZXJhdGlvbnM6IEdsaW1tZXJUcmVlQ2hhbmdlcztcbiAgcHVibGljIGNvbnN0cnVjdGluZzogT3B0aW9uPFNpbXBsZUVsZW1lbnQ+ID0gbnVsbDtcbiAgcHVibGljIG9wZXJhdGlvbnM6IE9wdGlvbjxFbGVtZW50T3BlcmF0aW9ucz4gPSBudWxsO1xuICBwcml2YXRlIGVudjogRW52aXJvbm1lbnQ7XG5cbiAgW0NVUlNPUl9TVEFDS10gPSBuZXcgU3RhY2s8Q3Vyc29yPigpO1xuICBwcml2YXRlIG1vZGlmaWVyU3RhY2sgPSBuZXcgU3RhY2s8T3B0aW9uPE1vZGlmaWVySW5zdGFuY2VbXT4+KCk7XG4gIHByaXZhdGUgYmxvY2tTdGFjayA9IG5ldyBTdGFjazxMaXZlQmxvY2s+KCk7XG5cbiAgc3RhdGljIGZvckluaXRpYWxSZW5kZXIoZW52OiBFbnZpcm9ubWVudCwgY3Vyc29yOiBDdXJzb3JJbXBsKSB7XG4gICAgcmV0dXJuIG5ldyB0aGlzKGVudiwgY3Vyc29yLmVsZW1lbnQsIGN1cnNvci5uZXh0U2libGluZykuaW5pdGlhbGl6ZSgpO1xuICB9XG5cbiAgc3RhdGljIHJlc3VtZShlbnY6IEVudmlyb25tZW50LCBibG9jazogVXBkYXRhYmxlQmxvY2spOiBOZXdFbGVtZW50QnVpbGRlciB7XG4gICAgbGV0IHBhcmVudE5vZGUgPSBibG9jay5wYXJlbnRFbGVtZW50KCk7XG4gICAgbGV0IG5leHRTaWJsaW5nID0gYmxvY2sucmVzZXQoZW52KTtcblxuICAgIGxldCBzdGFjayA9IG5ldyB0aGlzKGVudiwgcGFyZW50Tm9kZSwgbmV4dFNpYmxpbmcpLmluaXRpYWxpemUoKTtcbiAgICBzdGFjay5wdXNoTGl2ZUJsb2NrKGJsb2NrKTtcblxuICAgIHJldHVybiBzdGFjaztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGVudjogRW52aXJvbm1lbnQsIHBhcmVudE5vZGU6IFNpbXBsZUVsZW1lbnQsIG5leHRTaWJsaW5nOiBPcHRpb248U2ltcGxlTm9kZT4pIHtcbiAgICB0aGlzLnB1c2hFbGVtZW50KHBhcmVudE5vZGUsIG5leHRTaWJsaW5nKTtcblxuICAgIHRoaXMuZW52ID0gZW52O1xuICAgIHRoaXMuZG9tID0gZW52LmdldEFwcGVuZE9wZXJhdGlvbnMoKTtcbiAgICB0aGlzLnVwZGF0ZU9wZXJhdGlvbnMgPSBlbnYuZ2V0RE9NKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaW5pdGlhbGl6ZSgpOiB0aGlzIHtcbiAgICB0aGlzLnB1c2hTaW1wbGVCbG9jaygpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZGVidWdCbG9ja3MoKTogTGl2ZUJsb2NrW10ge1xuICAgIHJldHVybiB0aGlzLmJsb2NrU3RhY2sudG9BcnJheSgpO1xuICB9XG5cbiAgZ2V0IGVsZW1lbnQoKTogU2ltcGxlRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXNbQ1VSU09SX1NUQUNLXS5jdXJyZW50IS5lbGVtZW50O1xuICB9XG5cbiAgZ2V0IG5leHRTaWJsaW5nKCk6IE9wdGlvbjxTaW1wbGVOb2RlPiB7XG4gICAgcmV0dXJuIHRoaXNbQ1VSU09SX1NUQUNLXS5jdXJyZW50IS5uZXh0U2libGluZztcbiAgfVxuXG4gIGdldCBoYXNCbG9ja3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuYmxvY2tTdGFjay5zaXplID4gMDtcbiAgfVxuXG4gIHByb3RlY3RlZCBibG9jaygpOiBMaXZlQmxvY2sge1xuICAgIHJldHVybiBleHBlY3QodGhpcy5ibG9ja1N0YWNrLmN1cnJlbnQsICdFeHBlY3RlZCBhIGN1cnJlbnQgbGl2ZSBibG9jaycpO1xuICB9XG5cbiAgcG9wRWxlbWVudCgpIHtcbiAgICB0aGlzW0NVUlNPUl9TVEFDS10ucG9wKCk7XG4gICAgZXhwZWN0KHRoaXNbQ1VSU09SX1NUQUNLXS5jdXJyZW50LCBcImNhbid0IHBvcCBwYXN0IHRoZSBsYXN0IGVsZW1lbnRcIik7XG4gIH1cblxuICBwdXNoU2ltcGxlQmxvY2soKTogTGl2ZUJsb2NrIHtcbiAgICByZXR1cm4gdGhpcy5wdXNoTGl2ZUJsb2NrKG5ldyBTaW1wbGVMaXZlQmxvY2sodGhpcy5lbGVtZW50KSk7XG4gIH1cblxuICBwdXNoVXBkYXRhYmxlQmxvY2soKTogVXBkYXRhYmxlQmxvY2tJbXBsIHtcbiAgICByZXR1cm4gdGhpcy5wdXNoTGl2ZUJsb2NrKG5ldyBVcGRhdGFibGVCbG9ja0ltcGwodGhpcy5lbGVtZW50KSk7XG4gIH1cblxuICBwdXNoQmxvY2tMaXN0KGxpc3Q6IExpdmVCbG9ja1tdKTogTGl2ZUJsb2NrTGlzdCB7XG4gICAgcmV0dXJuIHRoaXMucHVzaExpdmVCbG9jayhuZXcgTGl2ZUJsb2NrTGlzdCh0aGlzLmVsZW1lbnQsIGxpc3QpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwdXNoTGl2ZUJsb2NrPFQgZXh0ZW5kcyBMaXZlQmxvY2s+KGJsb2NrOiBULCBpc1JlbW90ZSA9IGZhbHNlKTogVCB7XG4gICAgbGV0IGN1cnJlbnQgPSB0aGlzLmJsb2NrU3RhY2suY3VycmVudDtcblxuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICBpZiAoIWlzUmVtb3RlKSB7XG4gICAgICAgIGN1cnJlbnQuZGlkQXBwZW5kQm91bmRzKGJsb2NrKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9fb3BlbkJsb2NrKCk7XG4gICAgdGhpcy5ibG9ja1N0YWNrLnB1c2goYmxvY2spO1xuICAgIHJldHVybiBibG9jaztcbiAgfVxuXG4gIHBvcEJsb2NrKCk6IExpdmVCbG9jayB7XG4gICAgdGhpcy5ibG9jaygpLmZpbmFsaXplKHRoaXMpO1xuICAgIHRoaXMuX19jbG9zZUJsb2NrKCk7XG4gICAgcmV0dXJuIGV4cGVjdCh0aGlzLmJsb2NrU3RhY2sucG9wKCksICdFeHBlY3RlZCBwb3BCbG9jayB0byByZXR1cm4gYSBibG9jaycpO1xuICB9XG5cbiAgX19vcGVuQmxvY2soKTogdm9pZCB7fVxuICBfX2Nsb3NlQmxvY2soKTogdm9pZCB7fVxuXG4gIC8vIHRvZG8gcmV0dXJuIHNlZW1zIHVudXNlZFxuICBvcGVuRWxlbWVudCh0YWc6IHN0cmluZyk6IFNpbXBsZUVsZW1lbnQge1xuICAgIGxldCBlbGVtZW50ID0gdGhpcy5fX29wZW5FbGVtZW50KHRhZyk7XG4gICAgdGhpcy5jb25zdHJ1Y3RpbmcgPSBlbGVtZW50O1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICBfX29wZW5FbGVtZW50KHRhZzogc3RyaW5nKTogU2ltcGxlRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuZG9tLmNyZWF0ZUVsZW1lbnQodGFnLCB0aGlzLmVsZW1lbnQpO1xuICB9XG5cbiAgZmx1c2hFbGVtZW50KG1vZGlmaWVyczogT3B0aW9uPE1vZGlmaWVySW5zdGFuY2VbXT4pIHtcbiAgICBsZXQgcGFyZW50ID0gdGhpcy5lbGVtZW50O1xuICAgIGxldCBlbGVtZW50ID0gZXhwZWN0KFxuICAgICAgdGhpcy5jb25zdHJ1Y3RpbmcsXG4gICAgICBgZmx1c2hFbGVtZW50IHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuIGNvbnN0cnVjdGluZyBhbiBlbGVtZW50YFxuICAgICk7XG5cbiAgICB0aGlzLl9fZmx1c2hFbGVtZW50KHBhcmVudCwgZWxlbWVudCk7XG5cbiAgICB0aGlzLmNvbnN0cnVjdGluZyA9IG51bGw7XG4gICAgdGhpcy5vcGVyYXRpb25zID0gbnVsbDtcblxuICAgIHRoaXMucHVzaE1vZGlmaWVycyhtb2RpZmllcnMpO1xuICAgIHRoaXMucHVzaEVsZW1lbnQoZWxlbWVudCwgbnVsbCk7XG4gICAgdGhpcy5kaWRPcGVuRWxlbWVudChlbGVtZW50KTtcbiAgfVxuXG4gIF9fZmx1c2hFbGVtZW50KHBhcmVudDogU2ltcGxlRWxlbWVudCwgY29uc3RydWN0aW5nOiBTaW1wbGVFbGVtZW50KSB7XG4gICAgdGhpcy5kb20uaW5zZXJ0QmVmb3JlKHBhcmVudCwgY29uc3RydWN0aW5nLCB0aGlzLm5leHRTaWJsaW5nKTtcbiAgfVxuXG4gIGNsb3NlRWxlbWVudCgpOiBPcHRpb248TW9kaWZpZXJJbnN0YW5jZVtdPiB7XG4gICAgdGhpcy53aWxsQ2xvc2VFbGVtZW50KCk7XG4gICAgdGhpcy5wb3BFbGVtZW50KCk7XG4gICAgcmV0dXJuIHRoaXMucG9wTW9kaWZpZXJzKCk7XG4gIH1cblxuICBwdXNoUmVtb3RlRWxlbWVudChcbiAgICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICAgIGd1aWQ6IHN0cmluZyxcbiAgICBpbnNlcnRCZWZvcmU6IE1heWJlPFNpbXBsZU5vZGU+XG4gICk6IE9wdGlvbjxSZW1vdGVMaXZlQmxvY2s+IHtcbiAgICByZXR1cm4gdGhpcy5fX3B1c2hSZW1vdGVFbGVtZW50KGVsZW1lbnQsIGd1aWQsIGluc2VydEJlZm9yZSk7XG4gIH1cblxuICBfX3B1c2hSZW1vdGVFbGVtZW50KFxuICAgIGVsZW1lbnQ6IFNpbXBsZUVsZW1lbnQsXG4gICAgX2d1aWQ6IHN0cmluZyxcbiAgICBpbnNlcnRCZWZvcmU6IE1heWJlPFNpbXBsZU5vZGU+XG4gICk6IE9wdGlvbjxSZW1vdGVMaXZlQmxvY2s+IHtcbiAgICB0aGlzLnB1c2hFbGVtZW50KGVsZW1lbnQsIGluc2VydEJlZm9yZSk7XG5cbiAgICBpZiAoaW5zZXJ0QmVmb3JlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHdoaWxlIChlbGVtZW50Lmxhc3RDaGlsZCkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQubGFzdENoaWxkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgYmxvY2sgPSBuZXcgUmVtb3RlTGl2ZUJsb2NrKGVsZW1lbnQpO1xuXG4gICAgcmV0dXJuIHRoaXMucHVzaExpdmVCbG9jayhibG9jaywgdHJ1ZSk7XG4gIH1cblxuICBwb3BSZW1vdGVFbGVtZW50KCkge1xuICAgIHRoaXMucG9wQmxvY2soKTtcbiAgICB0aGlzLnBvcEVsZW1lbnQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwdXNoRWxlbWVudChlbGVtZW50OiBTaW1wbGVFbGVtZW50LCBuZXh0U2libGluZzogTWF5YmU8U2ltcGxlTm9kZT4gPSBudWxsKSB7XG4gICAgdGhpc1tDVVJTT1JfU1RBQ0tdLnB1c2gobmV3IEN1cnNvckltcGwoZWxlbWVudCwgbmV4dFNpYmxpbmcpKTtcbiAgfVxuXG4gIHByaXZhdGUgcHVzaE1vZGlmaWVycyhtb2RpZmllcnM6IE9wdGlvbjxNb2RpZmllckluc3RhbmNlW10+KTogdm9pZCB7XG4gICAgdGhpcy5tb2RpZmllclN0YWNrLnB1c2gobW9kaWZpZXJzKTtcbiAgfVxuXG4gIHByaXZhdGUgcG9wTW9kaWZpZXJzKCk6IE9wdGlvbjxNb2RpZmllckluc3RhbmNlW10+IHtcbiAgICByZXR1cm4gdGhpcy5tb2RpZmllclN0YWNrLnBvcCgpO1xuICB9XG5cbiAgZGlkQXBwZW5kQm91bmRzKGJvdW5kczogQm91bmRzKTogQm91bmRzIHtcbiAgICB0aGlzLmJsb2NrKCkuZGlkQXBwZW5kQm91bmRzKGJvdW5kcyk7XG4gICAgcmV0dXJuIGJvdW5kcztcbiAgfVxuXG4gIGRpZEFwcGVuZE5vZGU8VCBleHRlbmRzIFNpbXBsZU5vZGU+KG5vZGU6IFQpOiBUIHtcbiAgICB0aGlzLmJsb2NrKCkuZGlkQXBwZW5kTm9kZShub2RlKTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIGRpZE9wZW5FbGVtZW50KGVsZW1lbnQ6IFNpbXBsZUVsZW1lbnQpOiBTaW1wbGVFbGVtZW50IHtcbiAgICB0aGlzLmJsb2NrKCkub3BlbkVsZW1lbnQoZWxlbWVudCk7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICB3aWxsQ2xvc2VFbGVtZW50KCkge1xuICAgIHRoaXMuYmxvY2soKS5jbG9zZUVsZW1lbnQoKTtcbiAgfVxuXG4gIGFwcGVuZFRleHQoc3RyaW5nOiBzdHJpbmcpOiBTaW1wbGVUZXh0IHtcbiAgICByZXR1cm4gdGhpcy5kaWRBcHBlbmROb2RlKHRoaXMuX19hcHBlbmRUZXh0KHN0cmluZykpO1xuICB9XG5cbiAgX19hcHBlbmRUZXh0KHRleHQ6IHN0cmluZyk6IFNpbXBsZVRleHQge1xuICAgIGxldCB7IGRvbSwgZWxlbWVudCwgbmV4dFNpYmxpbmcgfSA9IHRoaXM7XG4gICAgbGV0IG5vZGUgPSBkb20uY3JlYXRlVGV4dE5vZGUodGV4dCk7XG4gICAgZG9tLmluc2VydEJlZm9yZShlbGVtZW50LCBub2RlLCBuZXh0U2libGluZyk7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBfX2FwcGVuZE5vZGUobm9kZTogU2ltcGxlTm9kZSk6IFNpbXBsZU5vZGUge1xuICAgIHRoaXMuZG9tLmluc2VydEJlZm9yZSh0aGlzLmVsZW1lbnQsIG5vZGUsIHRoaXMubmV4dFNpYmxpbmcpO1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgX19hcHBlbmRGcmFnbWVudChmcmFnbWVudDogU2ltcGxlRG9jdW1lbnRGcmFnbWVudCk6IEJvdW5kcyB7XG4gICAgbGV0IGZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuICAgIGlmIChmaXJzdCkge1xuICAgICAgbGV0IHJldCA9IG5ldyBDb25jcmV0ZUJvdW5kcyh0aGlzLmVsZW1lbnQsIGZpcnN0LCBmcmFnbWVudC5sYXN0Q2hpbGQhKTtcbiAgICAgIHRoaXMuZG9tLmluc2VydEJlZm9yZSh0aGlzLmVsZW1lbnQsIGZyYWdtZW50LCB0aGlzLm5leHRTaWJsaW5nKTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgU2luZ2xlTm9kZUJvdW5kcyh0aGlzLmVsZW1lbnQsIHRoaXMuX19hcHBlbmRDb21tZW50KCcnKSk7XG4gICAgfVxuICB9XG5cbiAgX19hcHBlbmRIVE1MKGh0bWw6IHN0cmluZyk6IEJvdW5kcyB7XG4gICAgcmV0dXJuIHRoaXMuZG9tLmluc2VydEhUTUxCZWZvcmUodGhpcy5lbGVtZW50LCB0aGlzLm5leHRTaWJsaW5nLCBodG1sKTtcbiAgfVxuXG4gIGFwcGVuZER5bmFtaWNIVE1MKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgYm91bmRzID0gdGhpcy50cnVzdGVkQ29udGVudCh2YWx1ZSk7XG4gICAgdGhpcy5kaWRBcHBlbmRCb3VuZHMoYm91bmRzKTtcbiAgfVxuXG4gIGFwcGVuZER5bmFtaWNUZXh0KHZhbHVlOiBzdHJpbmcpOiBTaW1wbGVUZXh0IHtcbiAgICBsZXQgbm9kZSA9IHRoaXMudW50cnVzdGVkQ29udGVudCh2YWx1ZSk7XG4gICAgdGhpcy5kaWRBcHBlbmROb2RlKG5vZGUpO1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgYXBwZW5kRHluYW1pY0ZyYWdtZW50KHZhbHVlOiBTaW1wbGVEb2N1bWVudEZyYWdtZW50KTogdm9pZCB7XG4gICAgbGV0IGJvdW5kcyA9IHRoaXMuX19hcHBlbmRGcmFnbWVudCh2YWx1ZSk7XG4gICAgdGhpcy5kaWRBcHBlbmRCb3VuZHMoYm91bmRzKTtcbiAgfVxuXG4gIGFwcGVuZER5bmFtaWNOb2RlKHZhbHVlOiBTaW1wbGVOb2RlKTogdm9pZCB7XG4gICAgbGV0IG5vZGUgPSB0aGlzLl9fYXBwZW5kTm9kZSh2YWx1ZSk7XG4gICAgbGV0IGJvdW5kcyA9IG5ldyBTaW5nbGVOb2RlQm91bmRzKHRoaXMuZWxlbWVudCwgbm9kZSk7XG4gICAgdGhpcy5kaWRBcHBlbmRCb3VuZHMoYm91bmRzKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJ1c3RlZENvbnRlbnQodmFsdWU6IHN0cmluZyk6IEJvdW5kcyB7XG4gICAgcmV0dXJuIHRoaXMuX19hcHBlbmRIVE1MKHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgdW50cnVzdGVkQ29udGVudCh2YWx1ZTogc3RyaW5nKTogU2ltcGxlVGV4dCB7XG4gICAgcmV0dXJuIHRoaXMuX19hcHBlbmRUZXh0KHZhbHVlKTtcbiAgfVxuXG4gIGFwcGVuZENvbW1lbnQoc3RyaW5nOiBzdHJpbmcpOiBTaW1wbGVDb21tZW50IHtcbiAgICByZXR1cm4gdGhpcy5kaWRBcHBlbmROb2RlKHRoaXMuX19hcHBlbmRDb21tZW50KHN0cmluZykpO1xuICB9XG5cbiAgX19hcHBlbmRDb21tZW50KHN0cmluZzogc3RyaW5nKTogU2ltcGxlQ29tbWVudCB7XG4gICAgbGV0IHsgZG9tLCBlbGVtZW50LCBuZXh0U2libGluZyB9ID0gdGhpcztcbiAgICBsZXQgbm9kZSA9IGRvbS5jcmVhdGVDb21tZW50KHN0cmluZyk7XG4gICAgZG9tLmluc2VydEJlZm9yZShlbGVtZW50LCBub2RlLCBuZXh0U2libGluZyk7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBfX3NldEF0dHJpYnV0ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIG5hbWVzcGFjZTogT3B0aW9uPEF0dHJOYW1lc3BhY2U+KTogdm9pZCB7XG4gICAgdGhpcy5kb20uc2V0QXR0cmlidXRlKHRoaXMuY29uc3RydWN0aW5nISwgbmFtZSwgdmFsdWUsIG5hbWVzcGFjZSk7XG4gIH1cblxuICBfX3NldFByb3BlcnR5KG5hbWU6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICAodGhpcy5jb25zdHJ1Y3RpbmchIGFzIGFueSlbbmFtZV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHNldFN0YXRpY0F0dHJpYnV0ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIG5hbWVzcGFjZTogT3B0aW9uPEF0dHJOYW1lc3BhY2U+KTogdm9pZCB7XG4gICAgdGhpcy5fX3NldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSwgbmFtZXNwYWNlKTtcbiAgfVxuXG4gIHNldER5bmFtaWNBdHRyaWJ1dGUoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiB1bmtub3duLFxuICAgIHRydXN0aW5nOiBib29sZWFuLFxuICAgIG5hbWVzcGFjZTogT3B0aW9uPEF0dHJOYW1lc3BhY2U+XG4gICk6IER5bmFtaWNBdHRyaWJ1dGUge1xuICAgIGxldCBlbGVtZW50ID0gdGhpcy5jb25zdHJ1Y3RpbmchO1xuICAgIGxldCBhdHRyaWJ1dGUgPSBkeW5hbWljQXR0cmlidXRlKGVsZW1lbnQsIG5hbWUsIG5hbWVzcGFjZSwgdHJ1c3RpbmcpO1xuICAgIGF0dHJpYnV0ZS5zZXQodGhpcywgdmFsdWUsIHRoaXMuZW52KTtcbiAgICByZXR1cm4gYXR0cmlidXRlO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTaW1wbGVMaXZlQmxvY2sgaW1wbGVtZW50cyBMaXZlQmxvY2sge1xuICBwcm90ZWN0ZWQgZmlyc3Q6IE9wdGlvbjxGaXJzdE5vZGU+ID0gbnVsbDtcbiAgcHJvdGVjdGVkIGxhc3Q6IE9wdGlvbjxMYXN0Tm9kZT4gPSBudWxsO1xuICBwcm90ZWN0ZWQgbmVzdGluZyA9IDA7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBwYXJlbnQ6IFNpbXBsZUVsZW1lbnQpIHt9XG5cbiAgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICBmaXJzdE5vZGUoKTogU2ltcGxlTm9kZSB7XG4gICAgbGV0IGZpcnN0ID0gZXhwZWN0KFxuICAgICAgdGhpcy5maXJzdCxcbiAgICAgICdjYW5ub3QgY2FsbCBgZmlyc3ROb2RlKClgIHdoaWxlIGBTaW1wbGVMaXZlQmxvY2tgIGlzIHN0aWxsIGluaXRpYWxpemluZydcbiAgICApO1xuXG4gICAgcmV0dXJuIGZpcnN0LmZpcnN0Tm9kZSgpO1xuICB9XG5cbiAgbGFzdE5vZGUoKTogU2ltcGxlTm9kZSB7XG4gICAgbGV0IGxhc3QgPSBleHBlY3QoXG4gICAgICB0aGlzLmxhc3QsXG4gICAgICAnY2Fubm90IGNhbGwgYGxhc3ROb2RlKClgIHdoaWxlIGBTaW1wbGVMaXZlQmxvY2tgIGlzIHN0aWxsIGluaXRpYWxpemluZydcbiAgICApO1xuXG4gICAgcmV0dXJuIGxhc3QubGFzdE5vZGUoKTtcbiAgfVxuXG4gIG9wZW5FbGVtZW50KGVsZW1lbnQ6IFNpbXBsZUVsZW1lbnQpIHtcbiAgICB0aGlzLmRpZEFwcGVuZE5vZGUoZWxlbWVudCk7XG4gICAgdGhpcy5uZXN0aW5nKys7XG4gIH1cblxuICBjbG9zZUVsZW1lbnQoKSB7XG4gICAgdGhpcy5uZXN0aW5nLS07XG4gIH1cblxuICBkaWRBcHBlbmROb2RlKG5vZGU6IFNpbXBsZU5vZGUpIHtcbiAgICBpZiAodGhpcy5uZXN0aW5nICE9PSAwKSByZXR1cm47XG5cbiAgICBpZiAoIXRoaXMuZmlyc3QpIHtcbiAgICAgIHRoaXMuZmlyc3QgPSBuZXcgRmlyc3Qobm9kZSk7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0ID0gbmV3IExhc3Qobm9kZSk7XG4gIH1cblxuICBkaWRBcHBlbmRCb3VuZHMoYm91bmRzOiBCb3VuZHMpIHtcbiAgICBpZiAodGhpcy5uZXN0aW5nICE9PSAwKSByZXR1cm47XG5cbiAgICBpZiAoIXRoaXMuZmlyc3QpIHtcbiAgICAgIHRoaXMuZmlyc3QgPSBib3VuZHM7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0ID0gYm91bmRzO1xuICB9XG5cbiAgZmluYWxpemUoc3RhY2s6IEVsZW1lbnRCdWlsZGVyKSB7XG4gICAgaWYgKHRoaXMuZmlyc3QgPT09IG51bGwpIHtcbiAgICAgIHN0YWNrLmFwcGVuZENvbW1lbnQoJycpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVtb3RlTGl2ZUJsb2NrIGV4dGVuZHMgU2ltcGxlTGl2ZUJsb2NrIHtcbiAgY29uc3RydWN0b3IocGFyZW50OiBTaW1wbGVFbGVtZW50KSB7XG4gICAgc3VwZXIocGFyZW50KTtcblxuICAgIHJlZ2lzdGVyRGVzdHJ1Y3Rvcih0aGlzLCAoKSA9PiB7XG4gICAgICAvLyBJbiBnZW5lcmFsLCB5b3Ugb25seSBuZWVkIHRvIGNsZWFyIHRoZSByb290IG9mIGEgaGllcmFyY2h5LCBhbmQgc2hvdWxkIG5ldmVyXG4gICAgICAvLyBuZWVkIHRvIGNsZWFyIGFueSBjaGlsZCBub2Rlcy4gVGhpcyBpcyBhbiBpbXBvcnRhbnQgY29uc3RyYWludCB0aGF0IGdpdmVzIHVzXG4gICAgICAvLyBhIHN0cm9uZyBndWFyYW50ZWUgdGhhdCBjbGVhcmluZyBhIHN1YnRyZWUgaXMgYSBzaW5nbGUgRE9NIG9wZXJhdGlvbi5cbiAgICAgIC8vXG4gICAgICAvLyBCZWNhdXNlIHJlbW90ZSBibG9ja3MgYXJlIG5vdCBub3JtYWxseSBwaHlzaWNhbGx5IG5lc3RlZCBpbnNpZGUgb2YgdGhlIHRyZWVcbiAgICAgIC8vIHRoYXQgdGhleSBhcmUgbG9naWNhbGx5IG5lc3RlZCBpbnNpZGUsIHdlIG1hbnVhbGx5IGNsZWFyIHJlbW90ZSBibG9ja3Mgd2hlblxuICAgICAgLy8gYSBsb2dpY2FsIHBhcmVudCBpcyBjbGVhcmVkLlxuICAgICAgLy9cbiAgICAgIC8vIEhPV0VWRVIsIGl0IGlzIGN1cnJlbnRseSBwb3NzaWJsZSBmb3IgYSByZW1vdGUgYmxvY2sgdG8gYmUgcGh5c2ljYWxseSBuZXN0ZWRcbiAgICAgIC8vIGluc2lkZSBvZiB0aGUgYmxvY2sgaXQgaXMgbG9naWNhbGx5IGNvbnRhaW5lZCBpbnNpZGUgb2YuIFRoaXMgaGFwcGVucyB3aGVuXG4gICAgICAvLyB0aGUgcmVtb3RlIGJsb2NrIGlzIGFwcGVuZGVkIHRvIHRoZSBlbmQgb2YgdGhlIGFwcGxpY2F0aW9uJ3MgZW50aXJlIGVsZW1lbnQuXG4gICAgICAvL1xuICAgICAgLy8gVGhlIHByb2JsZW0gd2l0aCB0aGF0IHNjZW5hcmlvIGlzIHRoYXQgR2xpbW1lciBiZWxpZXZlcyB0aGF0IGl0IG93bnMgbW9yZSBvZlxuICAgICAgLy8gdGhlIERPTSB0aGFuIGl0IGFjdHVhbGx5IGRvZXMuIFRoZSBjb2RlIGlzIGF0dGVtcHRpbmcgdG8gd3JpdGUgcGFzdCB0aGUgZW5kXG4gICAgICAvLyBvZiB0aGUgR2xpbW1lci1tYW5hZ2VkIHJvb3QsIGJ1dCBHbGltbWVyIGlzbid0IGF3YXJlIG9mIHRoYXQuXG4gICAgICAvL1xuICAgICAgLy8gVGhlIGNvcnJlY3Qgc29sdXRpb24gdG8gdGhhdCBwcm9ibGVtIGlzIGZvciBHbGltbWVyIHRvIGJlIGF3YXJlIG9mIHRoZSBlbmRcbiAgICAgIC8vIG9mIHRoZSBib3VuZHMgdGhhdCBpdCBvd25zLCBhbmQgb25jZSB3ZSBtYWtlIHRoYXQgY2hhbmdlLCB0aGlzIGNoZWNrIGNvdWxkXG4gICAgICAvLyBiZSByZW1vdmVkLlxuICAgICAgLy9cbiAgICAgIC8vIEZvciBub3csIGEgbW9yZSB0YXJnZXRlZCBmaXggaXMgdG8gY2hlY2sgd2hldGhlciB0aGUgbm9kZSB3YXMgYWxyZWFkeSByZW1vdmVkXG4gICAgICAvLyBhbmQgYXZvaWQgY2xlYXJpbmcgdGhlIG5vZGUgaWYgaXQgd2FzLiBJbiBtb3N0IGNhc2VzIHRoaXMgc2hvdWxkbid0IGhhcHBlbixcbiAgICAgIC8vIHNvIHRoaXMgbWlnaHQgaGlkZSBidWdzIHdoZXJlIHRoZSBjb2RlIGNsZWFycyBuZXN0ZWQgbm9kZXMgdW5uZWNlc3NhcmlseSxcbiAgICAgIC8vIHNvIHdlIHNob3VsZCBldmVudHVhbGx5IHRyeSB0byBkbyB0aGUgY29ycmVjdCBmaXguXG4gICAgICBpZiAodGhpcy5wYXJlbnRFbGVtZW50KCkgPT09IHRoaXMuZmlyc3ROb2RlKCkucGFyZW50Tm9kZSkge1xuICAgICAgICBjbGVhcih0aGlzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVXBkYXRhYmxlQmxvY2tJbXBsIGV4dGVuZHMgU2ltcGxlTGl2ZUJsb2NrIGltcGxlbWVudHMgVXBkYXRhYmxlQmxvY2sge1xuICByZXNldCgpOiBPcHRpb248U2ltcGxlTm9kZT4ge1xuICAgIGRlc3Ryb3kodGhpcyk7XG4gICAgbGV0IG5leHRTaWJsaW5nID0gY2xlYXIodGhpcyk7XG5cbiAgICB0aGlzLmZpcnN0ID0gbnVsbDtcbiAgICB0aGlzLmxhc3QgPSBudWxsO1xuICAgIHRoaXMubmVzdGluZyA9IDA7XG5cbiAgICByZXR1cm4gbmV4dFNpYmxpbmc7XG4gIH1cbn1cblxuLy8gRklYTUU6IEFsbCB0aGUgbm9vcHMgaW4gaGVyZSBpbmRpY2F0ZSBhIG1vZGVsbGluZyBwcm9ibGVtXG5leHBvcnQgY2xhc3MgTGl2ZUJsb2NrTGlzdCBpbXBsZW1lbnRzIExpdmVCbG9jayB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcGFyZW50OiBTaW1wbGVFbGVtZW50LCBwdWJsaWMgYm91bmRMaXN0OiBMaXZlQmxvY2tbXSkge1xuICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgIHRoaXMuYm91bmRMaXN0ID0gYm91bmRMaXN0O1xuICB9XG5cbiAgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICBmaXJzdE5vZGUoKTogU2ltcGxlTm9kZSB7XG4gICAgbGV0IGhlYWQgPSBleHBlY3QoXG4gICAgICB0aGlzLmJvdW5kTGlzdFswXSxcbiAgICAgICdjYW5ub3QgY2FsbCBgZmlyc3ROb2RlKClgIHdoaWxlIGBMaXZlQmxvY2tMaXN0YCBpcyBzdGlsbCBpbml0aWFsaXppbmcnXG4gICAgKTtcblxuICAgIHJldHVybiBoZWFkLmZpcnN0Tm9kZSgpO1xuICB9XG5cbiAgbGFzdE5vZGUoKTogU2ltcGxlTm9kZSB7XG4gICAgbGV0IGJvdW5kTGlzdCA9IHRoaXMuYm91bmRMaXN0O1xuXG4gICAgbGV0IHRhaWwgPSBleHBlY3QoXG4gICAgICBib3VuZExpc3RbYm91bmRMaXN0Lmxlbmd0aCAtIDFdLFxuICAgICAgJ2Nhbm5vdCBjYWxsIGBsYXN0Tm9kZSgpYCB3aGlsZSBgTGl2ZUJsb2NrTGlzdGAgaXMgc3RpbGwgaW5pdGlhbGl6aW5nJ1xuICAgICk7XG5cbiAgICByZXR1cm4gdGFpbC5sYXN0Tm9kZSgpO1xuICB9XG5cbiAgb3BlbkVsZW1lbnQoX2VsZW1lbnQ6IFNpbXBsZUVsZW1lbnQpIHtcbiAgICBhc3NlcnQoZmFsc2UsICdDYW5ub3Qgb3BlbkVsZW1lbnQgZGlyZWN0bHkgaW5zaWRlIGEgYmxvY2sgbGlzdCcpO1xuICB9XG5cbiAgY2xvc2VFbGVtZW50KCkge1xuICAgIGFzc2VydChmYWxzZSwgJ0Nhbm5vdCBjbG9zZUVsZW1lbnQgZGlyZWN0bHkgaW5zaWRlIGEgYmxvY2sgbGlzdCcpO1xuICB9XG5cbiAgZGlkQXBwZW5kTm9kZShfbm9kZTogU2ltcGxlTm9kZSkge1xuICAgIGFzc2VydChmYWxzZSwgJ0Nhbm5vdCBjcmVhdGUgYSBuZXcgbm9kZSBkaXJlY3RseSBpbnNpZGUgYSBibG9jayBsaXN0Jyk7XG4gIH1cblxuICBkaWRBcHBlbmRCb3VuZHMoX2JvdW5kczogQm91bmRzKSB7fVxuXG4gIGZpbmFsaXplKF9zdGFjazogRWxlbWVudEJ1aWxkZXIpIHtcbiAgICBhc3NlcnQodGhpcy5ib3VuZExpc3QubGVuZ3RoID4gMCwgJ2JvdW5kc0xpc3QgY2Fubm90IGJlIGVtcHR5Jyk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsaWVudEJ1aWxkZXIoZW52OiBFbnZpcm9ubWVudCwgY3Vyc29yOiBDdXJzb3JJbXBsKTogRWxlbWVudEJ1aWxkZXIge1xuICByZXR1cm4gTmV3RWxlbWVudEJ1aWxkZXIuZm9ySW5pdGlhbFJlbmRlcihlbnYsIGN1cnNvcik7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9