UNPKG

ember-legacy-class-transform

Version:
361 lines (314 loc) 44.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HandlebarsNodeVisitors = undefined; var _builders = require("../builders"); var _builders2 = _interopRequireDefault(_builders); var _utils = require("../utils"); var _parser = require("../parser"); var _syntaxError = require("../errors/syntax-error"); var _syntaxError2 = _interopRequireDefault(_syntaxError); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 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); } var HandlebarsNodeVisitors = exports.HandlebarsNodeVisitors = function (_Parser) { _inherits(HandlebarsNodeVisitors, _Parser); function HandlebarsNodeVisitors() { _classCallCheck(this, HandlebarsNodeVisitors); return _possibleConstructorReturn(this, _Parser.apply(this, arguments)); } HandlebarsNodeVisitors.prototype.Program = function Program(program) { var body = []; var node = _builders2.default.program(body, program.blockParams, program.loc); var i = void 0, l = program.body.length; this.elementStack.push(node); if (l === 0) { return this.elementStack.pop(); } for (i = 0; i < l; i++) { this.acceptNode(program.body[i]); } // Ensure that that the element stack is balanced properly. var poppedNode = this.elementStack.pop(); if (poppedNode !== node) { var elementNode = poppedNode; throw new _syntaxError2.default("Unclosed element `" + elementNode.tag + "` (on line " + elementNode.loc.start.line + ").", elementNode.loc); } return node; }; HandlebarsNodeVisitors.prototype.BlockStatement = function BlockStatement(block) { if (this.tokenizer['state'] === 'comment') { this.appendToCommentData(this.sourceForNode(block)); return; } if (this.tokenizer['state'] !== 'comment' && this.tokenizer['state'] !== 'data' && this.tokenizer['state'] !== 'beforeData') { throw new _syntaxError2.default("A block may only be used inside an HTML element or another block.", block.loc); } var _acceptCallNodes = acceptCallNodes(this, block), path = _acceptCallNodes.path, params = _acceptCallNodes.params, hash = _acceptCallNodes.hash; var program = this.Program(block.program); var inverse = block.inverse ? this.Program(block.inverse) : null; var node = _builders2.default.block(path, params, hash, program, inverse, block.loc); var parentProgram = this.currentElement(); (0, _utils.appendChild)(parentProgram, node); }; HandlebarsNodeVisitors.prototype.MustacheStatement = function MustacheStatement(rawMustache) { var tokenizer = this.tokenizer; if (tokenizer['state'] === 'comment') { this.appendToCommentData(this.sourceForNode(rawMustache)); return; } var mustache = void 0; var escaped = rawMustache.escaped, loc = rawMustache.loc; if (rawMustache.path.type.match(/Literal$/)) { mustache = { type: 'MustacheStatement', path: this.acceptNode(rawMustache.path), params: [], hash: _builders2.default.hash(), escaped: escaped, loc: loc }; } else { var _acceptCallNodes2 = acceptCallNodes(this, rawMustache), path = _acceptCallNodes2.path, params = _acceptCallNodes2.params, hash = _acceptCallNodes2.hash; mustache = _builders2.default.mustache(path, params, hash, !escaped, loc); } switch (tokenizer.state) { // Tag helpers case "tagName": addElementModifier(this.currentStartTag, mustache); tokenizer.state = "beforeAttributeName"; break; case "beforeAttributeName": addElementModifier(this.currentStartTag, mustache); break; case "attributeName": case "afterAttributeName": this.beginAttributeValue(false); this.finishAttributeValue(); addElementModifier(this.currentStartTag, mustache); tokenizer.state = "beforeAttributeName"; break; case "afterAttributeValueQuoted": addElementModifier(this.currentStartTag, mustache); tokenizer.state = "beforeAttributeName"; break; // Attribute values case "beforeAttributeValue": appendDynamicAttributeValuePart(this.currentAttribute, mustache); tokenizer.state = 'attributeValueUnquoted'; break; case "attributeValueDoubleQuoted": case "attributeValueSingleQuoted": case "attributeValueUnquoted": appendDynamicAttributeValuePart(this.currentAttribute, mustache); break; // TODO: Only append child when the tokenizer state makes // sense to do so, otherwise throw an error. default: (0, _utils.appendChild)(this.currentElement(), mustache); } return mustache; }; HandlebarsNodeVisitors.prototype.ContentStatement = function ContentStatement(content) { updateTokenizerLocation(this.tokenizer, content); this.tokenizer.tokenizePart(content.value); this.tokenizer.flushData(); }; HandlebarsNodeVisitors.prototype.CommentStatement = function CommentStatement(rawComment) { var tokenizer = this.tokenizer; if (tokenizer.state === 'comment') { this.appendToCommentData(this.sourceForNode(rawComment)); return null; } var value = rawComment.value, loc = rawComment.loc; var comment = _builders2.default.mustacheComment(value, loc); switch (tokenizer.state) { case "beforeAttributeName": this.currentStartTag.comments.push(comment); break; case 'beforeData': case 'data': (0, _utils.appendChild)(this.currentElement(), comment); break; default: throw new _syntaxError2.default("Using a Handlebars comment when in the `" + tokenizer.state + "` state is not supported: \"" + comment.value + "\" on line " + loc.start.line + ":" + loc.start.column, rawComment.loc); } return comment; }; HandlebarsNodeVisitors.prototype.PartialStatement = function PartialStatement(partial) { var loc = partial.loc; throw new _syntaxError2.default("Handlebars partials are not supported: \"" + this.sourceForNode(partial, partial.name) + "\" at L" + loc.start.line + ":C" + loc.start.column, partial.loc); }; HandlebarsNodeVisitors.prototype.PartialBlockStatement = function PartialBlockStatement(partialBlock) { var loc = partialBlock.loc; throw new _syntaxError2.default("Handlebars partial blocks are not supported: \"" + this.sourceForNode(partialBlock, partialBlock.name) + "\" at L" + loc.start.line + ":C" + loc.start.column, partialBlock.loc); }; HandlebarsNodeVisitors.prototype.Decorator = function Decorator(decorator) { var loc = decorator.loc; throw new _syntaxError2.default("Handlebars decorators are not supported: \"" + this.sourceForNode(decorator, decorator.path) + "\" at L" + loc.start.line + ":C" + loc.start.column, decorator.loc); }; HandlebarsNodeVisitors.prototype.DecoratorBlock = function DecoratorBlock(decoratorBlock) { var loc = decoratorBlock.loc; throw new _syntaxError2.default("Handlebars decorator blocks are not supported: \"" + this.sourceForNode(decoratorBlock, decoratorBlock.path) + "\" at L" + loc.start.line + ":C" + loc.start.column, decoratorBlock.loc); }; HandlebarsNodeVisitors.prototype.SubExpression = function SubExpression(sexpr) { var _acceptCallNodes3 = acceptCallNodes(this, sexpr), path = _acceptCallNodes3.path, params = _acceptCallNodes3.params, hash = _acceptCallNodes3.hash; return _builders2.default.sexpr(path, params, hash, sexpr.loc); }; HandlebarsNodeVisitors.prototype.PathExpression = function PathExpression(path) { var original = path.original, loc = path.loc; var parts = void 0; if (original.indexOf('/') !== -1) { if (original.slice(0, 2) === './') { throw new _syntaxError2.default("Using \"./\" is not supported in Glimmer and unnecessary: \"" + path.original + "\" on line " + loc.start.line + ".", path.loc); } if (original.slice(0, 3) === '../') { throw new _syntaxError2.default("Changing context using \"../\" is not supported in Glimmer: \"" + path.original + "\" on line " + loc.start.line + ".", path.loc); } if (original.indexOf('.') !== -1) { throw new _syntaxError2.default("Mixing '.' and '/' in paths is not supported in Glimmer; use only '.' to separate property paths: \"" + path.original + "\" on line " + loc.start.line + ".", path.loc); } parts = [path.parts.join('/')]; } else { parts = path.parts; } var thisHead = false; // This is to fix a bug in the Handlebars AST where the path expressions in // `{{this.foo}}` (and similarly `{{foo-bar this.foo named=this.foo}}` etc) // are simply turned into `{{foo}}`. The fix is to push it back onto the // parts array and let the runtime see the difference. However, we cannot // simply use the string `this` as it means literally the property called // "this" in the current context (it can be expressed in the syntax as // `{{[this]}}`, where the square bracket are generally for this kind of // escaping – such as `{{foo.["bar.baz"]}}` would mean lookup a property // named literally "bar.baz" on `this.foo`). By convention, we use `null` // for this purpose. if (original.match(/^this(\..+)?$/)) { thisHead = true; } return { type: 'PathExpression', original: path.original, this: thisHead, parts: parts, data: path.data, loc: path.loc }; }; HandlebarsNodeVisitors.prototype.Hash = function Hash(hash) { var pairs = []; for (var i = 0; i < hash.pairs.length; i++) { var pair = hash.pairs[i]; pairs.push(_builders2.default.pair(pair.key, this.acceptNode(pair.value), pair.loc)); } return _builders2.default.hash(pairs, hash.loc); }; HandlebarsNodeVisitors.prototype.StringLiteral = function StringLiteral(string) { return _builders2.default.literal('StringLiteral', string.value, string.loc); }; HandlebarsNodeVisitors.prototype.BooleanLiteral = function BooleanLiteral(boolean) { return _builders2.default.literal('BooleanLiteral', boolean.value, boolean.loc); }; HandlebarsNodeVisitors.prototype.NumberLiteral = function NumberLiteral(number) { return _builders2.default.literal('NumberLiteral', number.value, number.loc); }; HandlebarsNodeVisitors.prototype.UndefinedLiteral = function UndefinedLiteral(undef) { return _builders2.default.literal('UndefinedLiteral', undefined, undef.loc); }; HandlebarsNodeVisitors.prototype.NullLiteral = function NullLiteral(nul) { return _builders2.default.literal('NullLiteral', null, nul.loc); }; return HandlebarsNodeVisitors; }(_parser.Parser); function calculateRightStrippedOffsets(original, value) { if (value === '') { // if it is empty, just return the count of newlines // in original return { lines: original.split("\n").length - 1, columns: 0 }; } // otherwise, return the number of newlines prior to // `value` var difference = original.split(value)[0]; var lines = difference.split(/\n/); var lineCount = lines.length - 1; return { lines: lineCount, columns: lines[lineCount].length }; } function updateTokenizerLocation(tokenizer, content) { var line = content.loc.start.line; var column = content.loc.start.column; var offsets = calculateRightStrippedOffsets(content.original, content.value); line = line + offsets.lines; if (offsets.lines) { column = offsets.columns; } else { column = column + offsets.columns; } tokenizer.line = line; tokenizer.column = column; } function acceptCallNodes(compiler, node) { var path = compiler.PathExpression(node.path); var params = node.params ? node.params.map(function (e) { return compiler.acceptNode(e); }) : []; var hash = node.hash ? compiler.Hash(node.hash) : _builders2.default.hash(); return { path: path, params: params, hash: hash }; } function addElementModifier(element, mustache) { var path = mustache.path, params = mustache.params, hash = mustache.hash, loc = mustache.loc; if ((0, _utils.isLiteral)(path)) { var _modifier = "{{" + (0, _utils.printLiteral)(path) + "}}"; var tag = "<" + element.name + " ... " + _modifier + " ..."; throw new _syntaxError2.default("In " + tag + ", " + _modifier + " is not a valid modifier: \"" + path.original + "\" on line " + (loc && loc.start.line) + ".", mustache.loc); } var modifier = _builders2.default.elementModifier(path, params, hash, loc); element.modifiers.push(modifier); } function appendDynamicAttributeValuePart(attribute, part) { attribute.isDynamic = true; attribute.parts.push(part); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9wYXJzZXIvaGFuZGxlYmFycy1ub2RlLXZpc2l0b3JzLmpzIl0sIm5hbWVzIjpbImIiLCJhcHBlbmRDaGlsZCIsImlzTGl0ZXJhbCIsInByaW50TGl0ZXJhbCIsIlBhcnNlciIsIlN5bnRheEVycm9yIiwiSGFuZGxlYmFyc05vZGVWaXNpdG9ycyIsIlByb2dyYW0iLCJwcm9ncmFtIiwiYm9keSIsIm5vZGUiLCJibG9ja1BhcmFtcyIsImxvYyIsImkiLCJsIiwibGVuZ3RoIiwiZWxlbWVudFN0YWNrIiwicHVzaCIsInBvcCIsImFjY2VwdE5vZGUiLCJwb3BwZWROb2RlIiwiZWxlbWVudE5vZGUiLCJ0YWciLCJzdGFydCIsImxpbmUiLCJCbG9ja1N0YXRlbWVudCIsImJsb2NrIiwidG9rZW5pemVyIiwiYXBwZW5kVG9Db21tZW50RGF0YSIsInNvdXJjZUZvck5vZGUiLCJhY2NlcHRDYWxsTm9kZXMiLCJwYXRoIiwicGFyYW1zIiwiaGFzaCIsImludmVyc2UiLCJwYXJlbnRQcm9ncmFtIiwiY3VycmVudEVsZW1lbnQiLCJNdXN0YWNoZVN0YXRlbWVudCIsInJhd011c3RhY2hlIiwibXVzdGFjaGUiLCJlc2NhcGVkIiwidHlwZSIsIm1hdGNoIiwic3RhdGUiLCJhZGRFbGVtZW50TW9kaWZpZXIiLCJjdXJyZW50U3RhcnRUYWciLCJiZWdpbkF0dHJpYnV0ZVZhbHVlIiwiZmluaXNoQXR0cmlidXRlVmFsdWUiLCJhcHBlbmREeW5hbWljQXR0cmlidXRlVmFsdWVQYXJ0IiwiY3VycmVudEF0dHJpYnV0ZSIsIkNvbnRlbnRTdGF0ZW1lbnQiLCJjb250ZW50IiwidXBkYXRlVG9rZW5pemVyTG9jYXRpb24iLCJ0b2tlbml6ZVBhcnQiLCJ2YWx1ZSIsImZsdXNoRGF0YSIsIkNvbW1lbnRTdGF0ZW1lbnQiLCJyYXdDb21tZW50IiwiY29tbWVudCIsIm11c3RhY2hlQ29tbWVudCIsImNvbW1lbnRzIiwiY29sdW1uIiwiUGFydGlhbFN0YXRlbWVudCIsInBhcnRpYWwiLCJuYW1lIiwiUGFydGlhbEJsb2NrU3RhdGVtZW50IiwicGFydGlhbEJsb2NrIiwiRGVjb3JhdG9yIiwiZGVjb3JhdG9yIiwiRGVjb3JhdG9yQmxvY2siLCJkZWNvcmF0b3JCbG9jayIsIlN1YkV4cHJlc3Npb24iLCJzZXhwciIsIlBhdGhFeHByZXNzaW9uIiwib3JpZ2luYWwiLCJwYXJ0cyIsImluZGV4T2YiLCJzbGljZSIsImpvaW4iLCJ0aGlzSGVhZCIsInRoaXMiLCJkYXRhIiwiSGFzaCIsInBhaXJzIiwicGFpciIsImtleSIsIlN0cmluZ0xpdGVyYWwiLCJzdHJpbmciLCJsaXRlcmFsIiwiQm9vbGVhbkxpdGVyYWwiLCJib29sZWFuIiwiTnVtYmVyTGl0ZXJhbCIsIm51bWJlciIsIlVuZGVmaW5lZExpdGVyYWwiLCJ1bmRlZiIsInVuZGVmaW5lZCIsIk51bGxMaXRlcmFsIiwibnVsIiwiY2FsY3VsYXRlUmlnaHRTdHJpcHBlZE9mZnNldHMiLCJsaW5lcyIsInNwbGl0IiwiY29sdW1ucyIsImRpZmZlcmVuY2UiLCJsaW5lQ291bnQiLCJvZmZzZXRzIiwiY29tcGlsZXIiLCJtYXAiLCJlIiwiZWxlbWVudCIsIm1vZGlmaWVyIiwiZWxlbWVudE1vZGlmaWVyIiwibW9kaWZpZXJzIiwiYXR0cmlidXRlIiwicGFydCIsImlzRHluYW1pYyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLEFBQU8sQUFBTzs7OztBQUNkLEFBQVMsQUFBYSxBQUFXLEFBQW9COztBQUNyRCxBQUFTLEFBQWM7O0FBQ3ZCLEFBQU8sQUFBaUIsQUFDeEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBQUEsQUFBYSw2RUFBYjtzQ0FBQTs7c0NBQUE7OEJBQUE7O29FQUFBO0FBQUE7O3FDQUFBLEFBQ0ksMkJBREosQUFDWSxTQUFTLEFBQ2I7WUFBSSxPQUFKLEFBQVcsQUFDWDtZQUFJLE9BQU8sbUJBQUEsQUFBRSxRQUFGLEFBQVUsTUFBTSxRQUFoQixBQUF3QixhQUFhLFFBQWhELEFBQVcsQUFBNkMsQUFDeEQ7WUFB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Q0FBVCxBQUF5QyxXQUF6QyxBQUFvRCxNQUFNLEFBQ3REO2NBQUEsQUFBVSxZQUFWLEFBQXNCLEFBQ3RCO2NBQUEsQUFBVSxNQUFWLEFBQWdCLEtBQWhCLEFBQXFCLEFBQ3hCIiwiZmlsZSI6ImxpYi9wYXJzZXIvaGFuZGxlYmFycy1ub2RlLXZpc2l0b3JzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGIgZnJvbSBcIi4uL2J1aWxkZXJzXCI7XG5pbXBvcnQgeyBhcHBlbmRDaGlsZCwgaXNMaXRlcmFsLCBwcmludExpdGVyYWwgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IFBhcnNlciB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgU3ludGF4RXJyb3IgZnJvbSAnLi4vZXJyb3JzL3N5bnRheC1lcnJvcic7XG5leHBvcnQgY2xhc3MgSGFuZGxlYmFyc05vZGVWaXNpdG9ycyBleHRlbmRzIFBhcnNlciB7XG4gICAgUHJvZ3JhbShwcm9ncmFtKSB7XG4gICAgICAgIGxldCBib2R5ID0gW107XG4gICAgICAgIGxldCBub2RlID0gYi5wcm9ncmFtKGJvZHksIHByb2dyYW0uYmxvY2tQYXJhbXMsIHByb2dyYW0ubG9jKTtcbiAgICAgICAgbGV0IGksXG4gICAgICAgICAgICBsID0gcHJvZ3JhbS5ib2R5Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5lbGVtZW50U3RhY2sucHVzaChub2RlKTtcbiAgICAgICAgaWYgKGwgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjay5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmFjY2VwdE5vZGUocHJvZ3JhbS5ib2R5W2ldKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGF0IHRoZSBlbGVtZW50IHN0YWNrIGlzIGJhbGFuY2VkIHByb3Blcmx5LlxuICAgICAgICBsZXQgcG9wcGVkTm9kZSA9IHRoaXMuZWxlbWVudFN0YWNrLnBvcCgpO1xuICAgICAgICBpZiAocG9wcGVkTm9kZSAhPT0gbm9kZSkge1xuICAgICAgICAgICAgbGV0IGVsZW1lbnROb2RlID0gcG9wcGVkTm9kZTtcbiAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlVuY2xvc2VkIGVsZW1lbnQgYFwiICsgZWxlbWVudE5vZGUudGFnICsgXCJgIChvbiBsaW5lIFwiICsgZWxlbWVudE5vZGUubG9jLnN0YXJ0LmxpbmUgKyBcIikuXCIsIGVsZW1lbnROb2RlLmxvYyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICAgIEJsb2NrU3RhdGVtZW50KGJsb2NrKSB7XG4gICAgICAgIGlmICh0aGlzLnRva2VuaXplclsnc3RhdGUnXSA9PT0gJ2NvbW1lbnQnKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZFRvQ29tbWVudERhdGEodGhpcy5zb3VyY2VGb3JOb2RlKGJsb2NrKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudG9rZW5pemVyWydzdGF0ZSddICE9PSAnY29tbWVudCcgJiYgdGhpcy50b2tlbml6ZXJbJ3N0YXRlJ10gIT09ICdkYXRhJyAmJiB0aGlzLnRva2VuaXplclsnc3RhdGUnXSAhPT0gJ2JlZm9yZURhdGEnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJBIGJsb2NrIG1heSBvbmx5IGJlIHVzZWQgaW5zaWRlIGFuIEhUTUwgZWxlbWVudCBvciBhbm90aGVyIGJsb2NrLlwiLCBibG9jay5sb2MpO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHBhdGgsIHBhcmFtcywgaGFzaCB9ID0gYWNjZXB0Q2FsbE5vZGVzKHRoaXMsIGJsb2NrKTtcbiAgICAgICAgbGV0IHByb2dyYW0gPSB0aGlzLlByb2dyYW0oYmxvY2sucHJvZ3JhbSk7XG4gICAgICAgIGxldCBpbnZlcnNlID0gYmxvY2suaW52ZXJzZSA/IHRoaXMuUHJvZ3JhbShibG9jay5pbnZlcnNlKSA6IG51bGw7XG4gICAgICAgIGxldCBub2RlID0gYi5ibG9jayhwYXRoLCBwYXJhbXMsIGhhc2gsIHByb2dyYW0sIGludmVyc2UsIGJsb2NrLmxvYyk7XG4gICAgICAgIGxldCBwYXJlbnRQcm9ncmFtID0gdGhpcy5jdXJyZW50RWxlbWVudCgpO1xuICAgICAgICBhcHBlbmRDaGlsZChwYXJlbnRQcm9ncmFtLCBub2RlKTtcbiAgICB9XG4gICAgTXVzdGFjaGVTdGF0ZW1lbnQocmF3TXVzdGFjaGUpIHtcbiAgICAgICAgbGV0IHsgdG9rZW5pemVyIH0gPSB0aGlzO1xuICAgICAgICBpZiAodG9rZW5pemVyWydzdGF0ZSddID09PSAnY29tbWVudCcpIHtcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kVG9Db21tZW50RGF0YSh0aGlzLnNvdXJjZUZvck5vZGUocmF3TXVzdGFjaGUpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbXVzdGFjaGU7XG4gICAgICAgIGxldCB7IGVzY2FwZWQsIGxvYyB9ID0gcmF3TXVzdGFjaGU7XG4gICAgICAgIGlmIChyYXdNdXN0YWNoZS5wYXRoLnR5cGUubWF0Y2goL0xpdGVyYWwkLykpIHtcbiAgICAgICAgICAgIG11c3RhY2hlID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdNdXN0YWNoZVN0YXRlbWVudCcsXG4gICAgICAgICAgICAgICAgcGF0aDogdGhpcy5hY2NlcHROb2RlKHJhd011c3RhY2hlLnBhdGgpLFxuICAgICAgICAgICAgICAgIHBhcmFtczogW10sXG4gICAgICAgICAgICAgICAgaGFzaDogYi5oYXNoKCksXG4gICAgICAgICAgICAgICAgZXNjYXBlZCxcbiAgICAgICAgICAgICAgICBsb2NcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCByYXdNdXN0YWNoZSk7XG4gICAgICAgICAgICBtdXN0YWNoZSA9IGIubXVzdGFjaGUocGF0aCwgcGFyYW1zLCBoYXNoLCAhZXNjYXBlZCwgbG9jKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRva2VuaXplci5zdGF0ZSkge1xuICAgICAgICAgICAgLy8gVGFnIGhlbHBlcnNcbiAgICAgICAgICAgIGNhc2UgXCJ0YWdOYW1lXCI6XG4gICAgICAgICAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgdG9rZW5pemVyLnN0YXRlID0gXCJiZWZvcmVBdHRyaWJ1dGVOYW1lXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiYmVmb3JlQXR0cmlidXRlTmFtZVwiOlxuICAgICAgICAgICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImF0dHJpYnV0ZU5hbWVcIjpcbiAgICAgICAgICAgIGNhc2UgXCJhZnRlckF0dHJpYnV0ZU5hbWVcIjpcbiAgICAgICAgICAgICAgICB0aGlzLmJlZ2luQXR0cmlidXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIHRoaXMuZmluaXNoQXR0cmlidXRlVmFsdWUoKTtcbiAgICAgICAgICAgICAgICBhZGRFbGVtZW50TW9kaWZpZXIodGhpcy5jdXJyZW50U3RhcnRUYWcsIG11c3RhY2hlKTtcbiAgICAgICAgICAgICAgICB0b2tlbml6ZXIuc3RhdGUgPSBcImJlZm9yZUF0dHJpYnV0ZU5hbWVcIjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJhZnRlckF0dHJpYnV0ZVZhbHVlUXVvdGVkXCI6XG4gICAgICAgICAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgdG9rZW5pemVyLnN0YXRlID0gXCJiZWZvcmVBdHRyaWJ1dGVOYW1lXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAvLyBBdHRyaWJ1dGUgdmFsdWVzXG4gICAgICAgICAgICBjYXNlIFwiYmVmb3JlQXR0cmlidXRlVmFsdWVcIjpcbiAgICAgICAgICAgICAgICBhcHBlbmREeW5hbWljQXR0cmlidXRlVmFsdWVQYXJ0KHRoaXMuY3VycmVudEF0dHJpYnV0ZSwgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIHRva2VuaXplci5zdGF0ZSA9ICdhdHRyaWJ1dGVWYWx1ZVVucXVvdGVkJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJhdHRyaWJ1dGVWYWx1ZURvdWJsZVF1b3RlZFwiOlxuICAgICAgICAgICAgY2FzZSBcImF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVkXCI6XG4gICAgICAgICAgICBjYXNlIFwiYXR0cmlidXRlVmFsdWVVbnF1b3RlZFwiOlxuICAgICAgICAgICAgICAgIGFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQodGhpcy5jdXJyZW50QXR0cmlidXRlLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAvLyBUT0RPOiBPbmx5IGFwcGVuZCBjaGlsZCB3aGVuIHRoZSB0b2tlbml6ZXIgc3RhdGUgbWFrZXNcbiAgICAgICAgICAgIC8vIHNlbnNlIHRvIGRvIHNvLCBvdGhlcndpc2UgdGhyb3cgYW4gZXJyb3IuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGFwcGVuZENoaWxkKHRoaXMuY3VycmVudEVsZW1lbnQoKSwgbXVzdGFjaGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtdXN0YWNoZTtcbiAgICB9XG4gICAgQ29udGVudFN0YXRlbWVudChjb250ZW50KSB7XG4gICAgICAgIHVwZGF0ZVRva2VuaXplckxvY2F0aW9uKHRoaXMudG9rZW5pemVyLCBjb250ZW50KTtcbiAgICAgICAgdGhpcy50b2tlbml6ZXIudG9rZW5pemVQYXJ0KGNvbnRlbnQudmFsdWUpO1xuICAgICAgICB0aGlzLnRva2VuaXplci5mbHVzaERhdGEoKTtcbiAgICB9XG4gICAgQ29tbWVudFN0YXRlbWVudChyYXdDb21tZW50KSB7XG4gICAgICAgIGxldCB7IHRva2VuaXplciB9ID0gdGhpcztcbiAgICAgICAgaWYgKHRva2VuaXplci5zdGF0ZSA9PT0gJ2NvbW1lbnQnKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZFRvQ29tbWVudERhdGEodGhpcy5zb3VyY2VGb3JOb2RlKHJhd0NvbW1lbnQpKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHZhbHVlLCBsb2MgfSA9IHJhd0NvbW1lbnQ7XG4gICAgICAgIGxldCBjb21tZW50ID0gYi5tdXN0YWNoZUNvbW1lbnQodmFsdWUsIGxvYyk7XG4gICAgICAgIHN3aXRjaCAodG9rZW5pemVyLnN0YXRlKSB7XG4gICAgICAgICAgICBjYXNlIFwiYmVmb3JlQXR0cmlidXRlTmFtZVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFN0YXJ0VGFnLmNvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdiZWZvcmVEYXRhJzpcbiAgICAgICAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgICAgICAgICAgIGFwcGVuZENoaWxkKHRoaXMuY3VycmVudEVsZW1lbnQoKSwgY29tbWVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgVXNpbmcgYSBIYW5kbGViYXJzIGNvbW1lbnQgd2hlbiBpbiB0aGUgXFxgJHt0b2tlbml6ZXIuc3RhdGV9XFxgIHN0YXRlIGlzIG5vdCBzdXBwb3J0ZWQ6IFwiJHtjb21tZW50LnZhbHVlfVwiIG9uIGxpbmUgJHtsb2Muc3RhcnQubGluZX06JHtsb2Muc3RhcnQuY29sdW1ufWAsIHJhd0NvbW1lbnQubG9jKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tbWVudDtcbiAgICB9XG4gICAgUGFydGlhbFN0YXRlbWVudChwYXJ0aWFsKSB7XG4gICAgICAgIGxldCB7IGxvYyB9ID0gcGFydGlhbDtcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBIYW5kbGViYXJzIHBhcnRpYWxzIGFyZSBub3Qgc3VwcG9ydGVkOiBcIiR7dGhpcy5zb3VyY2VGb3JOb2RlKHBhcnRpYWwsIHBhcnRpYWwubmFtZSl9XCIgYXQgTCR7bG9jLnN0YXJ0LmxpbmV9OkMke2xvYy5zdGFydC5jb2x1bW59YCwgcGFydGlhbC5sb2MpO1xuICAgIH1cbiAgICBQYXJ0aWFsQmxvY2tTdGF0ZW1lbnQocGFydGlhbEJsb2NrKSB7XG4gICAgICAgIGxldCB7IGxvYyB9ID0gcGFydGlhbEJsb2NrO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEhhbmRsZWJhcnMgcGFydGlhbCBibG9ja3MgYXJlIG5vdCBzdXBwb3J0ZWQ6IFwiJHt0aGlzLnNvdXJjZUZvck5vZGUocGFydGlhbEJsb2NrLCBwYXJ0aWFsQmxvY2submFtZSl9XCIgYXQgTCR7bG9jLnN0YXJ0LmxpbmV9OkMke2xvYy5zdGFydC5jb2x1bW59YCwgcGFydGlhbEJsb2NrLmxvYyk7XG4gICAgfVxuICAgIERlY29yYXRvcihkZWNvcmF0b3IpIHtcbiAgICAgICAgbGV0IHsgbG9jIH0gPSBkZWNvcmF0b3I7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgSGFuZGxlYmFycyBkZWNvcmF0b3JzIGFyZSBub3Qgc3VwcG9ydGVkOiBcIiR7dGhpcy5zb3VyY2VGb3JOb2RlKGRlY29yYXRvciwgZGVjb3JhdG9yLnBhdGgpfVwiIGF0IEwke2xvYy5zdGFydC5saW5lfTpDJHtsb2Muc3RhcnQuY29sdW1ufWAsIGRlY29yYXRvci5sb2MpO1xuICAgIH1cbiAgICBEZWNvcmF0b3JCbG9jayhkZWNvcmF0b3JCbG9jaykge1xuICAgICAgICBsZXQgeyBsb2MgfSA9IGRlY29yYXRvckJsb2NrO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEhhbmRsZWJhcnMgZGVjb3JhdG9yIGJsb2NrcyBhcmUgbm90IHN1cHBvcnRlZDogXCIke3RoaXMuc291cmNlRm9yTm9kZShkZWNvcmF0b3JCbG9jaywgZGVjb3JhdG9yQmxvY2sucGF0aCl9XCIgYXQgTCR7bG9jLnN0YXJ0LmxpbmV9OkMke2xvYy5zdGFydC5jb2x1bW59YCwgZGVjb3JhdG9yQmxvY2subG9jKTtcbiAgICB9XG4gICAgU3ViRXhwcmVzc2lvbihzZXhwcikge1xuICAgICAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCBzZXhwcik7XG4gICAgICAgIHJldHVybiBiLnNleHByKHBhdGgsIHBhcmFtcywgaGFzaCwgc2V4cHIubG9jKTtcbiAgICB9XG4gICAgUGF0aEV4cHJlc3Npb24ocGF0aCkge1xuICAgICAgICBsZXQgeyBvcmlnaW5hbCwgbG9jIH0gPSBwYXRoO1xuICAgICAgICBsZXQgcGFydHM7XG4gICAgICAgIGlmIChvcmlnaW5hbC5pbmRleE9mKCcvJykgIT09IC0xKSB7XG4gICAgICAgICAgICBpZiAob3JpZ2luYWwuc2xpY2UoMCwgMikgPT09ICcuLycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYFVzaW5nIFwiLi9cIiBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXIgYW5kIHVubmVjZXNzYXJ5OiBcIiR7cGF0aC5vcmlnaW5hbH1cIiBvbiBsaW5lICR7bG9jLnN0YXJ0LmxpbmV9LmAsIHBhdGgubG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcmlnaW5hbC5zbGljZSgwLCAzKSA9PT0gJy4uLycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYENoYW5naW5nIGNvbnRleHQgdXNpbmcgXCIuLi9cIiBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXI6IFwiJHtwYXRoLm9yaWdpbmFsfVwiIG9uIGxpbmUgJHtsb2Muc3RhcnQubGluZX0uYCwgcGF0aC5sb2MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9yaWdpbmFsLmluZGV4T2YoJy4nKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYE1peGluZyAnLicgYW5kICcvJyBpbiBwYXRocyBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXI7IHVzZSBvbmx5ICcuJyB0byBzZXBhcmF0ZSBwcm9wZXJ0eSBwYXRoczogXCIke3BhdGgub3JpZ2luYWx9XCIgb24gbGluZSAke2xvYy5zdGFydC5saW5lfS5gLCBwYXRoLmxvYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJ0cyA9IFtwYXRoLnBhcnRzLmpvaW4oJy8nKV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJ0cyA9IHBhdGgucGFydHM7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRoaXNIZWFkID0gZmFsc2U7XG4gICAgICAgIC8vIFRoaXMgaXMgdG8gZml4IGEgYnVnIGluIHRoZSBIYW5kbGViYXJzIEFTVCB3aGVyZSB0aGUgcGF0aCBleHByZXNzaW9ucyBpblxuICAgICAgICAvLyBge3t0aGlzLmZvb319YCAoYW5kIHNpbWlsYXJseSBge3tmb28tYmFyIHRoaXMuZm9vIG5hbWVkPXRoaXMuZm9vfX1gIGV0YylcbiAgICAgICAgLy8gYXJlIHNpbXBseSB0dXJuZWQgaW50byBge3tmb299fWAuIFRoZSBmaXggaXMgdG8gcHVzaCBpdCBiYWNrIG9udG8gdGhlXG4gICAgICAgIC8vIHBhcnRzIGFycmF5IGFuZCBsZXQgdGhlIHJ1bnRpbWUgc2VlIHRoZSBkaWZmZXJlbmNlLiBIb3dldmVyLCB3ZSBjYW5ub3RcbiAgICAgICAgLy8gc2ltcGx5IHVzZSB0aGUgc3RyaW5nIGB0aGlzYCBhcyBpdCBtZWFucyBsaXRlcmFsbHkgdGhlIHByb3BlcnR5IGNhbGxlZFxuICAgICAgICAvLyBcInRoaXNcIiBpbiB0aGUgY3VycmVudCBjb250ZXh0IChpdCBjYW4gYmUgZXhwcmVzc2VkIGluIHRoZSBzeW50YXggYXNcbiAgICAgICAgLy8gYHt7W3RoaXNdfX1gLCB3aGVyZSB0aGUgc3F1YXJlIGJyYWNrZXQgYXJlIGdlbmVyYWxseSBmb3IgdGhpcyBraW5kIG9mXG4gICAgICAgIC8vIGVzY2FwaW5nIOKAkyBzdWNoIGFzIGB7e2Zvby5bXCJiYXIuYmF6XCJdfX1gIHdvdWxkIG1lYW4gbG9va3VwIGEgcHJvcGVydHlcbiAgICAgICAgLy8gbmFtZWQgbGl0ZXJhbGx5IFwiYmFyLmJhelwiIG9uIGB0aGlzLmZvb2ApLiBCeSBjb252ZW50aW9uLCB3ZSB1c2UgYG51bGxgXG4gICAgICAgIC8vIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgICAgIGlmIChvcmlnaW5hbC5tYXRjaCgvXnRoaXMoXFwuLispPyQvKSkge1xuICAgICAgICAgICAgdGhpc0hlYWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnUGF0aEV4cHJlc3Npb24nLFxuICAgICAgICAgICAgb3JpZ2luYWw6IHBhdGgub3JpZ2luYWwsXG4gICAgICAgICAgICB0aGlzOiB0aGlzSGVhZCxcbiAgICAgICAgICAgIHBhcnRzLFxuICAgICAgICAgICAgZGF0YTogcGF0aC5kYXRhLFxuICAgICAgICAgICAgbG9jOiBwYXRoLmxvY1xuICAgICAgICB9O1xuICAgIH1cbiAgICBIYXNoKGhhc2gpIHtcbiAgICAgICAgbGV0IHBhaXJzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGFzaC5wYWlycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHBhaXIgPSBoYXNoLnBhaXJzW2ldO1xuICAgICAgICAgICAgcGFpcnMucHVzaChiLnBhaXIocGFpci5rZXksIHRoaXMuYWNjZXB0Tm9kZShwYWlyLnZhbHVlKSwgcGFpci5sb2MpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYi5oYXNoKHBhaXJzLCBoYXNoLmxvYyk7XG4gICAgfVxuICAgIFN0cmluZ0xpdGVyYWwoc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBiLmxpdGVyYWwoJ1N0cmluZ0xpdGVyYWwnLCBzdHJpbmcudmFsdWUsIHN0cmluZy5sb2MpO1xuICAgIH1cbiAgICBCb29sZWFuTGl0ZXJhbChib29sZWFuKSB7XG4gICAgICAgIHJldHVybiBiLmxpdGVyYWwoJ0Jvb2xlYW5MaXRlcmFsJywgYm9vbGVhbi52YWx1ZSwgYm9vbGVhbi5sb2MpO1xuICAgIH1cbiAgICBOdW1iZXJMaXRlcmFsKG51bWJlcikge1xuICAgICAgICByZXR1cm4gYi5saXRlcmFsKCdOdW1iZXJMaXRlcmFsJywgbnVtYmVyLnZhbHVlLCBudW1iZXIubG9jKTtcbiAgICB9XG4gICAgVW5kZWZpbmVkTGl0ZXJhbCh1bmRlZikge1xuICAgICAgICByZXR1cm4gYi5saXRlcmFsKCdVbmRlZmluZWRMaXRlcmFsJywgdW5kZWZpbmVkLCB1bmRlZi5sb2MpO1xuICAgIH1cbiAgICBOdWxsTGl0ZXJhbChudWwpIHtcbiAgICAgICAgcmV0dXJuIGIubGl0ZXJhbCgnTnVsbExpdGVyYWwnLCBudWxsLCBudWwubG9jKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjYWxjdWxhdGVSaWdodFN0cmlwcGVkT2Zmc2V0cyhvcmlnaW5hbCwgdmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgIC8vIGlmIGl0IGlzIGVtcHR5LCBqdXN0IHJldHVybiB0aGUgY291bnQgb2YgbmV3bGluZXNcbiAgICAgICAgLy8gaW4gb3JpZ2luYWxcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxpbmVzOiBvcmlnaW5hbC5zcGxpdChcIlxcblwiKS5sZW5ndGggLSAxLFxuICAgICAgICAgICAgY29sdW1uczogMFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBvdGhlcndpc2UsIHJldHVybiB0aGUgbnVtYmVyIG9mIG5ld2xpbmVzIHByaW9yIHRvXG4gICAgLy8gYHZhbHVlYFxuICAgIGxldCBkaWZmZXJlbmNlID0gb3JpZ2luYWwuc3BsaXQodmFsdWUpWzBdO1xuICAgIGxldCBsaW5lcyA9IGRpZmZlcmVuY2Uuc3BsaXQoL1xcbi8pO1xuICAgIGxldCBsaW5lQ291bnQgPSBsaW5lcy5sZW5ndGggLSAxO1xuICAgIHJldHVybiB7XG4gICAgICAgIGxpbmVzOiBsaW5lQ291bnQsXG4gICAgICAgIGNvbHVtbnM6IGxpbmVzW2xpbmVDb3VudF0ubGVuZ3RoXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZVRva2VuaXplckxvY2F0aW9uKHRva2VuaXplciwgY29udGVudCkge1xuICAgIGxldCBsaW5lID0gY29udGVudC5sb2Muc3RhcnQubGluZTtcbiAgICBsZXQgY29sdW1uID0gY29udGVudC5sb2Muc3RhcnQuY29sdW1uO1xuICAgIGxldCBvZmZzZXRzID0gY2FsY3VsYXRlUmlnaHRTdHJpcHBlZE9mZnNldHMoY29udGVudC5vcmlnaW5hbCwgY29udGVudC52YWx1ZSk7XG4gICAgbGluZSA9IGxpbmUgKyBvZmZzZXRzLmxpbmVzO1xuICAgIGlmIChvZmZzZXRzLmxpbmVzKSB7XG4gICAgICAgIGNvbHVtbiA9IG9mZnNldHMuY29sdW1ucztcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW4gPSBjb2x1bW4gKyBvZmZzZXRzLmNvbHVtbnM7XG4gICAgfVxuICAgIHRva2VuaXplci5saW5lID0gbGluZTtcbiAgICB0b2tlbml6ZXIuY29sdW1uID0gY29sdW1uO1xufVxuZnVuY3Rpb24gYWNjZXB0Q2FsbE5vZGVzKGNvbXBpbGVyLCBub2RlKSB7XG4gICAgbGV0IHBhdGggPSBjb21waWxlci5QYXRoRXhwcmVzc2lvbihub2RlLnBhdGgpO1xuICAgIGxldCBwYXJhbXMgPSBub2RlLnBhcmFtcyA/IG5vZGUucGFyYW1zLm1hcChlID0+IGNvbXBpbGVyLmFjY2VwdE5vZGUoZSkpIDogW107XG4gICAgbGV0IGhhc2ggPSBub2RlLmhhc2ggPyBjb21waWxlci5IYXNoKG5vZGUuaGFzaCkgOiBiLmhhc2goKTtcbiAgICByZXR1cm4geyBwYXRoLCBwYXJhbXMsIGhhc2ggfTtcbn1cbmZ1bmN0aW9uIGFkZEVsZW1lbnRNb2RpZmllcihlbGVtZW50LCBtdXN0YWNoZSkge1xuICAgIGxldCB7IHBhdGgsIHBhcmFtcywgaGFzaCwgbG9jIH0gPSBtdXN0YWNoZTtcbiAgICBpZiAoaXNMaXRlcmFsKHBhdGgpKSB7XG4gICAgICAgIGxldCBtb2RpZmllciA9IGB7eyR7cHJpbnRMaXRlcmFsKHBhdGgpfX19YDtcbiAgICAgICAgbGV0IHRhZyA9IGA8JHtlbGVtZW50Lm5hbWV9IC4uLiAke21vZGlmaWVyfSAuLi5gO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEluICR7dGFnfSwgJHttb2RpZmllcn0gaXMgbm90IGEgdmFsaWQgbW9kaWZpZXI6IFwiJHtwYXRoLm9yaWdpbmFsfVwiIG9uIGxpbmUgJHtsb2MgJiYgbG9jLnN0YXJ0LmxpbmV9LmAsIG11c3RhY2hlLmxvYyk7XG4gICAgfVxuICAgIGxldCBtb2RpZmllciA9IGIuZWxlbWVudE1vZGlmaWVyKHBhdGgsIHBhcmFtcywgaGFzaCwgbG9jKTtcbiAgICBlbGVtZW50Lm1vZGlmaWVycy5wdXNoKG1vZGlmaWVyKTtcbn1cbmZ1bmN0aW9uIGFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQoYXR0cmlidXRlLCBwYXJ0KSB7XG4gICAgYXR0cmlidXRlLmlzRHluYW1pYyA9IHRydWU7XG4gICAgYXR0cmlidXRlLnBhcnRzLnB1c2gocGFydCk7XG59Il19