UNPKG

ember-legacy-class-transform

Version:
311 lines (299 loc) 36.8 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.BlockSymbolTable = exports.ProgramSymbolTable = exports.SymbolTable = undefined; var _util = require('@glimmer/util'); class SymbolTable { static top() { return new ProgramSymbolTable(); } child(locals) { let symbols = locals.map(name => this.allocate(name)); return new BlockSymbolTable(this, locals, symbols); } } exports.SymbolTable = SymbolTable; class ProgramSymbolTable extends SymbolTable { constructor() { super(...arguments); this.symbols = []; this.size = 1; this.named = (0, _util.dict)(); this.blocks = (0, _util.dict)(); } has(_name) { return false; } get(_name) { throw (0, _util.unreachable)(); } getLocalsMap() { return {}; } getEvalInfo() { return []; } allocateNamed(name) { let named = this.named[name]; if (!named) { named = this.named[name] = this.allocate(`@${name}`); } return named; } allocateBlock(name) { let block = this.blocks[name]; if (!block) { block = this.blocks[name] = this.allocate(`&${name}`); } return block; } allocate(identifier) { this.symbols.push(identifier); return this.size++; } } exports.ProgramSymbolTable = ProgramSymbolTable; class BlockSymbolTable extends SymbolTable { constructor(parent, symbols, slots) { super(); this.parent = parent; this.symbols = symbols; this.slots = slots; } has(name) { return this.symbols.indexOf(name) !== -1 || this.parent.has(name); } get(name) { let slot = this.symbols.indexOf(name); return slot === -1 ? this.parent.get(name) : this.slots[slot]; } getLocalsMap() { let dict = this.parent.getLocalsMap(); this.symbols.forEach(symbol => dict[symbol] = this.get(symbol)); return dict; } getEvalInfo() { let locals = this.getLocalsMap(); return Object.keys(locals).map(symbol => locals[symbol]); } allocateNamed(name) { return this.parent.allocateNamed(name); } allocateBlock(name) { return this.parent.allocateBlock(name); } allocate(identifier) { return this.parent.allocate(identifier); } } exports.BlockSymbolTable = BlockSymbolTable; /** * Takes in an AST and outputs a list of actions to be consumed * by a compiler. For example, the template * * foo{{bar}}<div>baz</div> * * produces the actions * * [['startProgram', [programNode, 0]], * ['text', [textNode, 0, 3]], * ['mustache', [mustacheNode, 1, 3]], * ['openElement', [elementNode, 2, 3, 0]], * ['text', [textNode, 0, 1]], * ['closeElement', [elementNode, 2, 3], * ['endProgram', [programNode]]] * * This visitor walks the AST depth first and backwards. As * a result the bottom-most child template will appear at the * top of the actions list whereas the root template will appear * at the bottom of the list. For example, * * <div>{{#if}}foo{{else}}bar<b></b>{{/if}}</div> * * produces the actions * * [['startProgram', [programNode, 0]], * ['text', [textNode, 0, 2, 0]], * ['openElement', [elementNode, 1, 2, 0]], * ['closeElement', [elementNode, 1, 2]], * ['endProgram', [programNode]], * ['startProgram', [programNode, 0]], * ['text', [textNode, 0, 1]], * ['endProgram', [programNode]], * ['startProgram', [programNode, 2]], * ['openElement', [elementNode, 0, 1, 1]], * ['block', [blockNode, 0, 1]], * ['closeElement', [elementNode, 0, 1]], * ['endProgram', [programNode]]] * * The state of the traversal is maintained by a stack of frames. * Whenever a node with children is entered (either a ProgramNode * or an ElementNode) a frame is pushed onto the stack. The frame * contains information about the state of the traversal of that * node. For example, * * - index of the current child node being visited * - the number of mustaches contained within its child nodes * - the list of actions generated by its child nodes */ class Frame { constructor() { this.parentNode = null; this.children = null; this.childIndex = null; this.childCount = null; this.childTemplateCount = 0; this.mustacheCount = 0; this.actions = []; this.blankChildTextNodes = null; this.symbols = null; } } class TemplateVisitor { constructor() { this.frameStack = []; this.actions = []; this.programDepth = -1; } visit(node) { this[node.type](node); } // Traversal methods Program(program) { this.programDepth++; let parentFrame = this.getCurrentFrame(); let programFrame = this.pushFrame(); if (!parentFrame) { program['symbols'] = SymbolTable.top(); } else { program['symbols'] = parentFrame.symbols.child(program.blockParams); } let startType, endType; if (this.programDepth === 0) { startType = 'startProgram'; endType = 'endProgram'; } else { startType = 'startBlock'; endType = 'endBlock'; } programFrame.parentNode = program; programFrame.children = program.body; programFrame.childCount = program.body.length; programFrame.blankChildTextNodes = []; programFrame.actions.push([endType, [program, this.programDepth]]); programFrame.symbols = program['symbols']; for (let i = program.body.length - 1; i >= 0; i--) { programFrame.childIndex = i; this.visit(program.body[i]); } programFrame.actions.push([startType, [program, programFrame.childTemplateCount, programFrame.blankChildTextNodes.reverse()]]); this.popFrame(); this.programDepth--; // Push the completed template into the global actions list if (parentFrame) { parentFrame.childTemplateCount++; } this.actions.push(...programFrame.actions.reverse()); } ElementNode(element) { let parentFrame = this.currentFrame; let elementFrame = this.pushFrame(); elementFrame.parentNode = element; elementFrame.children = element.children; elementFrame.childCount = element.children.length; elementFrame.mustacheCount += element.modifiers.length; elementFrame.blankChildTextNodes = []; elementFrame.symbols = element['symbols'] = parentFrame.symbols.child(element.blockParams); let actionArgs = [element, parentFrame.childIndex, parentFrame.childCount]; elementFrame.actions.push(['closeElement', actionArgs]); for (let i = element.attributes.length - 1; i >= 0; i--) { this.visit(element.attributes[i]); } for (let i = element.children.length - 1; i >= 0; i--) { elementFrame.childIndex = i; this.visit(element.children[i]); } let open = ['openElement', [...actionArgs, elementFrame.mustacheCount, elementFrame.blankChildTextNodes.reverse()]]; elementFrame.actions.push(open); this.popFrame(); // Propagate the element's frame state to the parent frame if (elementFrame.mustacheCount > 0) { parentFrame.mustacheCount++; } parentFrame.childTemplateCount += elementFrame.childTemplateCount; parentFrame.actions.push(...elementFrame.actions); } AttrNode(attr) { if (attr.value.type !== 'TextNode') { this.currentFrame.mustacheCount++; } } TextNode(text) { let frame = this.currentFrame; if (text.chars === '') { frame.blankChildTextNodes.push(domIndexOf(frame.children, text)); } frame.actions.push(['text', [text, frame.childIndex, frame.childCount]]); } BlockStatement(node) { let frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['block', [node, frame.childIndex, frame.childCount]]); if (node.inverse) { this.visit(node.inverse); } if (node.program) { this.visit(node.program); } } PartialStatement(node) { let frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['mustache', [node, frame.childIndex, frame.childCount]]); } CommentStatement(text) { let frame = this.currentFrame; frame.actions.push(['comment', [text, frame.childIndex, frame.childCount]]); } MustacheCommentStatement() { // Intentional empty: Handlebars comments should not affect output. } MustacheStatement(mustache) { let frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['mustache', [mustache, frame.childIndex, frame.childCount]]); } // Frame helpers get currentFrame() { return (0, _util.expect)(this.getCurrentFrame(), "Expected a current frame"); } getCurrentFrame() { return this.frameStack[this.frameStack.length - 1]; } pushFrame() { let frame = new Frame(); this.frameStack.push(frame); return frame; } popFrame() { return this.frameStack.pop(); } } exports.default = TemplateVisitor; // Returns the index of `domNode` in the `nodes` array, skipping // over any nodes which do not represent DOM nodes. function domIndexOf(nodes, domNode) { let index = -1; for (let i = 0; i < nodes.length; i++) { let node = nodes[i]; if (node.type !== 'TextNode' && node.type !== 'ElementNode') { continue; } else { index++; } if (node === domNode) { return index; } } return -1; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90ZW1wbGF0ZS12aXNpdG9yLmpzIl0sIm5hbWVzIjpbIlN5bWJvbFRhYmxlIiwidG9wIiwiUHJvZ3JhbVN5bWJvbFRhYmxlIiwiY2hpbGQiLCJsb2NhbHMiLCJzeW1ib2xzIiwibWFwIiwibmFtZSIsImFsbG9jYXRlIiwiQmxvY2tTeW1ib2xUYWJsZSIsImNvbnN0cnVjdG9yIiwiYXJndW1lbnRzIiwic2l6ZSIsIm5hbWVkIiwiYmxvY2tzIiwiaGFzIiwiX25hbWUiLCJnZXQiLCJnZXRMb2NhbHNNYXAiLCJnZXRFdmFsSW5mbyIsImFsbG9jYXRlTmFtZWQiLCJhbGxvY2F0ZUJsb2NrIiwiYmxvY2siLCJpZGVudGlmaWVyIiwicHVzaCIsInBhcmVudCIsInNsb3RzIiwiaW5kZXhPZiIsInNsb3QiLCJkaWN0IiwiZm9yRWFjaCIsInN5bWJvbCIsIk9iamVjdCIsImtleXMiLCJGcmFtZSIsInBhcmVudE5vZGUiLCJjaGlsZHJlbiIsImNoaWxkSW5kZXgiLCJjaGlsZENvdW50IiwiY2hpbGRUZW1wbGF0ZUNvdW50IiwibXVzdGFjaGVDb3VudCIsImFjdGlvbnMiLCJibGFua0NoaWxkVGV4dE5vZGVzIiwiVGVtcGxhdGVWaXNpdG9yIiwiZnJhbWVTdGFjayIsInByb2dyYW1EZXB0aCIsInZpc2l0Iiwibm9kZSIsInR5cGUiLCJQcm9ncmFtIiwicHJvZ3JhbSIsInBhcmVudEZyYW1lIiwiZ2V0Q3VycmVudEZyYW1lIiwicHJvZ3JhbUZyYW1lIiwicHVzaEZyYW1lIiwiYmxvY2tQYXJhbXMiLCJzdGFydFR5cGUiLCJlbmRUeXBlIiwiYm9keSIsImxlbmd0aCIsImkiLCJyZXZlcnNlIiwicG9wRnJhbWUiLCJFbGVtZW50Tm9kZSIsImVsZW1lbnQiLCJjdXJyZW50RnJhbWUiLCJlbGVtZW50RnJhbWUiLCJtb2RpZmllcnMiLCJhY3Rpb25BcmdzIiwiYXR0cmlidXRlcyIsIm9wZW4iLCJBdHRyTm9kZSIsImF0dHIiLCJ2YWx1ZSIsIlRleHROb2RlIiwidGV4dCIsImZyYW1lIiwiY2hhcnMiLCJkb21JbmRleE9mIiwiQmxvY2tTdGF0ZW1lbnQiLCJpbnZlcnNlIiwiUGFydGlhbFN0YXRlbWVudCIsIkNvbW1lbnRTdGF0ZW1lbnQiLCJNdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQiLCJNdXN0YWNoZVN0YXRlbWVudCIsIm11c3RhY2hlIiwicG9wIiwibm9kZXMiLCJkb21Ob2RlIiwiaW5kZXgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDTyxNQUFNQSxXQUFOLENBQWtCO0FBQ3JCLFdBQU9DLEdBQVAsR0FBYTtBQUNULGVBQU8sSUFBSUMsa0JBQUosRUFBUDtBQUNIO0FBQ0RDLFVBQU1DLE1BQU4sRUFBYztBQUNWLFlBQUlDLFVBQVVELE9BQU9FLEdBQVAsQ0FBV0MsUUFBUSxLQUFLQyxRQUFMLENBQWNELElBQWQsQ0FBbkIsQ0FBZDtBQUNBLGVBQU8sSUFBSUUsZ0JBQUosQ0FBcUIsSUFBckIsRUFBMkJMLE1BQTNCLEVBQW1DQyxPQUFuQyxDQUFQO0FBQ0g7QUFQb0I7UUFBWkwsVyxHQUFBQSxXO0FBU04sTUFBTUUsa0JBQU4sU0FBaUNGLFdBQWpDLENBQTZDO0FBQ2hEVSxrQkFBYztBQUNWLGNBQU0sR0FBR0MsU0FBVDtBQUNBLGFBQUtOLE9BQUwsR0FBZSxFQUFmO0FBQ0EsYUFBS08sSUFBTCxHQUFZLENBQVo7QUFDQSxhQUFLQyxLQUFMLEdBQWEsaUJBQWI7QUFDQSxhQUFLQyxNQUFMLEdBQWMsaUJBQWQ7QUFDSDtBQUNEQyxRQUFJQyxLQUFKLEVBQVc7QUFDUCxlQUFPLEtBQVA7QUFDSDtBQUNEQyxRQUFJRCxLQUFKLEVBQVc7QUFDUCxjQUFNLHdCQUFOO0FBQ0g7QUFDREUsbUJBQWU7QUFDWCxlQUFPLEVBQVA7QUFDSDtBQUNEQyxrQkFBYztBQUNWLGVBQU8sRUFBUDtBQUNIO0FBQ0RDLGtCQUFjYixJQUFkLEVBQW9CO0FBQ2hCLFlBQUlNLFFBQVEsS0FBS0EsS0FBTCxDQUFXTixJQUFYLENBQVo7QUFDQSxZQUFJLENBQUNNLEtBQUwsRUFBWTtBQUNS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QixNQUFNNUIsTUFBMUIsRUFBa0NDLEdBQWxDLEVBQXVDO0FBQ25DLFlBQUliLE9BQU93QyxNQUFNM0IsQ0FBTixDQUFYO0FBQ0EsWUFBSWIsS0FBS0MsSUFBTCxLQUFjLFVBQWQsSUFBNEJELEtBQUtDLElBQUwsS0FBYyxhQUE5QyxFQUE2RDtBQUN6RDtBQUNILFNBRkQsTUFFTztBQUNIeUM7QUFDSDtBQUNELFlBQUkxQyxTQUFTeUMsT0FBYixFQUFzQjtBQUNsQixtQkFBT0MsS0FBUDtBQUNIO0FBQ0o7QUFDRCxXQUFPLENBQUMsQ0FBUjtBQUNIIiwiZmlsZSI6ImxpYi90ZW1wbGF0ZS12aXNpdG9yLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGljdCwgdW5yZWFjaGFibGUsIGV4cGVjdCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuZXhwb3J0IGNsYXNzIFN5bWJvbFRhYmxlIHtcbiAgICBzdGF0aWMgdG9wKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb2dyYW1TeW1ib2xUYWJsZSgpO1xuICAgIH1cbiAgICBjaGlsZChsb2NhbHMpIHtcbiAgICAgICAgbGV0IHN5bWJvbHMgPSBsb2NhbHMubWFwKG5hbWUgPT4gdGhpcy5hbGxvY2F0ZShuYW1lKSk7XG4gICAgICAgIHJldHVybiBuZXcgQmxvY2tTeW1ib2xUYWJsZSh0aGlzLCBsb2NhbHMsIHN5bWJvbHMpO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBQcm9ncmFtU3ltYm9sVGFibGUgZXh0ZW5kcyBTeW1ib2xUYWJsZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuc3ltYm9scyA9IFtdO1xuICAgICAgICB0aGlzLnNpemUgPSAxO1xuICAgICAgICB0aGlzLm5hbWVkID0gZGljdCgpO1xuICAgICAgICB0aGlzLmJsb2NrcyA9IGRpY3QoKTtcbiAgICB9XG4gICAgaGFzKF9uYW1lKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZ2V0KF9uYW1lKSB7XG4gICAgICAgIHRocm93IHVucmVhY2hhYmxlKCk7XG4gICAgfVxuICAgIGdldExvY2Fsc01hcCgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXRFdmFsSW5mbygpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBhbGxvY2F0ZU5hbWVkKG5hbWUpIHtcbiAgICAgICAgbGV0IG5hbWVkID0gdGhpcy5uYW1lZFtuYW1lXTtcbiAgICAgICAgaWYgKCFuYW1lZCkge1xuICAgICAgICAgICAgbmFtZWQgPSB0aGlzLm5hbWVkW25hbWVdID0gdGhpcy5hbGxvY2F0ZShgQCR7bmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmFtZWQ7XG4gICAgfVxuICAgIGFsbG9jYXRlQmxvY2sobmFtZSkge1xuICAgICAgICBsZXQgYmxvY2sgPSB0aGlzLmJsb2Nrc1tuYW1lXTtcbiAgICAgICAgaWYgKCFibG9jaykge1xuICAgICAgICAgICAgYmxvY2sgPSB0aGlzLmJsb2Nrc1tuYW1lXSA9IHRoaXMuYWxsb2NhdGUoYCYke25hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJsb2NrO1xuICAgIH1cbiAgICBhbGxvY2F0ZShpZGVudGlmaWVyKSB7XG4gICAgICAgIHRoaXMuc3ltYm9scy5wdXNoKGlkZW50aWZpZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5zaXplKys7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIEJsb2NrU3ltYm9sVGFibGUgZXh0ZW5kcyBTeW1ib2xUYWJsZSB7XG4gICAgY29uc3RydWN0b3IocGFyZW50LCBzeW1ib2xzLCBzbG90cykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgICAgdGhpcy5zeW1ib2xzID0gc3ltYm9scztcbiAgICAgICAgdGhpcy5zbG90cyA9IHNsb3RzO1xuICAgIH1cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW1ib2xzLmluZGV4T2YobmFtZSkgIT09IC0xIHx8IHRoaXMucGFyZW50LmhhcyhuYW1lKTtcbiAgICB9XG4gICAgZ2V0KG5hbWUpIHtcbiAgICAgICAgbGV0IHNsb3QgPSB0aGlzLnN5bWJvbHMuaW5kZXhPZihuYW1lKTtcbiAgICAgICAgcmV0dXJuIHNsb3QgPT09IC0xID8gdGhpcy5wYXJlbnQuZ2V0KG5hbWUpIDogdGhpcy5zbG90c1tzbG90XTtcbiAgICB9XG4gICAgZ2V0TG9jYWxzTWFwKCkge1xuICAgICAgICBsZXQgZGljdCA9IHRoaXMucGFyZW50LmdldExvY2Fsc01hcCgpO1xuICAgICAgICB0aGlzLnN5bWJvbHMuZm9yRWFjaChzeW1ib2wgPT4gZGljdFtzeW1ib2xdID0gdGhpcy5nZXQoc3ltYm9sKSk7XG4gICAgICAgIHJldHVybiBkaWN0O1xuICAgIH1cbiAgICBnZXRFdmFsSW5mbygpIHtcbiAgICAgICAgbGV0IGxvY2FscyA9IHRoaXMuZ2V0TG9jYWxzTWFwKCk7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhsb2NhbHMpLm1hcChzeW1ib2wgPT4gbG9jYWxzW3N5bWJvbF0pO1xuICAgIH1cbiAgICBhbGxvY2F0ZU5hbWVkKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlTmFtZWQobmFtZSk7XG4gICAgfVxuICAgIGFsbG9jYXRlQmxvY2sobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuYWxsb2NhdGVCbG9jayhuYW1lKTtcbiAgICB9XG4gICAgYWxsb2NhdGUoaWRlbnRpZmllcikge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuYWxsb2NhdGUoaWRlbnRpZmllcik7XG4gICAgfVxufVxuLyoqXG4gKiBUYWtlcyBpbiBhbiBBU1QgYW5kIG91dHB1dHMgYSBsaXN0IG9mIGFjdGlvbnMgdG8gYmUgY29uc3VtZWRcbiAqIGJ5IGEgY29tcGlsZXIuIEZvciBleGFtcGxlLCB0aGUgdGVtcGxhdGVcbiAqXG4gKiAgICAgZm9ve3tiYXJ9fTxkaXY+YmF6PC9kaXY+XG4gKlxuICogcHJvZHVjZXMgdGhlIGFjdGlvbnNcbiAqXG4gKiAgICAgW1snc3RhcnRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlLCAwXV0sXG4gKiAgICAgIFsndGV4dCcsIFt0ZXh0Tm9kZSwgMCwgM11dLFxuICogICAgICBbJ211c3RhY2hlJywgW211c3RhY2hlTm9kZSwgMSwgM11dLFxuICogICAgICBbJ29wZW5FbGVtZW50JywgW2VsZW1lbnROb2RlLCAyLCAzLCAwXV0sXG4gKiAgICAgIFsndGV4dCcsIFt0ZXh0Tm9kZSwgMCwgMV1dLFxuICogICAgICBbJ2Nsb3NlRWxlbWVudCcsIFtlbGVtZW50Tm9kZSwgMiwgM10sXG4gKiAgICAgIFsnZW5kUHJvZ3JhbScsIFtwcm9ncmFtTm9kZV1dXVxuICpcbiAqIFRoaXMgdmlzaXRvciB3YWxrcyB0aGUgQVNUIGRlcHRoIGZpcnN0IGFuZCBiYWNrd2FyZHMuIEFzXG4gKiBhIHJlc3VsdCB0aGUgYm90dG9tLW1vc3QgY2hpbGQgdGVtcGxhdGUgd2lsbCBhcHBlYXIgYXQgdGhlXG4gKiB0b3Agb2YgdGhlIGFjdGlvbnMgbGlzdCB3aGVyZWFzIHRoZSByb290IHRlbXBsYXRlIHdpbGwgYXBwZWFyXG4gKiBhdCB0aGUgYm90dG9tIG9mIHRoZSBsaXN0LiBGb3IgZXhhbXBsZSxcbiAqXG4gKiAgICAgPGRpdj57eyNpZn19Zm9ve3tlbHNlfX1iYXI8Yj48L2I+e3svaWZ9fTwvZGl2PlxuICpcbiAqIHByb2R1Y2VzIHRoZSBhY3Rpb25zXG4gKlxuICogICAgIFtbJ3N0YXJ0UHJvZ3JhbScsIFtwcm9ncmFtTm9kZSwgMF1dLFxuICogICAgICBbJ3RleHQnLCBbdGV4dE5vZGUsIDAsIDIsIDBdXSxcbiAqICAgICAgWydvcGVuRWxlbWVudCcsIFtlbGVtZW50Tm9kZSwgMSwgMiwgMF1dLFxuICogICAgICBbJ2Nsb3NlRWxlbWVudCcsIFtlbGVtZW50Tm9kZSwgMSwgMl1dLFxuICogICAgICBbJ2VuZFByb2dyYW0nLCBbcHJvZ3JhbU5vZGVdXSxcbiAqICAgICAgWydzdGFydFByb2dyYW0nLCBbcHJvZ3JhbU5vZGUsIDBdXSxcbiAqICAgICAgWyd0ZXh0JywgW3RleHROb2RlLCAwLCAxXV0sXG4gKiAgICAgIFsnZW5kUHJvZ3JhbScsIFtwcm9ncmFtTm9kZV1dLFxuICogICAgICBbJ3N0YXJ0UHJvZ3JhbScsIFtwcm9ncmFtTm9kZSwgMl1dLFxuICogICAgICBbJ29wZW5FbGVtZW50JywgW2VsZW1lbnROb2RlLCAwLCAxLCAxXV0sXG4gKiAgICAgIFsnYmxvY2snLCBbYmxvY2tOb2RlLCAwLCAxXV0sXG4gKiAgICAgIFsnY2xvc2VFbGVtZW50JywgW2VsZW1lbnROb2RlLCAwLCAxXV0sXG4gKiAgICAgIFsnZW5kUHJvZ3JhbScsIFtwcm9ncmFtTm9kZV1dXVxuICpcbiAqIFRoZSBzdGF0ZSBvZiB0aGUgdHJhdmVyc2FsIGlzIG1haW50YWluZWQgYnkgYSBzdGFjayBvZiBmcmFtZXMuXG4gKiBXaGVuZXZlciBhIG5vZGUgd2l0aCBjaGlsZHJlbiBpcyBlbnRlcmVkIChlaXRoZXIgYSBQcm9ncmFtTm9kZVxuICogb3IgYW4gRWxlbWVudE5vZGUpIGEgZnJhbWUgaXMgcHVzaGVkIG9udG8gdGhlIHN0YWNrLiBUaGUgZnJhbWVcbiAqIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzdGF0ZSBvZiB0aGUgdHJhdmVyc2FsIG9mIHRoYXRcbiAqIG5vZGUuIEZvciBleGFtcGxlLFxuICpcbiAqICAgLSBpbmRleCBvZiB0aGUgY3VycmVudCBjaGlsZCBub2RlIGJlaW5nIHZpc2l0ZWRcbiAqICAgLSB0aGUgbnVtYmVyIG9mIG11c3RhY2hlcyBjb250YWluZWQgd2l0aGluIGl0cyBjaGlsZCBub2Rlc1xuICogICAtIHRoZSBsaXN0IG9mIGFjdGlvbnMgZ2VuZXJhdGVkIGJ5IGl0cyBjaGlsZCBub2Rlc1xuICovXG5jbGFzcyBGcmFtZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucGFyZW50Tm9kZSA9IG51bGw7XG4gICAgICAgIHRoaXMuY2hpbGRyZW4gPSBudWxsO1xuICAgICAgICB0aGlzLmNoaWxkSW5kZXggPSBudWxsO1xuICAgICAgICB0aGlzLmNoaWxkQ291bnQgPSBudWxsO1xuICAgICAgICB0aGlzLmNoaWxkVGVtcGxhdGVDb3VudCA9IDA7XG4gICAgICAgIHRoaXMubXVzdGFjaGVDb3VudCA9IDA7XG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLmJsYW5rQ2hpbGRUZXh0Tm9kZXMgPSBudWxsO1xuICAgICAgICB0aGlzLnN5bWJvbHMgPSBudWxsO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlbXBsYXRlVmlzaXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZnJhbWVTdGFjayA9IFtdO1xuICAgICAgICB0aGlzLmFjdGlvbnMgPSBbXTtcbiAgICAgICAgdGhpcy5wcm9ncmFtRGVwdGggPSAtMTtcbiAgICB9XG4gICAgdmlzaXQobm9kZSkge1xuICAgICAgICB0aGlzW25vZGUudHlwZV0obm9kZSk7XG4gICAgfVxuICAgIC8vIFRyYXZlcnNhbCBtZXRob2RzXG4gICAgUHJvZ3JhbShwcm9ncmFtKSB7XG4gICAgICAgIHRoaXMucHJvZ3JhbURlcHRoKys7XG4gICAgICAgIGxldCBwYXJlbnRGcmFtZSA9IHRoaXMuZ2V0Q3VycmVudEZyYW1lKCk7XG4gICAgICAgIGxldCBwcm9ncmFtRnJhbWUgPSB0aGlzLnB1c2hGcmFtZSgpO1xuICAgICAgICBpZiAoIXBhcmVudEZyYW1lKSB7XG4gICAgICAgICAgICBwcm9ncmFtWydzeW1ib2xzJ10gPSBTeW1ib2xUYWJsZS50b3AoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb2dyYW1bJ3N5bWJvbHMnXSA9IHBhcmVudEZyYW1lLnN5bWJvbHMuY2hpbGQocHJvZ3JhbS5ibG9ja1BhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0YXJ0VHlwZSwgZW5kVHlwZTtcbiAgICAgICAgaWYgKHRoaXMucHJvZ3JhbURlcHRoID09PSAwKSB7XG4gICAgICAgICAgICBzdGFydFR5cGUgPSAnc3RhcnRQcm9ncmFtJztcbiAgICAgICAgICAgIGVuZFR5cGUgPSAnZW5kUHJvZ3JhbSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGFydFR5cGUgPSAnc3RhcnRCbG9jayc7XG4gICAgICAgICAgICBlbmRUeXBlID0gJ2VuZEJsb2NrJztcbiAgICAgICAgfVxuICAgICAgICBwcm9ncmFtRnJhbWUucGFyZW50Tm9kZSA9IHByb2dyYW07XG4gICAgICAgIHByb2dyYW1GcmFtZS5jaGlsZHJlbiA9IHByb2dyYW0uYm9keTtcbiAgICAgICAgcHJvZ3JhbUZyYW1lLmNoaWxkQ291bnQgPSBwcm9ncmFtLmJvZHkubGVuZ3RoO1xuICAgICAgICBwcm9ncmFtRnJhbWUuYmxhbmtDaGlsZFRleHROb2RlcyA9IFtdO1xuICAgICAgICBwcm9ncmFtRnJhbWUuYWN0aW9ucy5wdXNoKFtlbmRUeXBlLCBbcHJvZ3JhbSwgdGhpcy5wcm9ncmFtRGVwdGhdXSk7XG4gICAgICAgIHByb2dyYW1GcmFtZS5zeW1ib2xzID0gcHJvZ3JhbVsnc3ltYm9scyddO1xuICAgICAgICBmb3IgKGxldCBpID0gcHJvZ3JhbS5ib2R5Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBwcm9ncmFtRnJhbWUuY2hpbGRJbmRleCA9IGk7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KHByb2dyYW0uYm9keVtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvZ3JhbUZyYW1lLmFjdGlvbnMucHVzaChbc3RhcnRUeXBlLCBbcHJvZ3JhbSwgcHJvZ3JhbUZyYW1lLmNoaWxkVGVtcGxhdGVDb3VudCwgcHJvZ3JhbUZyYW1lLmJsYW5rQ2hpbGRUZXh0Tm9kZXMucmV2ZXJzZSgpXV0pO1xuICAgICAgICB0aGlzLnBvcEZyYW1lKCk7XG4gICAgICAgIHRoaXMucHJvZ3JhbURlcHRoLS07XG4gICAgICAgIC8vIFB1c2ggdGhlIGNvbXBsZXRlZCB0ZW1wbGF0ZSBpbnRvIHRoZSBnbG9iYWwgYWN0aW9ucyBsaXN0XG4gICAgICAgIGlmIChwYXJlbnRGcmFtZSkge1xuICAgICAgICAgICAgcGFyZW50RnJhbWUuY2hpbGRUZW1wbGF0ZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hY3Rpb25zLnB1c2goLi4ucHJvZ3JhbUZyYW1lLmFjdGlvbnMucmV2ZXJzZSgpKTtcbiAgICB9XG4gICAgRWxlbWVudE5vZGUoZWxlbWVudCkge1xuICAgICAgICBsZXQgcGFyZW50RnJhbWUgPSB0aGlzLmN1cnJlbnRGcmFtZTtcbiAgICAgICAgbGV0IGVsZW1lbnRGcmFtZSA9IHRoaXMucHVzaEZyYW1lKCk7XG4gICAgICAgIGVsZW1lbnRGcmFtZS5wYXJlbnROb2RlID0gZWxlbWVudDtcbiAgICAgICAgZWxlbWVudEZyYW1lLmNoaWxkcmVuID0gZWxlbWVudC5jaGlsZHJlbjtcbiAgICAgICAgZWxlbWVudEZyYW1lLmNoaWxkQ291bnQgPSBlbGVtZW50LmNoaWxkcmVuLmxlbmd0aDtcbiAgICAgICAgZWxlbWVudEZyYW1lLm11c3RhY2hlQ291bnQgKz0gZWxlbWVudC5tb2RpZmllcnMubGVuZ3RoO1xuICAgICAgICBlbGVtZW50RnJhbWUuYmxhbmtDaGlsZFRleHROb2RlcyA9IFtdO1xuICAgICAgICBlbGVtZW50RnJhbWUuc3ltYm9scyA9IGVsZW1lbnRbJ3N5bWJvbHMnXSA9IHBhcmVudEZyYW1lLnN5bWJvbHMuY2hpbGQoZWxlbWVudC5ibG9ja1BhcmFtcyk7XG4gICAgICAgIGxldCBhY3Rpb25BcmdzID0gW2VsZW1lbnQsIHBhcmVudEZyYW1lLmNoaWxkSW5kZXgsIHBhcmVudEZyYW1lLmNoaWxkQ291bnRdO1xuICAgICAgICBlbGVtZW50RnJhbWUuYWN0aW9ucy5wdXNoKFsnY2xvc2VFbGVtZW50JywgYWN0aW9uQXJnc10pO1xuICAgICAgICBmb3IgKGxldCBpID0gZWxlbWVudC5hdHRyaWJ1dGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KGVsZW1lbnQuYXR0cmlidXRlc1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IGVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGVsZW1lbnRGcmFtZS5jaGlsZEluZGV4ID0gaTtcbiAgICAgICAgICAgIHRoaXMudmlzaXQoZWxlbWVudC5jaGlsZHJlbltpXSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG9wZW4gPSBbJ29wZW5FbGVtZW50JywgWy4uLmFjdGlvbkFyZ3MsIGVsZW1lbnRGcmFtZS5tdXN0YWNoZUNvdW50LCBlbGVtZW50RnJhbWUuYmxhbmtDaGlsZFRleHROb2Rlcy5yZXZlcnNlKCldXTtcbiAgICAgICAgZWxlbWVudEZyYW1lLmFjdGlvbnMucHVzaChvcGVuKTtcbiAgICAgICAgdGhpcy5wb3BGcmFtZSgpO1xuICAgICAgICAvLyBQcm9wYWdhdGUgdGhlIGVsZW1lbnQncyBmcmFtZSBzdGF0ZSB0byB0aGUgcGFyZW50IGZyYW1lXG4gICAgICAgIGlmIChlbGVtZW50RnJhbWUubXVzdGFjaGVDb3VudCA+IDApIHtcbiAgICAgICAgICAgIHBhcmVudEZyYW1lLm11c3RhY2hlQ291bnQrKztcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnRGcmFtZS5jaGlsZFRlbXBsYXRlQ291bnQgKz0gZWxlbWVudEZyYW1lLmNoaWxkVGVtcGxhdGVDb3VudDtcbiAgICAgICAgcGFyZW50RnJhbWUuYWN0aW9ucy5wdXNoKC4uLmVsZW1lbnRGcmFtZS5hY3Rpb25zKTtcbiAgICB9XG4gICAgQXR0ck5vZGUoYXR0cikge1xuICAgICAgICBpZiAoYXR0ci52YWx1ZS50eXBlICE9PSAnVGV4dE5vZGUnKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRGcmFtZS5tdXN0YWNoZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBUZXh0Tm9kZSh0ZXh0KSB7XG4gICAgICAgIGxldCBmcmFtZSA9IHRoaXMuY3VycmVudEZyYW1lO1xuICAgICAgICBpZiAodGV4dC5jaGFycyA9PT0gJycpIHtcbiAgICAgICAgICAgIGZyYW1lLmJsYW5rQ2hpbGRUZXh0Tm9kZXMucHVzaChkb21JbmRleE9mKGZyYW1lLmNoaWxkcmVuLCB0ZXh0KSk7XG4gICAgICAgIH1cbiAgICAgICAgZnJhbWUuYWN0aW9ucy5wdXNoKFsndGV4dCcsIFt0ZXh0LCBmcmFtZS5jaGlsZEluZGV4LCBmcmFtZS5jaGlsZENvdW50XV0pO1xuICAgIH1cblxuICAgIEJsb2NrU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgbGV0IGZyYW1lID0gdGhpcy5jdXJyZW50RnJhbWU7XG4gICAgICAgIGZyYW1lLm11c3RhY2hlQ291bnQrKztcbiAgICAgICAgZnJhbWUuYWN0aW9ucy5wdXNoKFsnYmxvY2snLCBbbm9kZSwgZnJhbWUuY2hpbGRJbmRleCwgZnJhbWUuY2hpbGRDb3VudF1dKTtcbiAgICAgICAgaWYgKG5vZGUuaW52ZXJzZSkge1xuICAgICAgICAgICAgdGhpcy52aXNpdChub2RlLmludmVyc2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLnByb2dyYW0pIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXQobm9kZS5wcm9ncmFtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIFBhcnRpYWxTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICBsZXQgZnJhbWUgPSB0aGlzLmN1cnJlbnRGcmFtZTtcbiAgICAgICAgZnJhbWUubXVzdGFjaGVDb3VudCsrO1xuICAgICAgICBmcmFtZS5hY3Rpb25zLnB1c2goWydtdXN0YWNoZScsIFtub2RlLCBmcmFtZS5jaGlsZEluZGV4LCBmcmFtZS5jaGlsZENvdW50XV0pO1xuICAgIH1cblxuICAgIENvbW1lbnRTdGF0ZW1lbnQodGV4dCkge1xuICAgICAgICBsZXQgZnJhbWUgPSB0aGlzLmN1cnJlbnRGcmFtZTtcbiAgICAgICAgZnJhbWUuYWN0aW9ucy5wdXNoKFsnY29tbWVudCcsIFt0ZXh0LCBmcmFtZS5jaGlsZEluZGV4LCBmcmFtZS5jaGlsZENvdW50XV0pO1xuICAgIH1cblxuICAgIE11c3RhY2hlQ29tbWVudFN0YXRlbWVudCgpIHtcbiAgICAgICAgLy8gSW50ZW50aW9uYWwgZW1wdHk6IEhhbmRsZWJhcnMgY29tbWVudHMgc2hvdWxkIG5vdCBhZmZlY3Qgb3V0cHV0LlxuICAgIH1cblxuICAgIE11c3RhY2hlU3RhdGVtZW50KG11c3RhY2hlKSB7XG4gICAgICAgIGxldCBmcmFtZSA9IHRoaXMuY3VycmVudEZyYW1lO1xuICAgICAgICBmcmFtZS5tdXN0YWNoZUNvdW50Kys7XG4gICAgICAgIGZyYW1lLmFjdGlvbnMucHVzaChbJ211c3RhY2hlJywgW211c3RhY2hlLCBmcmFtZS5jaGlsZEluZGV4LCBmcmFtZS5jaGlsZENvdW50XV0pO1xuICAgIH1cblxuICAgIC8vIEZyYW1lIGhlbHBlcnNcbiAgICBnZXQgY3VycmVudEZyYW1lKCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0KHRoaXMuZ2V0Q3VycmVudEZyYW1lKCksIFwiRXhwZWN0ZWQgYSBjdXJyZW50IGZyYW1lXCIpO1xuICAgIH1cbiAgICBnZXRDdXJyZW50RnJhbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyYW1lU3RhY2tbdGhpcy5mcmFtZVN0YWNrLmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgICBwdXNoRnJhbWUoKSB7XG4gICAgICAgIGxldCBmcmFtZSA9IG5ldyBGcmFtZSgpO1xuICAgICAgICB0aGlzLmZyYW1lU3RhY2sucHVzaChmcmFtZSk7XG4gICAgICAgIHJldHVybiBmcmFtZTtcbiAgICB9XG4gICAgcG9wRnJhbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyYW1lU3RhY2sucG9wKCk7XG4gICAgfVxufVxuLy8gUmV0dXJucyB0aGUgaW5kZXggb2YgYGRvbU5vZGVgIGluIHRoZSBgbm9kZXNgIGFycmF5LCBza2lwcGluZ1xuLy8gb3ZlciBhbnkgbm9kZXMgd2hpY2ggZG8gbm90IHJlcHJlc2VudCBET00gbm9kZXMuXG5mdW5jdGlvbiBkb21JbmRleE9mKG5vZGVzLCBkb21Ob2RlKSB7XG4gICAgbGV0IGluZGV4ID0gLTE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAobm9kZS50eXBlICE9PSAnVGV4dE5vZGUnICYmIG5vZGUudHlwZSAhPT0gJ0VsZW1lbnROb2RlJykge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlID09PSBkb21Ob2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufSJdfQ==