ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
383 lines (325 loc) • 39.3 kB
JavaScript
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"); } }
import { dict, unreachable } from '@glimmer/util';
export var 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;
}();
export var 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 = dict();
_this2.blocks = dict();
return _this2;
}
ProgramSymbolTable.prototype.has = function has(_name) {
return false;
};
ProgramSymbolTable.prototype.get = function get(_name) {
throw 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);
export var 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.
export 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90ZW1wbGF0ZS12aXNpdG9yLmpzIl0sIm5hbWVzIjpbImRpY3QiLCJ1bnJlYWNoYWJsZSIsIlN5bWJvbFRhYmxlIiwidG9wIiwiUHJvZ3JhbVN5bWJvbFRhYmxlIiwiY2hpbGQiLCJsb2NhbHMiLCJzeW1ib2xzIiwibWFwIiwiYWxsb2NhdGUiLCJuYW1lIiwiQmxvY2tTeW1ib2xUYWJsZSIsImFyZ3VtZW50cyIsInNpemUiLCJuYW1lZCIsImJsb2NrcyIsImhhcyIsIl9uYW1lIiwiZ2V0IiwiZ2V0TG9jYWxzTWFwIiwiZ2V0RXZhbEluZm8iLCJhbGxvY2F0ZU5hbWVkIiwiYWxsb2NhdGVCbG9jayIsImJsb2NrIiwiaWRlbnRpZmllciIsInB1c2giLCJwYXJlbnQiLCJzbG90cyIsImluZGV4T2YiLCJzbG90IiwiZm9yRWFjaCIsInN5bWJvbCIsIk9iamVjdCIsImtleXMiLCJGcmFtZSIsInBhcmVudE5vZGUiLCJjaGlsZHJlbiIsImNoaWxkSW5kZXgiLCJjaGlsZENvdW50IiwiY2hpbGRUZW1wbGF0ZUNvdW50IiwibXVzdGFjaGVDb3VudCIsImFjdGlvbnMiLCJibGFua0NoaWxkVGV4dE5vZGVzIiwiVGVtcGxhdGVWaXNpdG9yIiwiZnJhbWVTdGFjayIsInByb2dyYW1EZXB0aCIsInZpc2l0Iiwibm9kZSIsInR5cGUiLCJQcm9ncmFtIiwicHJvZ3JhbSIsInBhcmVudEZyYW1lIiwiZ2V0Q3VycmVudEZyYW1lIiwicHJvZ3JhbUZyYW1lIiwicHVzaEZyYW1lIiwiYmxvY2tQYXJhbXMiLCJzdGFydFR5cGUiLCJlbmRUeXBlIiwiYm9keSIsImxlbmd0aCIsImkiLCJyZXZlcnNlIiwicG9wRnJhbWUiLCJFbGVtZW50Tm9kZSIsImVsZW1lbnQiLCJjdXJyZW50RnJhbWUiLCJlbGVtZW50RnJhbWUiLCJtb2RpZmllcnMiLCJhY3Rpb25BcmdzIiwiYXR0cmlidXRlcyIsIm9wZW4iLCJBdHRyTm9kZSIsImF0dHIiLCJ2YWx1ZSIsIlRleHROb2RlIiwidGV4dCIsImZyYW1lIiwiY2hhcnMiLCJkb21JbmRleE9mIiwiQmxvY2tTdGF0ZW1lbnQiLCJpbnZlcnNlIiwiUGFydGlhbFN0YXRlbWVudCIsIkNvbW1lbnRTdGF0ZW1lbnQiLCJNdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQiLCJNdXN0YWNoZVN0YXRlbWVudCIsIm11c3RhY2hlIiwicG9wIiwibm9kZXMiLCJkb21Ob2RlIiwiaW5kZXgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSxTQUFTQSxJQUFULEVBQWVDLFdBQWYsUUFBMEMsZUFBMUM7QUFDQSxXQUFhQyxXQUFiO0FBQUE7QUFBQTtBQUFBOztBQUFBLGdCQUNXQyxHQURYLGtCQUNpQjtBQUNULGVBQU8sSUFBSUMsa0JBQUosRUFBUDtBQUNILEtBSEw7O0FBQUEsMEJBSUlDLEtBSkosa0JBSVVDLE1BSlYsRUFJa0I7QUFBQTs7QUFDVixZQUFJQyxVQUFVRCxPQUFPRSxHQUFQLENBQVc7QUFBQSxtQkFBUSxNQUFLQyxRQUFMLENBQWNDLElBQWQsQ0FBUjtBQUFBLFNBQVgsQ0FBZDtBQUNBLGVBQU8sSUFBSUMsZ0JBQUosQ0FBcUIsSUFBckIsRUFBMkJMLE1BQTNCLEVBQW1DQyxPQUFuQyxDQUFQO0FBQ0gsS0FQTDs7QUFBQTtBQUFBO0FBU0EsV0FBYUgsa0JBQWI7QUFBQTs7QUFDSSxrQ0FBYztBQUFBOztBQUFBLHNEQUNWLHlCQUFTUSxTQUFULENBRFU7O0FBRVYsZUFBS0wsT0FBTCxHQUFlLEVBQWY7QUFDQSxlQUFLTSxJQUFMLEdBQVksQ0FBWjtBQUNBLGVBQUtDLEtBQUwsR0FBYWQsTUFBYjtBQUNBLGVBQUtlLE1BQUwsR0FBY2YsTUFBZDtBQUxVO0FBTWI7O0FBUEwsaUNBUUlnQixHQVJKLGdCQVFRQyxLQVJSLEVBUWU7QUFDUCxlQUFPLEtBQVA7QUFDSCxLQVZMOztBQUFBLGlDQVdJQyxHQVhKLGdCQVdRRCxLQVhSLEVBV2U7QUFDUCxjQUFNaEIsYUFBTjtBQUNILEtBYkw7O0FBQUEsaUNBY0lrQixZQWRKLDJCQWNtQjtBQUNYLGVBQU8sRUFB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TCxDQUFnQmUsTUFBaEIsR0FBeUIsQ0FBekMsQ0FBUDtBQUNILEs7OzhCQUNETCxTLHdCQUFZO0FBQ1IsWUFBSXNCLFFBQVEsSUFBSTFDLEtBQUosRUFBWjtBQUNBLGFBQUtVLFVBQUwsQ0FBZ0JuQixJQUFoQixDQUFxQm1ELEtBQXJCO0FBQ0EsZUFBT0EsS0FBUDtBQUNILEs7OzhCQUNEZCxRLHVCQUFXO0FBQ1AsZUFBTyxLQUFLbEIsVUFBTCxDQUFnQjBDLEdBQWhCLEVBQVA7QUFDSCxLOzs7O3lCQWJrQjtBQUNmLG1CQUFjLEtBQUtsQyxlQUFMLEVBQWQ7QUFDSDs7Ozs7QUFhTDtBQUNBOzs7ZUExSXFCVCxlO0FBMklyQixTQUFTbUMsVUFBVCxDQUFvQlMsS0FBcEIsRUFBMkJDLE9BQTNCLEVBQW9DO0FBQ2hDLFFBQUlDLFFBQVEsQ0FBQyxDQUFiO0FBQ0EsU0FBSyxJQUFJN0IsSUFBSSxDQUFiLEVBQWdCQSxJQUFJMkIsTUFBTTVCLE1BQTFCLEVBQWtDQyxHQUFsQyxFQUF1QztBQUNuQyxZQUFJYixPQUFPd0MsTUFBTTNCLENBQU4sQ0FBWDtBQUNBLFlBQUliLEtBQUtDLElBQUwsS0FBYyxVQUFkLElBQTRCRCxLQUFLQyxJQUFMLEtBQWMsYUFBOUMsRUFBNkQ7QUFDekQ7QUFDSCxTQUZELE1BRU87QUFDSHlDO0FBQ0g7QUFDRCxZQUFJMUMsU0FBU3lDLE9BQWIsRUFBc0I7QUFDbEIsbUJBQU9DLEtBQVA7QUFDSDtBQUNKO0FBQ0QsV0FBTyxDQUFDLENBQVI7QUFDSCIsImZpbGUiOiJsaWIvdGVtcGxhdGUtdmlzaXRvci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRpY3QsIHVucmVhY2hhYmxlLCBleHBlY3QgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmV4cG9ydCBjbGFzcyBTeW1ib2xUYWJsZSB7XG4gICAgc3RhdGljIHRvcCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9ncmFtU3ltYm9sVGFibGUoKTtcbiAgICB9XG4gICAgY2hpbGQobG9jYWxzKSB7XG4gICAgICAgIGxldCBzeW1ib2xzID0gbG9jYWxzLm1hcChuYW1lID0+IHRoaXMuYWxsb2NhdGUobmFtZSkpO1xuICAgICAgICByZXR1cm4gbmV3IEJsb2NrU3ltYm9sVGFibGUodGhpcywgbG9jYWxzLCBzeW1ib2xzKTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgUHJvZ3JhbVN5bWJvbFRhYmxlIGV4dGVuZHMgU3ltYm9sVGFibGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnN5bWJvbHMgPSBbXTtcbiAgICAgICAgdGhpcy5zaXplID0gMTtcbiAgICAgICAgdGhpcy5uYW1lZCA9IGRpY3QoKTtcbiAgICAgICAgdGhpcy5ibG9ja3MgPSBkaWN0KCk7XG4gICAgfVxuICAgIGhhcyhfbmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGdldChfbmFtZSkge1xuICAgICAgICB0aHJvdyB1bnJlYWNoYWJsZSgpO1xuICAgIH1cbiAgICBnZXRMb2NhbHNNYXAoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0RXZhbEluZm8oKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgYWxsb2NhdGVOYW1lZChuYW1lKSB7XG4gICAgICAgIGxldCBuYW1lZCA9IHRoaXMubmFtZWRbbmFtZV07XG4gICAgICAgIGlmICghbmFtZWQpIHtcbiAgICAgICAgICAgIG5hbWVkID0gdGhpcy5uYW1lZFtuYW1lXSA9IHRoaXMuYWxsb2NhdGUoYEAke25hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hbWVkO1xuICAgIH1cbiAgICBhbGxvY2F0ZUJsb2NrKG5hbWUpIHtcbiAgICAgICAgbGV0IGJsb2NrID0gdGhpcy5ibG9ja3NbbmFtZV07XG4gICAgICAgIGlmICghYmxvY2spIHtcbiAgICAgICAgICAgIGJsb2NrID0gdGhpcy5ibG9ja3NbbmFtZV0gPSB0aGlzLmFsbG9jYXRlKGAmJHtuYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBibG9jaztcbiAgICB9XG4gICAgYWxsb2NhdGUoaWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLnN5bWJvbHMucHVzaChpZGVudGlmaWVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2l6ZSsrO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBCbG9ja1N5bWJvbFRhYmxlIGV4dGVuZHMgU3ltYm9sVGFibGUge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgc3ltYm9scywgc2xvdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHRoaXMuc3ltYm9scyA9IHN5bWJvbHM7XG4gICAgICAgIHRoaXMuc2xvdHMgPSBzbG90cztcbiAgICB9XG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ltYm9scy5pbmRleE9mKG5hbWUpICE9PSAtMSB8fCB0aGlzLnBhcmVudC5oYXMobmFtZSk7XG4gICAgfVxuICAgIGdldChuYW1lKSB7XG4gICAgICAgIGxldCBzbG90ID0gdGhpcy5zeW1ib2xzLmluZGV4T2YobmFtZSk7XG4gICAgICAgIHJldHVybiBzbG90ID09PSAtMSA/IHRoaXMucGFyZW50LmdldChuYW1lKSA6IHRoaXMuc2xvdHNbc2xvdF07XG4gICAgfVxuICAgIGdldExvY2Fsc01hcCgpIHtcbiAgICAgICAgbGV0IGRpY3QgPSB0aGlzLnBhcmVudC5nZXRMb2NhbHNNYXAoKTtcbiAgICAgICAgdGhpcy5zeW1ib2xzLmZvckVhY2goc3ltYm9sID0+IGRpY3Rbc3ltYm9sXSA9IHRoaXMuZ2V0KHN5bWJvbCkpO1xuICAgICAgICByZXR1cm4gZGljdDtcbiAgICB9XG4gICAgZ2V0RXZhbEluZm8oKSB7XG4gICAgICAgIGxldCBsb2NhbHMgPSB0aGlzLmdldExvY2Fsc01hcCgpO1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMobG9jYWxzKS5tYXAoc3ltYm9sID0+IGxvY2Fsc1tzeW1ib2xdKTtcbiAgICB9XG4gICAgYWxsb2NhdGVOYW1lZChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5hbGxvY2F0ZU5hbWVkKG5hbWUpO1xuICAgIH1cbiAgICBhbGxvY2F0ZUJsb2NrKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlQmxvY2sobmFtZSk7XG4gICAgfVxuICAgIGFsbG9jYXRlKGlkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlKGlkZW50aWZpZXIpO1xuICAgIH1cbn1cbi8qKlxuICogVGFrZXMgaW4gYW4gQVNUIGFuZCBvdXRwdXRzIGEgbGlzdCBvZiBhY3Rpb25zIHRvIGJlIGNvbnN1bWVkXG4gKiBieSBhIGNvbXBpbGVyLiBGb3IgZXhhbXBsZSwgdGhlIHRlbXBsYXRlXG4gKlxuICogICAgIGZvb3t7YmFyfX08ZGl2PmJhejwvZGl2PlxuICpcbiAqIHByb2R1Y2VzIHRoZSBhY3Rpb25zXG4gKlxuICogICAgIFtbJ3N0YXJ0UHJvZ3JhbScsIFtwcm9ncmFtTm9kZSwgMF1dLFxuICogICAgICBbJ3RleHQnLCBbdGV4dE5vZGUsIDAsIDNdXSxcbiAqICAgICAgWydtdXN0YWNoZScsIFttdXN0YWNoZU5vZGUsIDEsIDNdXSxcbiAqICAgICAgWydvcGVuRWxlbWVudCcsIFtlbGVtZW50Tm9kZSwgMiwgMywgMF1dLFxuICogICAgICBbJ3RleHQnLCBbdGV4dE5vZGUsIDAsIDFdXSxcbiAqICAgICAgWydjbG9zZUVsZW1lbnQnLCBbZWxlbWVudE5vZGUsIDIsIDNdLFxuICogICAgICBbJ2VuZFByb2dyYW0nLCBbcHJvZ3JhbU5vZGVdXV1cbiAqXG4gKiBUaGlzIHZpc2l0b3Igd2Fsa3MgdGhlIEFTVCBkZXB0aCBmaXJzdCBhbmQgYmFja3dhcmRzLiBBc1xuICogYSByZXN1bHQgdGhlIGJvdHRvbS1tb3N0IGNoaWxkIHRlbXBsYXRlIHdpbGwgYXBwZWFyIGF0IHRoZVxuICogdG9wIG9mIHRoZSBhY3Rpb25zIGxpc3Qgd2hlcmVhcyB0aGUgcm9vdCB0ZW1wbGF0ZSB3aWxsIGFwcGVhclxuICogYXQgdGhlIGJvdHRvbSBvZiB0aGUgbGlzdC4gRm9yIGV4YW1wbGUsXG4gKlxuICogICAgIDxkaXY+e3sjaWZ9fWZvb3t7ZWxzZX19YmFyPGI+PC9iPnt7L2lmfX08L2Rpdj5cbiAqXG4gKiBwcm9kdWNlcyB0aGUgYWN0aW9uc1xuICpcbiAqICAgICBbWydzdGFydFByb2dyYW0nLCBbcHJvZ3JhbU5vZGUsIDBdXSxcbiAqICAgICAgWyd0ZXh0JywgW3RleHROb2RlLCAwLCAyLCAwXV0sXG4gKiAgICAgIFsnb3BlbkVsZW1lbnQnLCBbZWxlbWVudE5vZGUsIDEsIDIsIDBdXSxcbiAqICAgICAgWydjbG9zZUVsZW1lbnQnLCBbZWxlbWVudE5vZGUsIDEsIDJdXSxcbiAqICAgICAgWydlbmRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlXV0sXG4gKiAgICAgIFsnc3RhcnRQcm9ncmFtJywgW3Byb2dyYW1Ob2RlLCAwXV0sXG4gKiAgICAgIFsndGV4dCcsIFt0ZXh0Tm9kZSwgMCwgMV1dLFxuICogICAgICBbJ2VuZFByb2dyYW0nLCBbcHJvZ3JhbU5vZGVdXSxcbiAqICAgICAgWydzdGFydFByb2dyYW0nLCBbcHJvZ3JhbU5vZGUsIDJdXSxcbiAqICAgICAgWydvcGVuRWxlbWVudCcsIFtlbGVtZW50Tm9kZSwgMCwgMSwgMV1dLFxuICogICAgICBbJ2Jsb2NrJywgW2Jsb2NrTm9kZSwgMCwgMV1dLFxuICogICAgICBbJ2Nsb3NlRWxlbWVudCcsIFtlbGVtZW50Tm9kZSwgMCwgMV1dLFxuICogICAgICBbJ2VuZFByb2dyYW0nLCBbcHJvZ3JhbU5vZGVdXV1cbiAqXG4gKiBUaGUgc3RhdGUgb2YgdGhlIHRyYXZlcnNhbCBpcyBtYWludGFpbmVkIGJ5IGEgc3RhY2sgb2YgZnJhbWVzLlxuICogV2hlbmV2ZXIgYSBub2RlIHdpdGggY2hpbGRyZW4gaXMgZW50ZXJlZCAoZWl0aGVyIGEgUHJvZ3JhbU5vZGVcbiAqIG9yIGFuIEVsZW1lbnROb2RlKSBhIGZyYW1lIGlzIHB1c2hlZCBvbnRvIHRoZSBzdGFjay4gVGhlIGZyYW1lXG4gKiBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3RhdGUgb2YgdGhlIHRyYXZlcnNhbCBvZiB0aGF0XG4gKiBub2RlLiBGb3IgZXhhbXBsZSxcbiAqXG4gKiAgIC0gaW5kZXggb2YgdGhlIGN1cnJlbnQgY2hpbGQgbm9kZSBiZWluZyB2aXNpdGVkXG4gKiAgIC0gdGhlIG51bWJlciBvZiBtdXN0YWNoZXMgY29udGFpbmVkIHdpdGhpbiBpdHMgY2hpbGQgbm9kZXNcbiAqICAgLSB0aGUgbGlzdCBvZiBhY3Rpb25zIGdlbmVyYXRlZCBieSBpdHMgY2hpbGQgbm9kZXNcbiAqL1xuY2xhc3MgRnJhbWUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnBhcmVudE5vZGUgPSBudWxsO1xuICAgICAgICB0aGlzLmNoaWxkcmVuID0gbnVsbDtcbiAgICAgICAgdGhpcy5jaGlsZEluZGV4ID0gbnVsbDtcbiAgICAgICAgdGhpcy5jaGlsZENvdW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5jaGlsZFRlbXBsYXRlQ291bnQgPSAwO1xuICAgICAgICB0aGlzLm11c3RhY2hlQ291bnQgPSAwO1xuICAgICAgICB0aGlzLmFjdGlvbnMgPSBbXTtcbiAgICAgICAgdGhpcy5ibGFua0NoaWxkVGV4dE5vZGVzID0gbnVsbDtcbiAgICAgICAgdGhpcy5zeW1ib2xzID0gbnVsbDtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZW1wbGF0ZVZpc2l0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmZyYW1lU3RhY2sgPSBbXTtcbiAgICAgICAgdGhpcy5hY3Rpb25zID0gW107XG4gICAgICAgIHRoaXMucHJvZ3JhbURlcHRoID0gLTE7XG4gICAgfVxuICAgIHZpc2l0KG5vZGUpIHtcbiAgICAgICAgdGhpc1tub2RlLnR5cGVdKG5vZGUpO1xuICAgIH1cbiAgICAvLyBUcmF2ZXJzYWwgbWV0aG9kc1xuICAgIFByb2dyYW0ocHJvZ3JhbSkge1xuICAgICAgICB0aGlzLnByb2dyYW1EZXB0aCsrO1xuICAgICAgICBsZXQgcGFyZW50RnJhbWUgPSB0aGlzLmdldEN1cnJlbnRGcmFtZSgpO1xuICAgICAgICBsZXQgcHJvZ3JhbUZyYW1lID0gdGhpcy5wdXNoRnJhbWUoKTtcbiAgICAgICAgaWYgKCFwYXJlbnRGcmFtZSkge1xuICAgICAgICAgICAgcHJvZ3JhbVsnc3ltYm9scyddID0gU3ltYm9sVGFibGUudG9wKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9ncmFtWydzeW1ib2xzJ10gPSBwYXJlbnRGcmFtZS5zeW1ib2xzLmNoaWxkKHByb2dyYW0uYmxvY2tQYXJhbXMpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBzdGFydFR5cGUsIGVuZFR5cGU7XG4gICAgICAgIGlmICh0aGlzLnByb2dyYW1EZXB0aCA9PT0gMCkge1xuICAgICAgICAgICAgc3RhcnRUeXBlID0gJ3N0YXJ0UHJvZ3JhbSc7XG4gICAgICAgICAgICBlbmRUeXBlID0gJ2VuZFByb2dyYW0nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhcnRUeXBlID0gJ3N0YXJ0QmxvY2snO1xuICAgICAgICAgICAgZW5kVHlwZSA9ICdlbmRCbG9jayc7XG4gICAgICAgIH1cbiAgICAgICAgcHJvZ3JhbUZyYW1lLnBhcmVudE5vZGUgPSBwcm9ncmFtO1xuICAgICAgICBwcm9ncmFtRnJhbWUuY2hpbGRyZW4gPSBwcm9ncmFtLmJvZHk7XG4gICAgICAgIHByb2dyYW1GcmFtZS5jaGlsZENvdW50ID0gcHJvZ3JhbS5ib2R5Lmxlbmd0aDtcbiAgICAgICAgcHJvZ3JhbUZyYW1lLmJsYW5rQ2hpbGRUZXh0Tm9kZXMgPSBbXTtcbiAgICAgICAgcHJvZ3JhbUZyYW1lLmFjdGlvbnMucHVzaChbZW5kVHlwZSwgW3Byb2dyYW0sIHRoaXMucHJvZ3JhbURlcHRoXV0pO1xuICAgICAgICBwcm9ncmFtRnJhbWUuc3ltYm9scyA9IHByb2dyYW1bJ3N5bWJvbHMnXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IHByb2dyYW0uYm9keS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgcHJvZ3JhbUZyYW1lLmNoaWxkSW5kZXggPSBpO1xuICAgICAgICAgICAgdGhpcy52aXNpdChwcm9ncmFtLmJvZHlbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHByb2dyYW1GcmFtZS5hY3Rpb25zLnB1c2goW3N0YXJ0VHlwZSwgW3Byb2dyYW0sIHByb2dyYW1GcmFtZS5jaGlsZFRlbXBsYXRlQ291bnQsIHByb2dyYW1GcmFtZS5ibGFua0NoaWxkVGV4dE5vZGVzLnJldmVyc2UoKV1dKTtcbiAgICAgICAgdGhpcy5wb3BGcmFtZSgpO1xuICAgICAgICB0aGlzLnByb2dyYW1EZXB0aC0tO1xuICAgICAgICAvLyBQdXNoIHRoZSBjb21wbGV0ZWQgdGVtcGxhdGUgaW50byB0aGUgZ2xvYmFsIGFjdGlvbnMgbGlzdFxuICAgICAgICBpZiAocGFyZW50RnJhbWUpIHtcbiAgICAgICAgICAgIHBhcmVudEZyYW1lLmNoaWxkVGVtcGxhdGVDb3VudCsrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWN0aW9ucy5wdXNoKC4uLnByb2dyYW1GcmFtZS5hY3Rpb25zLnJldmVyc2UoKSk7XG4gICAgfVxuICAgIEVsZW1lbnROb2RlKGVsZW1lbnQpIHtcbiAgICAgICAgbGV0IHBhcmVudEZyYW1lID0gdGhpcy5jdXJyZW50RnJhbWU7XG4gICAgICAgIGxldCBlbGVtZW50RnJhbWUgPSB0aGlzLnB1c2hGcmFtZSgpO1xuICAgICAgICBlbGVtZW50RnJhbWUucGFyZW50Tm9kZSA9IGVsZW1lbnQ7XG4gICAgICAgIGVsZW1lbnRGcmFtZS5jaGlsZHJlbiA9IGVsZW1lbnQuY2hpbGRyZW47XG4gICAgICAgIGVsZW1lbnRGcmFtZS5jaGlsZENvdW50ID0gZWxlbWVudC5jaGlsZHJlbi5sZW5ndGg7XG4gICAgICAgIGVsZW1lbnRGcmFtZS5tdXN0YWNoZUNvdW50ICs9IGVsZW1lbnQubW9kaWZpZXJzLmxlbmd0aDtcbiAgICAgICAgZWxlbWVudEZyYW1lLmJsYW5rQ2hpbGRUZXh0Tm9kZXMgPSBbXTtcbiAgICAgICAgZWxlbWVudEZyYW1lLnN5bWJvbHMgPSBlbGVtZW50WydzeW1ib2xzJ10gPSBwYXJlbnRGcmFtZS5zeW1ib2xzLmNoaWxkKGVsZW1lbnQuYmxvY2tQYXJhbXMpO1xuICAgICAgICBsZXQgYWN0aW9uQXJncyA9IFtlbGVtZW50LCBwYXJlbnRGcmFtZS5jaGlsZEluZGV4LCBwYXJlbnRGcmFtZS5jaGlsZENvdW50XTtcbiAgICAgICAgZWxlbWVudEZyYW1lLmFjdGlvbnMucHVzaChbJ2Nsb3NlRWxlbWVudCcsIGFjdGlvbkFyZ3NdKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IGVsZW1lbnQuYXR0cmlidXRlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgdGhpcy52aXNpdChlbGVtZW50LmF0dHJpYnV0ZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSBlbGVtZW50LmNoaWxkcmVuLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBlbGVtZW50RnJhbWUuY2hpbGRJbmRleCA9IGk7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KGVsZW1lbnQuY2hpbGRyZW5baV0pO1xuICAgICAgICB9XG4gICAgICAgIGxldCBvcGVuID0gWydvcGVuRWxlbWVudCcsIFsuLi5hY3Rpb25BcmdzLCBlbGVtZW50RnJhbWUubXVzdGFjaGVDb3VudCwgZWxlbWVudEZyYW1lLmJsYW5rQ2hpbGRUZXh0Tm9kZXMucmV2ZXJzZSgpXV07XG4gICAgICAgIGVsZW1lbnRGcmFtZS5hY3Rpb25zLnB1c2gob3Blbik7XG4gICAgICAgIHRoaXMucG9wRnJhbWUoKTtcbiAgICAgICAgLy8gUHJvcGFnYXRlIHRoZSBlbGVtZW50J3MgZnJhbWUgc3RhdGUgdG8gdGhlIHBhcmVudCBmcmFtZVxuICAgICAgICBpZiAoZWxlbWVudEZyYW1lLm11c3RhY2hlQ291bnQgPiAwKSB7XG4gICAgICAgICAgICBwYXJlbnRGcmFtZS5tdXN0YWNoZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50RnJhbWUuY2hpbGRUZW1wbGF0ZUNvdW50ICs9IGVsZW1lbnRGcmFtZS5jaGlsZFRlbXBsYXRlQ291bnQ7XG4gICAgICAgIHBhcmVudEZyYW1lLmFjdGlvbnMucHVzaCguLi5lbGVtZW50RnJhbWUuYWN0aW9ucyk7XG4gICAgfVxuICAgIEF0dHJOb2RlKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIudmFsdWUudHlwZSAhPT0gJ1RleHROb2RlJykge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50RnJhbWUubXVzdGFjaGVDb3VudCsrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgVGV4dE5vZGUodGV4dCkge1xuICAgICAgICBsZXQgZnJhbWUgPSB0aGlzLmN1cnJlbnRGcmFtZTtcbiAgICAgICAgaWYgKHRleHQuY2hhcnMgPT09ICcnKSB7XG4gICAgICAgICAgICBmcmFtZS5ibGFua0NoaWxkVGV4dE5vZGVzLnB1c2goZG9tSW5kZXhPZihmcmFtZS5jaGlsZHJlbiwgdGV4dCkpO1xuICAgICAgICB9XG4gICAgICAgIGZyYW1lLmFjdGlvbnMucHVzaChbJ3RleHQnLCBbdGV4dCwgZnJhbWUuY2hpbGRJbmRleCwgZnJhbWUuY2hpbGRDb3VudF1dKTtcbiAgICB9XG5cbiAgICBCbG9ja1N0YXRlbWVudChub2RlKSB7XG4gICAgICAgIGxldCBmcmFtZSA9IHRoaXMuY3VycmVudEZyYW1lO1xuICAgICAgICBmcmFtZS5tdXN0YWNoZUNvdW50Kys7XG4gICAgICAgIGZyYW1lLmFjdGlvbnMucHVzaChbJ2Jsb2NrJywgW25vZGUsIGZyYW1lLmNoaWxkSW5kZXgsIGZyYW1lLmNoaWxkQ291bnRdXSk7XG4gICAgICAgIGlmIChub2RlLmludmVyc2UpIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXQobm9kZS5pbnZlcnNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5wcm9ncmFtKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUucHJvZ3JhbSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBQYXJ0aWFsU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgbGV0IGZyYW1lID0gdGhpcy5jdXJyZW50RnJhbWU7XG4gICAgICAgIGZyYW1lLm11c3RhY2hlQ291bnQrKztcbiAgICAgICAgZnJhbWUuYWN0aW9ucy5wdXNoKFsnbXVzdGFjaGUnLCBbbm9kZSwgZnJhbWUuY2hpbGRJbmRleCwgZnJhbWUuY2hpbGRDb3VudF1dKTtcbiAgICB9XG5cbiAgICBDb21tZW50U3RhdGVtZW50KHRleHQpIHtcbiAgICAgICAgbGV0IGZyYW1lID0gdGhpcy5jdXJyZW50RnJhbWU7XG4gICAgICAgIGZyYW1lLmFjdGlvbnMucHVzaChbJ2NvbW1lbnQnLCBbdGV4dCwgZnJhbWUuY2hpbGRJbmRleCwgZnJhbWUuY2hpbGRDb3VudF1dKTtcbiAgICB9XG5cbiAgICBNdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQoKSB7XG4gICAgICAgIC8vIEludGVudGlvbmFsIGVtcHR5OiBIYW5kbGViYXJzIGNvbW1lbnRzIHNob3VsZCBub3QgYWZmZWN0IG91dHB1dC5cbiAgICB9XG5cbiAgICBNdXN0YWNoZVN0YXRlbWVudChtdXN0YWNoZSkge1xuICAgICAgICBsZXQgZnJhbWUgPSB0aGlzLmN1cnJlbnRGcmFtZTtcbiAgICAgICAgZnJhbWUubXVzdGFjaGVDb3VudCsrO1xuICAgICAgICBmcmFtZS5hY3Rpb25zLnB1c2goWydtdXN0YWNoZScsIFttdXN0YWNoZSwgZnJhbWUuY2hpbGRJbmRleCwgZnJhbWUuY2hpbGRDb3VudF1dKTtcbiAgICB9XG5cbiAgICAvLyBGcmFtZSBoZWxwZXJzXG4gICAgZ2V0IGN1cnJlbnRGcmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIGV4cGVjdCh0aGlzLmdldEN1cnJlbnRGcmFtZSgpLCBcIkV4cGVjdGVkIGEgY3VycmVudCBmcmFtZVwiKTtcbiAgICB9XG4gICAgZ2V0Q3VycmVudEZyYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZVN0YWNrW3RoaXMuZnJhbWVTdGFjay5sZW5ndGggLSAxXTtcbiAgICB9XG4gICAgcHVzaEZyYW1lKCkge1xuICAgICAgICBsZXQgZnJhbWUgPSBuZXcgRnJhbWUoKTtcbiAgICAgICAgdGhpcy5mcmFtZVN0YWNrLnB1c2goZnJhbWUpO1xuICAgICAgICByZXR1cm4gZnJhbWU7XG4gICAgfVxuICAgIHBvcEZyYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZVN0YWNrLnBvcCgpO1xuICAgIH1cbn1cbi8vIFJldHVybnMgdGhlIGluZGV4IG9mIGBkb21Ob2RlYCBpbiB0aGUgYG5vZGVzYCBhcnJheSwgc2tpcHBpbmdcbi8vIG92ZXIgYW55IG5vZGVzIHdoaWNoIGRvIG5vdCByZXByZXNlbnQgRE9NIG5vZGVzLlxuZnVuY3Rpb24gZG9tSW5kZXhPZihub2RlcywgZG9tTm9kZSkge1xuICAgIGxldCBpbmRleCA9IC0xO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgaWYgKG5vZGUudHlwZSAhPT0gJ1RleHROb2RlJyAmJiBub2RlLnR5cGUgIT09ICdFbGVtZW50Tm9kZScpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZSA9PT0gZG9tTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn0iXX0=