UNPKG

ember-legacy-class-transform

Version:
418 lines (356 loc) 38.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BlockSymbolTable = exports.ProgramSymbolTable = exports.SymbolTable = undefined; var _util = require("@glimmer/util"); var _createClass = function () { 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); } }return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; }; }(); function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults);for (var i = 0; i < keys.length; i++) { var key = keys[i];var value = Object.getOwnPropertyDescriptor(defaults, key);if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } }return obj; } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); }return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var SymbolTable = exports.SymbolTable = function () { function SymbolTable() { _classCallCheck(this, SymbolTable); } SymbolTable.top = function top() { return new ProgramSymbolTable(); }; SymbolTable.prototype.child = function child(locals) { var _this = this; var symbols = locals.map(function (name) { return _this.allocate(name); }); return new BlockSymbolTable(this, locals, symbols); }; return SymbolTable; }(); var ProgramSymbolTable = exports.ProgramSymbolTable = function (_SymbolTable) { _inherits(ProgramSymbolTable, _SymbolTable); function ProgramSymbolTable() { _classCallCheck(this, ProgramSymbolTable); var _this2 = _possibleConstructorReturn(this, _SymbolTable.apply(this, arguments)); _this2.symbols = []; _this2.size = 1; _this2.named = (0, _util.dict)(); _this2.blocks = (0, _util.dict)(); return _this2; } ProgramSymbolTable.prototype.has = function has(_name) { return false; }; ProgramSymbolTable.prototype.get = function get(_name) { throw (0, _util.unreachable)(); }; ProgramSymbolTable.prototype.getLocalsMap = function getLocalsMap() { return {}; }; ProgramSymbolTable.prototype.getEvalInfo = function getEvalInfo() { return []; }; ProgramSymbolTable.prototype.allocateNamed = function allocateNamed(name) { var named = this.named[name]; if (!named) { named = this.named[name] = this.allocate('@' + name); } return named; }; ProgramSymbolTable.prototype.allocateBlock = function allocateBlock(name) { var block = this.blocks[name]; if (!block) { block = this.blocks[name] = this.allocate('&' + name); } return block; }; ProgramSymbolTable.prototype.allocate = function allocate(identifier) { this.symbols.push(identifier); return this.size++; }; return ProgramSymbolTable; }(SymbolTable); var BlockSymbolTable = exports.BlockSymbolTable = function (_SymbolTable2) { _inherits(BlockSymbolTable, _SymbolTable2); function BlockSymbolTable(parent, symbols, slots) { _classCallCheck(this, BlockSymbolTable); var _this3 = _possibleConstructorReturn(this, _SymbolTable2.call(this)); _this3.parent = parent; _this3.symbols = symbols; _this3.slots = slots; return _this3; } BlockSymbolTable.prototype.has = function has(name) { return this.symbols.indexOf(name) !== -1 || this.parent.has(name); }; BlockSymbolTable.prototype.get = function get(name) { var slot = this.symbols.indexOf(name); return slot === -1 ? this.parent.get(name) : this.slots[slot]; }; BlockSymbolTable.prototype.getLocalsMap = function getLocalsMap() { var _this4 = this; var dict = this.parent.getLocalsMap(); this.symbols.forEach(function (symbol) { return dict[symbol] = _this4.get(symbol); }); return dict; }; BlockSymbolTable.prototype.getEvalInfo = function getEvalInfo() { var locals = this.getLocalsMap(); return Object.keys(locals).map(function (symbol) { return locals[symbol]; }); }; BlockSymbolTable.prototype.allocateNamed = function allocateNamed(name) { return this.parent.allocateNamed(name); }; BlockSymbolTable.prototype.allocateBlock = function allocateBlock(name) { return this.parent.allocateBlock(name); }; BlockSymbolTable.prototype.allocate = function allocate(identifier) { return this.parent.allocate(identifier); }; return BlockSymbolTable; }(SymbolTable); /** * 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 */ var Frame = function Frame() { _classCallCheck(this, Frame); 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; }; var TemplateVisitor = function () { function TemplateVisitor() { _classCallCheck(this, TemplateVisitor); this.frameStack = []; this.actions = []; this.programDepth = -1; } TemplateVisitor.prototype.visit = function visit(node) { this[node.type](node); }; // Traversal methods TemplateVisitor.prototype.Program = function Program(program) { var _actions; this.programDepth++; var parentFrame = this.getCurrentFrame(); var programFrame = this.pushFrame(); if (!parentFrame) { program['symbols'] = SymbolTable.top(); } else { program['symbols'] = parentFrame.symbols.child(program.blockParams); } var startType = void 0, endType = void 0; 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 (var 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++; } (_actions = this.actions).push.apply(_actions, programFrame.actions.reverse()); }; TemplateVisitor.prototype.ElementNode = function ElementNode(element) { var _parentFrame$actions; var parentFrame = this.currentFrame; var 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); var actionArgs = [element, parentFrame.childIndex, parentFrame.childCount]; elementFrame.actions.push(['closeElement', actionArgs]); for (var i = element.attributes.length - 1; i >= 0; i--) { this.visit(element.attributes[i]); } for (var _i = element.children.length - 1; _i >= 0; _i--) { elementFrame.childIndex = _i; this.visit(element.children[_i]); } var open = ['openElement', [].concat(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 = parentFrame.actions).push.apply(_parentFrame$actions, elementFrame.actions); }; TemplateVisitor.prototype.AttrNode = function AttrNode(attr) { if (attr.value.type !== 'TextNode') { this.currentFrame.mustacheCount++; } }; TemplateVisitor.prototype.TextNode = function TextNode(text) { var frame = this.currentFrame; if (text.chars === '') { frame.blankChildTextNodes.push(domIndexOf(frame.children, text)); } frame.actions.push(['text', [text, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.BlockStatement = function BlockStatement(node) { var 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); } }; TemplateVisitor.prototype.PartialStatement = function PartialStatement(node) { var frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['mustache', [node, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.CommentStatement = function CommentStatement(text) { var frame = this.currentFrame; frame.actions.push(['comment', [text, frame.childIndex, frame.childCount]]); }; TemplateVisitor.prototype.MustacheCommentStatement = function MustacheCommentStatement() { // Intentional empty: Handlebars comments should not affect output. }; TemplateVisitor.prototype.MustacheStatement = function MustacheStatement(mustache) { var frame = this.currentFrame; frame.mustacheCount++; frame.actions.push(['mustache', [mustache, frame.childIndex, frame.childCount]]); }; // Frame helpers TemplateVisitor.prototype.getCurrentFrame = function getCurrentFrame() { return this.frameStack[this.frameStack.length - 1]; }; TemplateVisitor.prototype.pushFrame = function pushFrame() { var frame = new Frame(); this.frameStack.push(frame); return frame; }; TemplateVisitor.prototype.popFrame = function popFrame() { return this.frameStack.pop(); }; _createClass(TemplateVisitor, [{ key: 'currentFrame', get: function () { return this.getCurrentFrame(); } }]); return TemplateVisitor; }(); // Returns the index of `domNode` in the `nodes` array, skipping // over any nodes which do not represent DOM nodes. exports.default = TemplateVisitor; function domIndexOf(nodes, domNode) { var index = -1; for (var i = 0; i < nodes.length; i++) { var 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90ZW1wbGF0ZS12aXNpdG9yLmpzIl0sIm5hbWVzIjpbImRpY3QiLCJ1bnJlYWNoYWJsZSIsIlN5bWJvbFRhYmxlIiwidG9wIiwiUHJvZ3JhbVN5bWJvbFRhYmxlIiwiY2hpbGQiLCJsb2NhbHMiLCJzeW1ib2xzIiwibWFwIiwiYWxsb2NhdGUiLCJuYW1lIiwiQmxvY2tTeW1ib2xUYWJsZSIsImFyZ3VtZW50cyIsInNpemUiLCJuYW1lZCIsImJsb2NrcyIsImhhcyIsIl9uYW1lIiwiZ2V0IiwiZ2V0TG9jYWxzTWFwIiwiZ2V0RXZhbEluZm8iLCJhbGxvY2F0ZU5hbWVkIiwiYWxsb2NhdGVCbG9jayIsImJsb2NrIiwiaWRlbnRpZmllciIsInB1c2giLCJwYXJlbnQiLCJzbG90cyIsImluZGV4T2YiLCJzbG90IiwiZm9yRWFjaCIsInN5bWJvbCIsIk9iamVjdCIsImtleXMiLCJGcmFtZSIsInBhcmVudE5vZGUiLCJjaGlsZHJlbiIsImNoaWxkSW5kZXgiLCJjaGlsZENvdW50IiwiY2hpbGRUZW1wbGF0ZUNvdW50IiwibXVzdGFjaGVDb3VudCIsImFjdGlvbnMiLCJibGFua0NoaWxkVGV4dE5vZGVzIiwiVGVtcGxhdGVWaXNpdG9yIiwiZnJhbWVTdGFjayIsInByb2dyYW1EZXB0aCIsInZpc2l0Iiwibm9kZSIsInR5cGUiLCJQcm9ncmFtIiwicHJvZ3JhbSIsInBhcmVudEZyYW1lIiwiZ2V0Q3VycmVudEZyYW1lIiwicHJvZ3JhbUZyYW1lIiwicHVzaEZyYW1lIiwiYmxvY2tQYXJhbXMiLCJzdGFydFR5cGUiLCJlbmRUeXBlIiwiYm9keSIsImxlbmd0aCIsImkiLCJyZXZlcnNlIiwicG9wRnJhbWUiLCJFbGVtZW50Tm9kZSIsImVsZW1lbnQiLCJjdXJyZW50RnJhbWUiLCJlbGVtZW50RnJhbWUiLCJtb2RpZmllcnMiLCJhY3Rpb25BcmdzIiwiYXR0cmlidXRlcyIsIm9wZW4iLCJBdHRyTm9kZSIsImF0dHIiLCJ2YWx1ZSIsIlRleHROb2RlIiwidGV4dCIsImZyYW1lIiwiY2hhcnMiLCJkb21JbmRleE9mIiwiQmxvY2tTdGF0ZW1lbnQiLCJpbnZlcnNlIiwiUGFydGlhbFN0YXRlbWVudCIsIkNvbW1lbnRTdGF0ZW1lbnQiLCJNdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQiLCJNdXN0YWNoZVN0YXRlbWVudCIsIm11c3RhY2hlIiwicG9wIiwibm9kZXMiLCJkb21Ob2RlIiwiaW5kZXgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxBQUFTLEFBQU0sQUFBMkIsQUFDMUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBQUEsQUFBYSxnREFBYjsyQkFBQTs4QkFBQTtBQUFBOztnQkFBQSxBQUNXLHFCQUFNLEFBQ1Q7ZUFBTyxJQUFQLEFBQU8sQUFBSSxBQUNkO0FBSEw7OzBCQUFBLEFBSUksdUJBSkosQUFJVSxRQUFRO29CQUNWOztZQUFJLGlCQUFVLEFBQU8sSUFBSSxnQkFBQTttQkFBUSxNQUFBLEFBQUssU0FBYixBQUFRLEFBQWM7QUFBL0MsQUFBYyxBQUNkLFNBRGM7ZUFDUCxJQUFBLEFBQUksaUJBQUosQUFBcUIsTUFBckIsQUFBMkIsUUFBbEMsQUFBTyxBQUFtQyxBQUM3QztBQVBMOztXQUFBO0FBU0E7SUFBQSxBQUFhLDBFQUFiO2tDQUNJOztrQ0FBYzs4QkFBQTs7c0RBQ1YseUJBRFUsQUFDVixBQUFTLEFBQ1Q7O2VBQUEsQUFBSyxVQUFMLEFBQWUsQUFDZjtlQUFBLEFBQUssT0FBTCxBQUFZLEFBQ1o7ZUFBQSxBQUFLLFFBQUwsQUFBYSxBQUNiO2VBQUEsQUFBSyxTQUxLLEFBS1YsQUFBYztlQUNqQjtBQVBMOztpQ0FBQSxBQVFJLG1CQVJKLEFBUVEsT0FBTyxBQUNQO2VBQUEsQUFBTyxBQUNWO0FBVkw7O2lDQUFBLEFBV0ksbUJBWEosQUFXUSxPQUFPLEFBQ1A7Y0FBQSxBQUFNLEFBQ1Q7QUFiTDs7aUNBQUEsQUFjSSx1Q0FBZSxBQUNYO2VBQUEsQUFBTyxBQUNWO0FBaEJMOztpQ0FBQSxBQWlCSSxxQ0FBYyxBQUNWO2VBQUEs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QixVQUFVLEFBQ3hCO1lBQUksUUFBUSxLQUFaLEFBQWlCLEFBQ2pCO2NBQUEsQUFBTSxBQUNOO2NBQUEsQUFBTSxRQUFOLEFBQWMsS0FBSyxDQUFBLEFBQUMsWUFBWSxDQUFBLEFBQUMsVUFBVSxNQUFYLEFBQWlCLFlBQVksTUFBN0QsQUFBbUIsQUFBYSxBQUFtQyxBQUN0RTtBLEFBRUQ7Ozs7OzhCLEFBSUEsNkNBQWtCLEFBQ2Q7ZUFBTyxLQUFBLEFBQUssV0FBVyxLQUFBLEFBQUssV0FBTCxBQUFnQixTQUF2QyxBQUFPLEFBQXlDLEFBQ25EO0E7OzhCLEFBQ0QsaUNBQVksQUFDUjtZQUFJLFFBQVEsSUFBWixBQUFZLEFBQUksQUFDaEI7YUFBQSxBQUFLLFdBQUwsQUFBZ0IsS0FBaEIsQUFBcUIsQUFDckI7ZUFBQSxBQUFPLEFBQ1Y7QTs7OEJBQ0QsQSwrQkFBVyxBQUNQO2VBQU8sS0FBQSxBQUFLLFdBQVosQUFBTyxBQUFnQixBQUMxQjtBOzs7O3lCQWJrQixBQUNmO21CQUFjLEtBQWQsQUFBYyxBQUFLLEFBQ3RCOzs7Ozs7QUFhTDtBQUNBOzs7a0IsQUExSXFCOztBQTJJckIsU0FBQSxBQUFTLFdBQVQsQUFBb0IsT0FBcEIsQUFBMkIsU0FBUyxBQUNoQztRQUFJLFFBQVEsQ0FBWixBQUFhLEFBQ2I7U0FBSyxJQUFJLElBQVQsQUFBYSxHQUFHLElBQUksTUFBcEIsQUFBMEIsUUFBMUIsQUFBa0MsS0FBSyxBQUNuQztZQUFJLE9BQU8sTUFBWCxBQUFXLEFBQU0sQUFDakI7WUFBSSxLQUFBLEFBQUssU0FBTCxBQUFjLGNBQWMsS0FBQSxBQUFLLFNBQXJDLEFBQThDLGVBQWUsQUFDekQ7QUFDSDtBQUZELGVBRU8sQUFDSDtBQUNIO0FBQ0Q7WUFBSSxTQUFKLEFBQWEsU0FBUyxBQUNsQjttQkFBQSxBQUFPLEFBQ1Y7QUFDSjtBQUNEO1dBQU8sQ0FBUCxBQUFRLEFBQ1giLCJmaWxlIjoibGliL3RlbXBsYXRlLXZpc2l0b3IuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBkaWN0LCB1bnJlYWNoYWJsZSwgZXhwZWN0IH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5leHBvcnQgY2xhc3MgU3ltYm9sVGFibGUge1xuICAgIHN0YXRpYyB0b3AoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvZ3JhbVN5bWJvbFRhYmxlKCk7XG4gICAgfVxuICAgIGNoaWxkKGxvY2Fscykge1xuICAgICAgICBsZXQgc3ltYm9scyA9IGxvY2Fscy5tYXAobmFtZSA9PiB0aGlzLmFsbG9jYXRlKG5hbWUpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9ja1N5bWJvbFRhYmxlKHRoaXMsIGxvY2Fscywgc3ltYm9scyk7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIFByb2dyYW1TeW1ib2xUYWJsZSBleHRlbmRzIFN5bWJvbFRhYmxlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zeW1ib2xzID0gW107XG4gICAgICAgIHRoaXMuc2l6ZSA9IDE7XG4gICAgICAgIHRoaXMubmFtZWQgPSBkaWN0KCk7XG4gICAgICAgIHRoaXMuYmxvY2tzID0gZGljdCgpO1xuICAgIH1cbiAgICBoYXMoX25hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBnZXQoX25hbWUpIHtcbiAgICAgICAgdGhyb3cgdW5yZWFjaGFibGUoKTtcbiAgICB9XG4gICAgZ2V0TG9jYWxzTWFwKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldEV2YWxJbmZvKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGFsbG9jYXRlTmFtZWQobmFtZSkge1xuICAgICAgICBsZXQgbmFtZWQgPSB0aGlzLm5hbWVkW25hbWVdO1xuICAgICAgICBpZiAoIW5hbWVkKSB7XG4gICAgICAgICAgICBuYW1lZCA9IHRoaXMubmFtZWRbbmFtZV0gPSB0aGlzLmFsbG9jYXRlKGBAJHtuYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYW1lZDtcbiAgICB9XG4gICAgYWxsb2NhdGVCbG9jayhuYW1lKSB7XG4gICAgICAgIGxldCBibG9jayA9IHRoaXMuYmxvY2tzW25hbWVdO1xuICAgICAgICBpZiAoIWJsb2NrKSB7XG4gICAgICAgICAgICBibG9jayA9IHRoaXMuYmxvY2tzW25hbWVdID0gdGhpcy5hbGxvY2F0ZShgJiR7bmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYmxvY2s7XG4gICAgfVxuICAgIGFsbG9jYXRlKGlkZW50aWZpZXIpIHtcbiAgICAgICAgdGhpcy5zeW1ib2xzLnB1c2goaWRlbnRpZmllcik7XG4gICAgICAgIHJldHVybiB0aGlzLnNpemUrKztcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgQmxvY2tTeW1ib2xUYWJsZSBleHRlbmRzIFN5bWJvbFRhYmxlIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJlbnQsIHN5bWJvbHMsIHNsb3RzKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgICAgICB0aGlzLnN5bWJvbHMgPSBzeW1ib2xzO1xuICAgICAgICB0aGlzLnNsb3RzID0gc2xvdHM7XG4gICAgfVxuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bWJvbHMuaW5kZXhPZihuYW1lKSAhPT0gLTEgfHwgdGhpcy5wYXJlbnQuaGFzKG5hbWUpO1xuICAgIH1cbiAgICBnZXQobmFtZSkge1xuICAgICAgICBsZXQgc2xvdCA9IHRoaXMuc3ltYm9scy5pbmRleE9mKG5hbWUpO1xuICAgICAgICByZXR1cm4gc2xvdCA9PT0gLTEgPyB0aGlzLnBhcmVudC5nZXQobmFtZSkgOiB0aGlzLnNsb3RzW3Nsb3RdO1xuICAgIH1cbiAgICBnZXRMb2NhbHNNYXAoKSB7XG4gICAgICAgIGxldCBkaWN0ID0gdGhpcy5wYXJlbnQuZ2V0TG9jYWxzTWFwKCk7XG4gICAgICAgIHRoaXMuc3ltYm9scy5mb3JFYWNoKHN5bWJvbCA9PiBkaWN0W3N5bWJvbF0gPSB0aGlzLmdldChzeW1ib2wpKTtcbiAgICAgICAgcmV0dXJuIGRpY3Q7XG4gICAgfVxuICAgIGdldEV2YWxJbmZvKCkge1xuICAgICAgICBsZXQgbG9jYWxzID0gdGhpcy5nZXRMb2NhbHNNYXAoKTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGxvY2FscykubWFwKHN5bWJvbCA9PiBsb2NhbHNbc3ltYm9sXSk7XG4gICAgfVxuICAgIGFsbG9jYXRlTmFtZWQobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuYWxsb2NhdGVOYW1lZChuYW1lKTtcbiAgICB9XG4gICAgYWxsb2NhdGVCbG9jayhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5hbGxvY2F0ZUJsb2NrKG5hbWUpO1xuICAgIH1cbiAgICBhbGxvY2F0ZShpZGVudGlmaWVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5hbGxvY2F0ZShpZGVudGlmaWVyKTtcbiAgICB9XG59XG4vKipcbiAqIFRha2VzIGluIGFuIEFTVCBhbmQgb3V0cHV0cyBhIGxpc3Qgb2YgYWN0aW9ucyB0byBiZSBjb25zdW1lZFxuICogYnkgYSBjb21waWxlci4gRm9yIGV4YW1wbGUsIHRoZSB0ZW1wbGF0ZVxuICpcbiAqICAgICBmb297e2Jhcn19PGRpdj5iYXo8L2Rpdj5cbiAqXG4gKiBwcm9kdWNlcyB0aGUgYWN0aW9uc1xuICpcbiAqICAgICBbWydzdGFydFByb2dyYW0nLCBbcHJvZ3JhbU5vZGUsIDBdXSxcbiAqICAgICAgWyd0ZXh0JywgW3RleHROb2RlLCAwLCAzXV0sXG4gKiAgICAgIFsnbXVzdGFjaGUnLCBbbXVzdGFjaGVOb2RlLCAxLCAzXV0sXG4gKiAgICAgIFsnb3BlbkVsZW1lbnQnLCBbZWxlbWVudE5vZGUsIDIsIDMsIDBdXSxcbiAqICAgICAgWyd0ZXh0JywgW3RleHROb2RlLCAwLCAxXV0sXG4gKiAgICAgIFsnY2xvc2VFbGVtZW50JywgW2VsZW1lbnROb2RlLCAyLCAzXSxcbiAqICAgICAgWydlbmRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlXV1dXG4gKlxuICogVGhpcyB2aXNpdG9yIHdhbGtzIHRoZSBBU1QgZGVwdGggZmlyc3QgYW5kIGJhY2t3YXJkcy4gQXNcbiAqIGEgcmVzdWx0IHRoZSBib3R0b20tbW9zdCBjaGlsZCB0ZW1wbGF0ZSB3aWxsIGFwcGVhciBhdCB0aGVcbiAqIHRvcCBvZiB0aGUgYWN0aW9ucyBsaXN0IHdoZXJlYXMgdGhlIHJvb3QgdGVtcGxhdGUgd2lsbCBhcHBlYXJcbiAqIGF0IHRoZSBib3R0b20gb2YgdGhlIGxpc3QuIEZvciBleGFtcGxlLFxuICpcbiAqICAgICA8ZGl2Pnt7I2lmfX1mb297e2Vsc2V9fWJhcjxiPjwvYj57ey9pZn19PC9kaXY+XG4gKlxuICogcHJvZHVjZXMgdGhlIGFjdGlvbnNcbiAqXG4gKiAgICAgW1snc3RhcnRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlLCAwXV0sXG4gKiAgICAgIFsndGV4dCcsIFt0ZXh0Tm9kZSwgMCwgMiwgMF1dLFxuICogICAgICBbJ29wZW5FbGVtZW50JywgW2VsZW1lbnROb2RlLCAxLCAyLCAwXV0sXG4gKiAgICAgIFsnY2xvc2VFbGVtZW50JywgW2VsZW1lbnROb2RlLCAxLCAyXV0sXG4gKiAgICAgIFsnZW5kUHJvZ3JhbScsIFtwcm9ncmFtTm9kZV1dLFxuICogICAgICBbJ3N0YXJ0UHJvZ3JhbScsIFtwcm9ncmFtTm9kZSwgMF1dLFxuICogICAgICBbJ3RleHQnLCBbdGV4dE5vZGUsIDAsIDFdXSxcbiAqICAgICAgWydlbmRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlXV0sXG4gKiAgICAgIFsnc3RhcnRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlLCAyXV0sXG4gKiAgICAgIFsnb3BlbkVsZW1lbnQnLCBbZWxlbWVudE5vZGUsIDAsIDEsIDFdXSxcbiAqICAgICAgWydibG9jaycsIFtibG9ja05vZGUsIDAsIDFdXSxcbiAqICAgICAgWydjbG9zZUVsZW1lbnQnLCBbZWxlbWVudE5vZGUsIDAsIDFdXSxcbiAqICAgICAgWydlbmRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlXV1dXG4gKlxuICogVGhlIHN0YXRlIG9mIHRoZSB0cmF2ZXJzYWwgaXMgbWFpbnRhaW5lZCBieSBhIHN0YWNrIG9mIGZyYW1lcy5cbiAqIFdoZW5ldmVyIGEgbm9kZSB3aXRoIGNoaWxkcmVuIGlzIGVudGVyZWQgKGVpdGhlciBhIFByb2dyYW1Ob2RlXG4gKiBvciBhbiBFbGVtZW50Tm9kZSkgYSBmcmFtZSBpcyBwdXNoZWQgb250byB0aGUgc3RhY2suIFRoZSBmcmFtZVxuICogY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN0YXRlIG9mIHRoZSB0cmF2ZXJzYWwgb2YgdGhhdFxuICogbm9kZS4gRm9yIGV4YW1wbGUsXG4gKlxuICogICAtIGluZGV4IG9mIHRoZSBjdXJyZW50IGNoaWxkIG5vZGUgYmVpbmcgdmlzaXRlZFxuICogICAtIHRoZSBudW1iZXIgb2YgbXVzdGFjaGVzIGNvbnRhaW5lZCB3aXRoaW4gaXRzIGNoaWxkIG5vZGVzXG4gKiAgIC0gdGhlIGxpc3Qgb2YgYWN0aW9ucyBnZW5lcmF0ZWQgYnkgaXRzIGNoaWxkIG5vZGVzXG4gKi9cbmNsYXNzIEZyYW1lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5wYXJlbnROb2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5jaGlsZHJlbiA9IG51bGw7XG4gICAgICAgIHRoaXMuY2hpbGRJbmRleCA9IG51bGw7XG4gICAgICAgIHRoaXMuY2hpbGRDb3VudCA9IG51bGw7XG4gICAgICAgIHRoaXMuY2hpbGRUZW1wbGF0ZUNvdW50ID0gMDtcbiAgICAgICAgdGhpcy5tdXN0YWNoZUNvdW50ID0gMDtcbiAgICAgICAgdGhpcy5hY3Rpb25zID0gW107XG4gICAgICAgIHRoaXMuYmxhbmtDaGlsZFRleHROb2RlcyA9IG51bGw7XG4gICAgICAgIHRoaXMuc3ltYm9scyA9IG51bGw7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVtcGxhdGVWaXNpdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5mcmFtZVN0YWNrID0gW107XG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLnByb2dyYW1EZXB0aCA9IC0xO1xuICAgIH1cbiAgICB2aXNpdChub2RlKSB7XG4gICAgICAgIHRoaXNbbm9kZS50eXBlXShub2RlKTtcbiAgICB9XG4gICAgLy8gVHJhdmVyc2FsIG1ldGhvZHNcbiAgICBQcm9ncmFtKHByb2dyYW0pIHtcbiAgICAgICAgdGhpcy5wcm9ncmFtRGVwdGgrKztcbiAgICAgICAgbGV0IHBhcmVudEZyYW1lID0gdGhpcy5nZXRDdXJyZW50RnJhbWUoKTtcbiAgICAgICAgbGV0IHByb2dyYW1GcmFtZSA9IHRoaXMucHVzaEZyYW1lKCk7XG4gICAgICAgIGlmICghcGFyZW50RnJhbWUpIHtcbiAgICAgICAgICAgIHByb2dyYW1bJ3N5bWJvbHMnXSA9IFN5bWJvbFRhYmxlLnRvcCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHJvZ3JhbVsnc3ltYm9scyddID0gcGFyZW50RnJhbWUuc3ltYm9scy5jaGlsZChwcm9ncmFtLmJsb2NrUGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc3RhcnRUeXBlLCBlbmRUeXBlO1xuICAgICAgICBpZiAodGhpcy5wcm9ncmFtRGVwdGggPT09IDApIHtcbiAgICAgICAgICAgIHN0YXJ0VHlwZSA9ICdzdGFydFByb2dyYW0nO1xuICAgICAgICAgICAgZW5kVHlwZSA9ICdlbmRQcm9ncmFtJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0VHlwZSA9ICdzdGFydEJsb2NrJztcbiAgICAgICAgICAgIGVuZFR5cGUgPSAnZW5kQmxvY2snO1xuICAgICAgICB9XG4gICAgICAgIHByb2dyYW1GcmFtZS5wYXJlbnROb2RlID0gcHJvZ3JhbTtcbiAgICAgICAgcHJvZ3JhbUZyYW1lLmNoaWxkcmVuID0gcHJvZ3JhbS5ib2R5O1xuICAgICAgICBwcm9ncmFtRnJhbWUuY2hpbGRDb3VudCA9IHByb2dyYW0uYm9keS5sZW5ndGg7XG4gICAgICAgIHByb2dyYW1GcmFtZS5ibGFua0NoaWxkVGV4dE5vZGVzID0gW107XG4gICAgICAgIHByb2dyYW1GcmFtZS5hY3Rpb25zLnB1c2goW2VuZFR5cGUsIFtwcm9ncmFtLCB0aGlzLnByb2dyYW1EZXB0aF1dKTtcbiAgICAgICAgcHJvZ3JhbUZyYW1lLnN5bWJvbHMgPSBwcm9ncmFtWydzeW1ib2xzJ107XG4gICAgICAgIGZvciAobGV0IGkgPSBwcm9ncmFtLmJvZHkubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHByb2dyYW1GcmFtZS5jaGlsZEluZGV4ID0gaTtcbiAgICAgICAgICAgIHRoaXMudmlzaXQocHJvZ3JhbS5ib2R5W2ldKTtcbiAgICAgICAgfVxuICAgICAgICBwcm9ncmFtRnJhbWUuYWN0aW9ucy5wdXNoKFtzdGFydFR5cGUsIFtwcm9ncmFtLCBwcm9ncmFtRnJhbWUuY2hpbGRUZW1wbGF0ZUNvdW50LCBwcm9ncmFtRnJhbWUuYmxhbmtDaGlsZFRleHROb2Rlcy5yZXZlcnNlKCldXSk7XG4gICAgICAgIHRoaXMucG9wRnJhbWUoKTtcbiAgICAgICAgdGhpcy5wcm9ncmFtRGVwdGgtLTtcbiAgICAgICAgLy8gUHVzaCB0aGUgY29tcGxldGVkIHRlbXBsYXRlIGludG8gdGhlIGdsb2JhbCBhY3Rpb25zIGxpc3RcbiAgICAgICAgaWYgKHBhcmVudEZyYW1lKSB7XG4gICAgICAgICAgICBwYXJlbnRGcmFtZS5jaGlsZFRlbXBsYXRlQ291bnQrKztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFjdGlvbnMucHVzaCguLi5wcm9ncmFtRnJhbWUuYWN0aW9ucy5yZXZlcnNlKCkpO1xuICAgIH1cbiAgICBFbGVtZW50Tm9kZShlbGVtZW50KSB7XG4gICAgICAgIGxldCBwYXJlbnRGcmFtZSA9IHRoaXMuY3VycmVudEZyYW1lO1xuICAgICAgICBsZXQgZWxlbWVudEZyYW1lID0gdGhpcy5wdXNoRnJhbWUoKTtcbiAgICAgICAgZWxlbWVudEZyYW1lLnBhcmVudE5vZGUgPSBlbGVtZW50O1xuICAgICAgICBlbGVtZW50RnJhbWUuY2hpbGRyZW4gPSBlbGVtZW50LmNoaWxkcmVuO1xuICAgICAgICBlbGVtZW50RnJhbWUuY2hpbGRDb3VudCA9IGVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoO1xuICAgICAgICBlbGVtZW50RnJhbWUubXVzdGFjaGVDb3VudCArPSBlbGVtZW50Lm1vZGlmaWVycy5sZW5ndGg7XG4gICAgICAgIGVsZW1lbnRGcmFtZS5ibGFua0NoaWxkVGV4dE5vZGVzID0gW107XG4gICAgICAgIGVsZW1lbnRGcmFtZS5zeW1ib2xzID0gZWxlbWVudFsnc3ltYm9scyddID0gcGFyZW50RnJhbWUuc3ltYm9scy5jaGlsZChlbGVtZW50LmJsb2NrUGFyYW1zKTtcbiAgICAgICAgbGV0IGFjdGlvbkFyZ3MgPSBbZWxlbWVudCwgcGFyZW50RnJhbWUuY2hpbGRJbmRleCwgcGFyZW50RnJhbWUuY2hpbGRDb3VudF07XG4gICAgICAgIGVsZW1lbnRGcmFtZS5hY3Rpb25zLnB1c2goWydjbG9zZUVsZW1lbnQnLCBhY3Rpb25BcmdzXSk7XG4gICAgICAgIGZvciAobGV0IGkgPSBlbGVtZW50LmF0dHJpYnV0ZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXQoZWxlbWVudC5hdHRyaWJ1dGVzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gZWxlbWVudC5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgZWxlbWVudEZyYW1lLmNoaWxkSW5kZXggPSBpO1xuICAgICAgICAgICAgdGhpcy52aXNpdChlbGVtZW50LmNoaWxkcmVuW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb3BlbiA9IFsnb3BlbkVsZW1lbnQnLCBbLi4uYWN0aW9uQXJncywgZWxlbWVudEZyYW1lLm11c3RhY2hlQ291bnQsIGVsZW1lbnRGcmFtZS5ibGFua0NoaWxkVGV4dE5vZGVzLnJldmVyc2UoKV1dO1xuICAgICAgICBlbGVtZW50RnJhbWUuYWN0aW9ucy5wdXNoKG9wZW4pO1xuICAgICAgICB0aGlzLnBvcEZyYW1lKCk7XG4gICAgICAgIC8vIFByb3BhZ2F0ZSB0aGUgZWxlbWVudCdzIGZyYW1lIHN0YXRlIHRvIHRoZSBwYXJlbnQgZnJhbWVcbiAgICAgICAgaWYgKGVsZW1lbnRGcmFtZS5tdXN0YWNoZUNvdW50ID4gMCkge1xuICAgICAgICAgICAgcGFyZW50RnJhbWUubXVzdGFjaGVDb3VudCsrO1xuICAgICAgICB9XG4gICAgICAgIHBhcmVudEZyYW1lLmNoaWxkVGVtcGxhdGVDb3VudCArPSBlbGVtZW50RnJhbWUuY2hpbGRUZW1wbGF0ZUNvdW50O1xuICAgICAgICBwYXJlbnRGcmFtZS5hY3Rpb25zLnB1c2goLi4uZWxlbWVudEZyYW1lLmFjdGlvbnMpO1xuICAgIH1cbiAgICBBdHRyTm9kZShhdHRyKSB7XG4gICAgICAgIGlmIChhdHRyLnZhbHVlLnR5cGUgIT09ICdUZXh0Tm9kZScpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEZyYW1lLm11c3RhY2hlQ291bnQrKztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIFRleHROb2RlKHRleHQpIHtcbiAgICAgICAgbGV0IGZyYW1lID0gdGhpcy5jdXJyZW50RnJhbWU7XG4gICAgICAgIGlmICh0ZXh0LmNoYXJzID09PSAnJykge1xuICAgICAgICAgICAgZnJhbWUuYmxhbmtDaGlsZFRleHROb2Rlcy5wdXNoKGRvbUluZGV4T2YoZnJhbWUuY2hpbGRyZW4sIHRleHQpKTtcbiAgICAgICAgfVxuICAgICAgICBmcmFtZS5hY3Rpb25zLnB1c2goWyd0ZXh0JywgW3RleHQsIGZyYW1lLmNoaWxkSW5kZXgsIGZyYW1lLmNoaWxkQ291bnRdXSk7XG4gICAgfVxuXG4gICAgQmxvY2tTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICBsZXQgZnJhbWUgPSB0aGlzLmN1cnJlbnRGcmFtZTtcbiAgICAgICAgZnJhbWUubXVzdGFjaGVDb3VudCsrO1xuICAgICAgICBmcmFtZS5hY3Rpb25zLnB1c2goWydibG9jaycsIFtub2RlLCBmcmFtZS5jaGlsZEluZGV4LCBmcmFtZS5jaGlsZENvdW50XV0pO1xuICAgICAgICBpZiAobm9kZS5pbnZlcnNlKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUuaW52ZXJzZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGUucHJvZ3JhbSkge1xuICAgICAgICAgICAgdGhpcy52aXNpdChub2RlLnByb2dyYW0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgUGFydGlhbFN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIGxldCBmcmFtZSA9IHRoaXMuY3VycmVudEZyYW1lO1xuICAgICAgICBmcmFtZS5tdXN0YWNoZUNvdW50Kys7XG4gICAgICAgIGZyYW1lLmFjdGlvbnMucHVzaChbJ211c3RhY2hlJywgW25vZGUsIGZyYW1lLmNoaWxkSW5kZXgsIGZyYW1lLmNoaWxkQ291bnRdXSk7XG4gICAgfVxuXG4gICAgQ29tbWVudFN0YXRlbWVudCh0ZXh0KSB7XG4gICAgICAgIGxldCBmcmFtZSA9IHRoaXMuY3VycmVudEZyYW1lO1xuICAgICAgICBmcmFtZS5hY3Rpb25zLnB1c2goWydjb21tZW50JywgW3RleHQsIGZyYW1lLmNoaWxkSW5kZXgsIGZyYW1lLmNoaWxkQ291bnRdXSk7XG4gICAgfVxuXG4gICAgTXVzdGFjaGVDb21tZW50U3RhdGVtZW50KCkge1xuICAgICAgICAvLyBJbnRlbnRpb25hbCBlbXB0eTogSGFuZGxlYmFycyBjb21tZW50cyBzaG91bGQgbm90IGFmZmVjdCBvdXRwdXQuXG4gICAgfVxuXG4gICAgTXVzdGFjaGVTdGF0ZW1lbnQobXVzdGFjaGUpIHtcbiAgICAgICAgbGV0IGZyYW1lID0gdGhpcy5jdXJyZW50RnJhbWU7XG4gICAgICAgIGZyYW1lLm11c3RhY2hlQ291bnQrKztcbiAgICAgICAgZnJhbWUuYWN0aW9ucy5wdXNoKFsnbXVzdGFjaGUnLCBbbXVzdGFjaGUsIGZyYW1lLmNoaWxkSW5kZXgsIGZyYW1lLmNoaWxkQ291bnRdXSk7XG4gICAgfVxuXG4gICAgLy8gRnJhbWUgaGVscGVyc1xuICAgIGdldCBjdXJyZW50RnJhbWUoKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5nZXRDdXJyZW50RnJhbWUoKSwgXCJFeHBlY3RlZCBhIGN1cnJlbnQgZnJhbWVcIik7XG4gICAgfVxuICAgIGdldEN1cnJlbnRGcmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJhbWVTdGFja1t0aGlzLmZyYW1lU3RhY2subGVuZ3RoIC0gMV07XG4gICAgfVxuICAgIHB1c2hGcmFtZSgpIHtcbiAgICAgICAgbGV0IGZyYW1lID0gbmV3IEZyYW1lKCk7XG4gICAgICAgIHRoaXMuZnJhbWVTdGFjay5wdXNoKGZyYW1lKTtcbiAgICAgICAgcmV0dXJuIGZyYW1lO1xuICAgIH1cbiAgICBwb3BGcmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJhbWVTdGFjay5wb3AoKTtcbiAgICB9XG59XG4vLyBSZXR1cm5zIHRoZSBpbmRleCBvZiBgZG9tTm9kZWAgaW4gdGhlIGBub2Rlc2AgYXJyYXksIHNraXBwaW5nXG4vLyBvdmVyIGFueSBub2RlcyB3aGljaCBkbyBub3QgcmVwcmVzZW50IERPTSBub2Rlcy5cbmZ1bmN0aW9uIGRvbUluZGV4T2Yobm9kZXMsIGRvbU5vZGUpIHtcbiAgICBsZXQgaW5kZXggPSAtMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChub2RlLnR5cGUgIT09ICdUZXh0Tm9kZScgJiYgbm9kZS50eXBlICE9PSAnRWxlbWVudE5vZGUnKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGUgPT09IGRvbU5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59Il19