UNPKG

ember-legacy-class-transform

Version:
279 lines (270 loc) 40.8 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 }; } class HandlebarsNodeVisitors extends _parser.Parser { Program(program) { let body = []; let node = _builders2.default.program(body, program.blockParams, program.loc); let i, 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. let poppedNode = this.elementStack.pop(); if (poppedNode !== node) { let elementNode = poppedNode; throw new _syntaxError2.default("Unclosed element `" + elementNode.tag + "` (on line " + elementNode.loc.start.line + ").", elementNode.loc); } return node; } 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); } let { path, params, hash } = acceptCallNodes(this, block); let program = this.Program(block.program); let inverse = block.inverse ? this.Program(block.inverse) : null; let node = _builders2.default.block(path, params, hash, program, inverse, block.loc); let parentProgram = this.currentElement(); (0, _utils.appendChild)(parentProgram, node); } MustacheStatement(rawMustache) { let { tokenizer } = this; if (tokenizer['state'] === 'comment') { this.appendToCommentData(this.sourceForNode(rawMustache)); return; } let mustache; let { escaped, loc } = rawMustache; if (rawMustache.path.type.match(/Literal$/)) { mustache = { type: 'MustacheStatement', path: this.acceptNode(rawMustache.path), params: [], hash: _builders2.default.hash(), escaped, loc }; } else { let { path, params, hash } = acceptCallNodes(this, rawMustache); 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; } ContentStatement(content) { updateTokenizerLocation(this.tokenizer, content); this.tokenizer.tokenizePart(content.value); this.tokenizer.flushData(); } CommentStatement(rawComment) { let { tokenizer } = this; if (tokenizer.state === 'comment') { this.appendToCommentData(this.sourceForNode(rawComment)); return null; } let { value, loc } = rawComment; let 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; } PartialStatement(partial) { let { loc } = partial; 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); } PartialBlockStatement(partialBlock) { let { loc } = partialBlock; 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); } Decorator(decorator) { let { loc } = decorator; 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); } DecoratorBlock(decoratorBlock) { let { loc } = decoratorBlock; 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); } SubExpression(sexpr) { let { path, params, hash } = acceptCallNodes(this, sexpr); return _builders2.default.sexpr(path, params, hash, sexpr.loc); } PathExpression(path) { let { original, loc } = path; let parts; 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; } let 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, data: path.data, loc: path.loc }; } Hash(hash) { let pairs = []; for (let i = 0; i < hash.pairs.length; i++) { let pair = hash.pairs[i]; pairs.push(_builders2.default.pair(pair.key, this.acceptNode(pair.value), pair.loc)); } return _builders2.default.hash(pairs, hash.loc); } StringLiteral(string) { return _builders2.default.literal('StringLiteral', string.value, string.loc); } BooleanLiteral(boolean) { return _builders2.default.literal('BooleanLiteral', boolean.value, boolean.loc); } NumberLiteral(number) { return _builders2.default.literal('NumberLiteral', number.value, number.loc); } UndefinedLiteral(undef) { return _builders2.default.literal('UndefinedLiteral', undefined, undef.loc); } NullLiteral(nul) { return _builders2.default.literal('NullLiteral', null, nul.loc); } } exports.HandlebarsNodeVisitors = HandlebarsNodeVisitors; 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` let difference = original.split(value)[0]; let lines = difference.split(/\n/); let lineCount = lines.length - 1; return { lines: lineCount, columns: lines[lineCount].length }; } function updateTokenizerLocation(tokenizer, content) { let line = content.loc.start.line; let column = content.loc.start.column; let 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) { let path = compiler.PathExpression(node.path); let params = node.params ? node.params.map(e => compiler.acceptNode(e)) : []; let hash = node.hash ? compiler.Hash(node.hash) : _builders2.default.hash(); return { path, params, hash }; } function addElementModifier(element, mustache) { let { path, params, hash, loc } = mustache; if ((0, _utils.isLiteral)(path)) { let modifier = `{{${(0, _utils.printLiteral)(path)}}}`; let 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); } let 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9wYXJzZXIvaGFuZGxlYmFycy1ub2RlLXZpc2l0b3JzLmpzIl0sIm5hbWVzIjpbIkhhbmRsZWJhcnNOb2RlVmlzaXRvcnMiLCJQcm9ncmFtIiwicHJvZ3JhbSIsImJvZHkiLCJub2RlIiwiYmxvY2tQYXJhbXMiLCJsb2MiLCJpIiwibCIsImxlbmd0aCIsImVsZW1lbnRTdGFjayIsInB1c2giLCJwb3AiLCJhY2NlcHROb2RlIiwicG9wcGVkTm9kZSIsImVsZW1lbnROb2RlIiwidGFnIiwic3RhcnQiLCJsaW5lIiwiQmxvY2tTdGF0ZW1lbnQiLCJibG9jayIsInRva2VuaXplciIsImFwcGVuZFRvQ29tbWVudERhdGEiLCJzb3VyY2VGb3JOb2RlIiwicGF0aCIsInBhcmFtcyIsImhhc2giLCJhY2NlcHRDYWxsTm9kZXMiLCJpbnZlcnNlIiwicGFyZW50UHJvZ3JhbSIsImN1cnJlbnRFbGVtZW50IiwiTXVzdGFjaGVTdGF0ZW1lbnQiLCJyYXdNdXN0YWNoZSIsIm11c3RhY2hlIiwiZXNjYXBlZCIsInR5cGUiLCJtYXRjaCIsInN0YXRlIiwiYWRkRWxlbWVudE1vZGlmaWVyIiwiY3VycmVudFN0YXJ0VGFnIiwiYmVnaW5BdHRyaWJ1dGVWYWx1ZSIsImZpbmlzaEF0dHJpYnV0ZVZhbHVlIiwiYXBwZW5kRHluYW1pY0F0dHJpYnV0ZVZhbHVlUGFydCIsImN1cnJlbnRBdHRyaWJ1dGUiLCJDb250ZW50U3RhdGVtZW50IiwiY29udGVudCIsInVwZGF0ZVRva2VuaXplckxvY2F0aW9uIiwidG9rZW5pemVQYXJ0IiwidmFsdWUiLCJmbHVzaERhdGEiLCJDb21tZW50U3RhdGVtZW50IiwicmF3Q29tbWVudCIsImNvbW1lbnQiLCJtdXN0YWNoZUNvbW1lbnQiLCJjb21tZW50cyIsImNvbHVtbiIsIlBhcnRpYWxTdGF0ZW1lbnQiLCJwYXJ0aWFsIiwibmFtZSIsIlBhcnRpYWxCbG9ja1N0YXRlbWVudCIsInBhcnRpYWxCbG9jayIsIkRlY29yYXRvciIsImRlY29yYXRvciIsIkRlY29yYXRvckJsb2NrIiwiZGVjb3JhdG9yQmxvY2siLCJTdWJFeHByZXNzaW9uIiwic2V4cHIiLCJQYXRoRXhwcmVzc2lvbiIsIm9yaWdpbmFsIiwicGFydHMiLCJpbmRleE9mIiwic2xpY2UiLCJqb2luIiwidGhpc0hlYWQiLCJ0aGlzIiwiZGF0YSIsIkhhc2giLCJwYWlycyIsInBhaXIiLCJrZXkiLCJTdHJpbmdMaXRlcmFsIiwic3RyaW5nIiwibGl0ZXJhbCIsIkJvb2xlYW5MaXRlcmFsIiwiYm9vbGVhbiIsIk51bWJlckxpdGVyYWwiLCJudW1iZXIiLCJVbmRlZmluZWRMaXRlcmFsIiwidW5kZWYiLCJ1bmRlZmluZWQiLCJOdWxsTGl0ZXJhbCIsIm51bCIsImNhbGN1bGF0ZVJpZ2h0U3RyaXBwZWRPZmZzZXRzIiwibGluZXMiLCJzcGxpdCIsImNvbHVtbnMiLCJkaWZmZXJlbmNlIiwibGluZUNvdW50Iiwib2Zmc2V0cyIsImNvbXBpbGVyIiwibWFwIiwiZSIsImVsZW1lbnQiLCJtb2RpZmllciIsImVsZW1lbnRNb2RpZmllciIsIm1vZGlmaWVycyIsImF0dHJpYnV0ZSIsInBhcnQiLCJpc0R5bmFtaWMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUNBOztBQUNBOztBQUNBOzs7Ozs7QUFDTyxNQUFNQSxzQkFBTix3QkFBNEM7QUFDL0NDLFlBQVFDLE9BQVIsRUFBaUI7QUFDYixZQUFJQyxPQUFPLEVBQVg7QUFDQSxZQUFJQyxPQUFPLG1CQUFFRixPQUFGLENBQVVDLElBQVYsRUFBZ0JELFFBQVFHLFdBQXhCLEVBQXFDSCxRQUFRSSxHQUE3QyxDQUFYO0FBQ0EsWUFBSUMsQ0FBSjtBQUFBLFlBQ0lDLElBQUlOLFFBQVFDLElBQVIsQ0FBYU0sTUFEckI7QUFFQSxhQUFLQyxZQUFMLENBQWtCQyxJQUFsQixDQUF1QlAsSUFBdkI7QUFDQSxZQUFJSSxNQUFNLENBQVYsRUFBYTtBQUNULG1CQUFPLEtBQUtFLFlBQUwsQ0FBa0JFLEdBQWxCLEVBQVA7QUFDSDtBQUNELGFBQUtMLElB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QUFSLENBQWtCOUYsSUFBbEIsQ0FBdUI0RixRQUF2QjtBQUNIO0FBQ0QsU0FBUzdELCtCQUFULENBQXlDZ0UsU0FBekMsRUFBb0RDLElBQXBELEVBQTBEO0FBQ3RERCxjQUFVRSxTQUFWLEdBQXNCLElBQXRCO0FBQ0FGLGNBQVVyQyxLQUFWLENBQWdCMUQsSUFBaEIsQ0FBcUJnRyxJQUFyQjtBQUNIIiwiZmlsZSI6ImxpYi9wYXJzZXIvaGFuZGxlYmFycy1ub2RlLXZpc2l0b3JzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGIgZnJvbSBcIi4uL2J1aWxkZXJzXCI7XG5pbXBvcnQgeyBhcHBlbmRDaGlsZCwgaXNMaXRlcmFsLCBwcmludExpdGVyYWwgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IFBhcnNlciB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgU3ludGF4RXJyb3IgZnJvbSAnLi4vZXJyb3JzL3N5bnRheC1lcnJvcic7XG5leHBvcnQgY2xhc3MgSGFuZGxlYmFyc05vZGVWaXNpdG9ycyBleHRlbmRzIFBhcnNlciB7XG4gICAgUHJvZ3JhbShwcm9ncmFtKSB7XG4gICAgICAgIGxldCBib2R5ID0gW107XG4gICAgICAgIGxldCBub2RlID0gYi5wcm9ncmFtKGJvZHksIHByb2dyYW0uYmxvY2tQYXJhbXMsIHByb2dyYW0ubG9jKTtcbiAgICAgICAgbGV0IGksXG4gICAgICAgICAgICBsID0gcHJvZ3JhbS5ib2R5Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5lbGVtZW50U3RhY2sucHVzaChub2RlKTtcbiAgICAgICAgaWYgKGwgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjay5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmFjY2VwdE5vZGUocHJvZ3JhbS5ib2R5W2ldKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGF0IHRoZSBlbGVtZW50IHN0YWNrIGlzIGJhbGFuY2VkIHByb3Blcmx5LlxuICAgICAgICBsZXQgcG9wcGVkTm9kZSA9IHRoaXMuZWxlbWVudFN0YWNrLnBvcCgpO1xuICAgICAgICBpZiAocG9wcGVkTm9kZSAhPT0gbm9kZSkge1xuICAgICAgICAgICAgbGV0IGVsZW1lbnROb2RlID0gcG9wcGVkTm9kZTtcbiAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlVuY2xvc2VkIGVsZW1lbnQgYFwiICsgZWxlbWVudE5vZGUudGFnICsgXCJgIChvbiBsaW5lIFwiICsgZWxlbWVudE5vZGUubG9jLnN0YXJ0LmxpbmUgKyBcIikuXCIsIGVsZW1lbnROb2RlLmxvYyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICAgIEJsb2NrU3RhdGVtZW50KGJsb2NrKSB7XG4gICAgICAgIGlmICh0aGlzLnRva2VuaXplclsnc3RhdGUnXSA9PT0gJ2NvbW1lbnQnKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZFRvQ29tbWVudERhdGEodGhpcy5zb3VyY2VGb3JOb2RlKGJsb2NrKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudG9rZW5pemVyWydzdGF0ZSddICE9PSAnY29tbWVudCcgJiYgdGhpcy50b2tlbml6ZXJbJ3N0YXRlJ10gIT09ICdkYXRhJyAmJiB0aGlzLnRva2VuaXplclsnc3RhdGUnXSAhPT0gJ2JlZm9yZURhdGEnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJBIGJsb2NrIG1heSBvbmx5IGJlIHVzZWQgaW5zaWRlIGFuIEhUTUwgZWxlbWVudCBvciBhbm90aGVyIGJsb2NrLlwiLCBibG9jay5sb2MpO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHBhdGgsIHBhcmFtcywgaGFzaCB9ID0gYWNjZXB0Q2FsbE5vZGVzKHRoaXMsIGJsb2NrKTtcbiAgICAgICAgbGV0IHByb2dyYW0gPSB0aGlzLlByb2dyYW0oYmxvY2sucHJvZ3JhbSk7XG4gICAgICAgIGxldCBpbnZlcnNlID0gYmxvY2suaW52ZXJzZSA/IHRoaXMuUHJvZ3JhbShibG9jay5pbnZlcnNlKSA6IG51bGw7XG4gICAgICAgIGxldCBub2RlID0gYi5ibG9jayhwYXRoLCBwYXJhbXMsIGhhc2gsIHByb2dyYW0sIGludmVyc2UsIGJsb2NrLmxvYyk7XG4gICAgICAgIGxldCBwYXJlbnRQcm9ncmFtID0gdGhpcy5jdXJyZW50RWxlbWVudCgpO1xuICAgICAgICBhcHBlbmRDaGlsZChwYXJlbnRQcm9ncmFtLCBub2RlKTtcbiAgICB9XG4gICAgTXVzdGFjaGVTdGF0ZW1lbnQocmF3TXVzdGFjaGUpIHtcbiAgICAgICAgbGV0IHsgdG9rZW5pemVyIH0gPSB0aGlzO1xuICAgICAgICBpZiAodG9rZW5pemVyWydzdGF0ZSddID09PSAnY29tbWVudCcpIHtcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kVG9Db21tZW50RGF0YSh0aGlzLnNvdXJjZUZvck5vZGUocmF3TXVzdGFjaGUpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbXVzdGFjaGU7XG4gICAgICAgIGxldCB7IGVzY2FwZWQsIGxvYyB9ID0gcmF3TXVzdGFjaGU7XG4gICAgICAgIGlmIChyYXdNdXN0YWNoZS5wYXRoLnR5cGUubWF0Y2goL0xpdGVyYWwkLykpIHtcbiAgICAgICAgICAgIG11c3RhY2hlID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdNdXN0YWNoZVN0YXRlbWVudCcsXG4gICAgICAgICAgICAgICAgcGF0aDogdGhpcy5hY2NlcHROb2RlKHJhd011c3RhY2hlLnBhdGgpLFxuICAgICAgICAgICAgICAgIHBhcmFtczogW10sXG4gICAgICAgICAgICAgICAgaGFzaDogYi5oYXNoKCksXG4gICAgICAgICAgICAgICAgZXNjYXBlZCxcbiAgICAgICAgICAgICAgICBsb2NcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCByYXdNdXN0YWNoZSk7XG4gICAgICAgICAgICBtdXN0YWNoZSA9IGIubXVzdGFjaGUocGF0aCwgcGFyYW1zLCBoYXNoLCAhZXNjYXBlZCwgbG9jKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRva2VuaXplci5zdGF0ZSkge1xuICAgICAgICAgICAgLy8gVGFnIGhlbHBlcnNcbiAgICAgICAgICAgIGNhc2UgXCJ0YWdOYW1lXCI6XG4gICAgICAgICAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgdG9rZW5pemVyLnN0YXRlID0gXCJiZWZvcmVBdHRyaWJ1dGVOYW1lXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiYmVmb3JlQXR0cmlidXRlTmFtZVwiOlxuICAgICAgICAgICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImF0dHJpYnV0ZU5hbWVcIjpcbiAgICAgICAgICAgIGNhc2UgXCJhZnRlckF0dHJpYnV0ZU5hbWVcIjpcbiAgICAgICAgICAgICAgICB0aGlzLmJlZ2luQXR0cmlidXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIHRoaXMuZmluaXNoQXR0cmlidXRlVmFsdWUoKTtcbiAgICAgICAgICAgICAgICBhZGRFbGVtZW50TW9kaWZpZXIodGhpcy5jdXJyZW50U3RhcnRUYWcsIG11c3RhY2hlKTtcbiAgICAgICAgICAgICAgICB0b2tlbml6ZXIuc3RhdGUgPSBcImJlZm9yZUF0dHJpYnV0ZU5hbWVcIjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJhZnRlckF0dHJpYnV0ZVZhbHVlUXVvdGVkXCI6XG4gICAgICAgICAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgdG9rZW5pemVyLnN0YXRlID0gXCJiZWZvcmVBdHRyaWJ1dGVOYW1lXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAvLyBBdHRyaWJ1dGUgdmFsdWVzXG4gICAgICAgICAgICBjYXNlIFwiYmVmb3JlQXR0cmlidXRlVmFsdWVcIjpcbiAgICAgICAgICAgICAgICBhcHBlbmREeW5hbWljQXR0cmlidXRlVmFsdWVQYXJ0KHRoaXMuY3VycmVudEF0dHJpYnV0ZSwgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIHRva2VuaXplci5zdGF0ZSA9ICdhdHRyaWJ1dGVWYWx1ZVVucXVvdGVkJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJhdHRyaWJ1dGVWYWx1ZURvdWJsZVF1b3RlZFwiOlxuICAgICAgICAgICAgY2FzZSBcImF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVkXCI6XG4gICAgICAgICAgICBjYXNlIFwiYXR0cmlidXRlVmFsdWVVbnF1b3RlZFwiOlxuICAgICAgICAgICAgICAgIGFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQodGhpcy5jdXJyZW50QXR0cmlidXRlLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAvLyBUT0RPOiBPbmx5IGFwcGVuZCBjaGlsZCB3aGVuIHRoZSB0b2tlbml6ZXIgc3RhdGUgbWFrZXNcbiAgICAgICAgICAgIC8vIHNlbnNlIHRvIGRvIHNvLCBvdGhlcndpc2UgdGhyb3cgYW4gZXJyb3IuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGFwcGVuZENoaWxkKHRoaXMuY3VycmVudEVsZW1lbnQoKSwgbXVzdGFjaGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtdXN0YWNoZTtcbiAgICB9XG4gICAgQ29udGVudFN0YXRlbWVudChjb250ZW50KSB7XG4gICAgICAgIHVwZGF0ZVRva2VuaXplckxvY2F0aW9uKHRoaXMudG9rZW5pemVyLCBjb250ZW50KTtcbiAgICAgICAgdGhpcy50b2tlbml6ZXIudG9rZW5pemVQYXJ0KGNvbnRlbnQudmFsdWUpO1xuICAgICAgICB0aGlzLnRva2VuaXplci5mbHVzaERhdGEoKTtcbiAgICB9XG4gICAgQ29tbWVudFN0YXRlbWVudChyYXdDb21tZW50KSB7XG4gICAgICAgIGxldCB7IHRva2VuaXplciB9ID0gdGhpcztcbiAgICAgICAgaWYgKHRva2VuaXplci5zdGF0ZSA9PT0gJ2NvbW1lbnQnKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZFRvQ29tbWVudERhdGEodGhpcy5zb3VyY2VGb3JOb2RlKHJhd0NvbW1lbnQpKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHZhbHVlLCBsb2MgfSA9IHJhd0NvbW1lbnQ7XG4gICAgICAgIGxldCBjb21tZW50ID0gYi5tdXN0YWNoZUNvbW1lbnQodmFsdWUsIGxvYyk7XG4gICAgICAgIHN3aXRjaCAodG9rZW5pemVyLnN0YXRlKSB7XG4gICAgICAgICAgICBjYXNlIFwiYmVmb3JlQXR0cmlidXRlTmFtZVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFN0YXJ0VGFnLmNvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdiZWZvcmVEYXRhJzpcbiAgICAgICAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgICAgICAgICAgIGFwcGVuZENoaWxkKHRoaXMuY3VycmVudEVsZW1lbnQoKSwgY29tbWVudCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgVXNpbmcgYSBIYW5kbGViYXJzIGNvbW1lbnQgd2hlbiBpbiB0aGUgXFxgJHt0b2tlbml6ZXIuc3RhdGV9XFxgIHN0YXRlIGlzIG5vdCBzdXBwb3J0ZWQ6IFwiJHtjb21tZW50LnZhbHVlfVwiIG9uIGxpbmUgJHtsb2Muc3RhcnQubGluZX06JHtsb2Muc3RhcnQuY29sdW1ufWAsIHJhd0NvbW1lbnQubG9jKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tbWVudDtcbiAgICB9XG4gICAgUGFydGlhbFN0YXRlbWVudChwYXJ0aWFsKSB7XG4gICAgICAgIGxldCB7IGxvYyB9ID0gcGFydGlhbDtcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBIYW5kbGViYXJzIHBhcnRpYWxzIGFyZSBub3Qgc3VwcG9ydGVkOiBcIiR7dGhpcy5zb3VyY2VGb3JOb2RlKHBhcnRpYWwsIHBhcnRpYWwubmFtZSl9XCIgYXQgTCR7bG9jLnN0YXJ0LmxpbmV9OkMke2xvYy5zdGFydC5jb2x1bW59YCwgcGFydGlhbC5sb2MpO1xuICAgIH1cbiAgICBQYXJ0aWFsQmxvY2tTdGF0ZW1lbnQocGFydGlhbEJsb2NrKSB7XG4gICAgICAgIGxldCB7IGxvYyB9ID0gcGFydGlhbEJsb2NrO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEhhbmRsZWJhcnMgcGFydGlhbCBibG9ja3MgYXJlIG5vdCBzdXBwb3J0ZWQ6IFwiJHt0aGlzLnNvdXJjZUZvck5vZGUocGFydGlhbEJsb2NrLCBwYXJ0aWFsQmxvY2submFtZSl9XCIgYXQgTCR7bG9jLnN0YXJ0LmxpbmV9OkMke2xvYy5zdGFydC5jb2x1bW59YCwgcGFydGlhbEJsb2NrLmxvYyk7XG4gICAgfVxuICAgIERlY29yYXRvcihkZWNvcmF0b3IpIHtcbiAgICAgICAgbGV0IHsgbG9jIH0gPSBkZWNvcmF0b3I7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgSGFuZGxlYmFycyBkZWNvcmF0b3JzIGFyZSBub3Qgc3VwcG9ydGVkOiBcIiR7dGhpcy5zb3VyY2VGb3JOb2RlKGRlY29yYXRvciwgZGVjb3JhdG9yLnBhdGgpfVwiIGF0IEwke2xvYy5zdGFydC5saW5lfTpDJHtsb2Muc3RhcnQuY29sdW1ufWAsIGRlY29yYXRvci5sb2MpO1xuICAgIH1cbiAgICBEZWNvcmF0b3JCbG9jayhkZWNvcmF0b3JCbG9jaykge1xuICAgICAgICBsZXQgeyBsb2MgfSA9IGRlY29yYXRvckJsb2NrO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEhhbmRsZWJhcnMgZGVjb3JhdG9yIGJsb2NrcyBhcmUgbm90IHN1cHBvcnRlZDogXCIke3RoaXMuc291cmNlRm9yTm9kZShkZWNvcmF0b3JCbG9jaywgZGVjb3JhdG9yQmxvY2sucGF0aCl9XCIgYXQgTCR7bG9jLnN0YXJ0LmxpbmV9OkMke2xvYy5zdGFydC5jb2x1bW59YCwgZGVjb3JhdG9yQmxvY2subG9jKTtcbiAgICB9XG4gICAgU3ViRXhwcmVzc2lvbihzZXhwcikge1xuICAgICAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCBzZXhwcik7XG4gICAgICAgIHJldHVybiBiLnNleHByKHBhdGgsIHBhcmFtcywgaGFzaCwgc2V4cHIubG9jKTtcbiAgICB9XG4gICAgUGF0aEV4cHJlc3Npb24ocGF0aCkge1xuICAgICAgICBsZXQgeyBvcmlnaW5hbCwgbG9jIH0gPSBwYXRoO1xuICAgICAgICBsZXQgcGFydHM7XG4gICAgICAgIGlmIChvcmlnaW5hbC5pbmRleE9mKCcvJykgIT09IC0xKSB7XG4gICAgICAgICAgICBpZiAob3JpZ2luYWwuc2xpY2UoMCwgMikgPT09ICcuLycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYFVzaW5nIFwiLi9cIiBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXIgYW5kIHVubmVjZXNzYXJ5OiBcIiR7cGF0aC5vcmlnaW5hbH1cIiBvbiBsaW5lICR7bG9jLnN0YXJ0LmxpbmV9LmAsIHBhdGgubG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcmlnaW5hbC5zbGljZSgwLCAzKSA9PT0gJy4uLycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYENoYW5naW5nIGNvbnRleHQgdXNpbmcgXCIuLi9cIiBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXI6IFwiJHtwYXRoLm9yaWdpbmFsfVwiIG9uIGxpbmUgJHtsb2Muc3RhcnQubGluZX0uYCwgcGF0aC5sb2MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9yaWdpbmFsLmluZGV4T2YoJy4nKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYE1peGluZyAnLicgYW5kICcvJyBpbiBwYXRocyBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXI7IHVzZSBvbmx5ICcuJyB0byBzZXBhcmF0ZSBwcm9wZXJ0eSBwYXRoczogXCIke3BhdGgub3JpZ2luYWx9XCIgb24gbGluZSAke2xvYy5zdGFydC5saW5lfS5gLCBwYXRoLmxvYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJ0cyA9IFtwYXRoLnBhcnRzLmpvaW4oJy8nKV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJ0cyA9IHBhdGgucGFydHM7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRoaXNIZWFkID0gZmFsc2U7XG4gICAgICAgIC8vIFRoaXMgaXMgdG8gZml4IGEgYnVnIGluIHRoZSBIYW5kbGViYXJzIEFTVCB3aGVyZSB0aGUgcGF0aCBleHByZXNzaW9ucyBpblxuICAgICAgICAvLyBge3t0aGlzLmZvb319YCAoYW5kIHNpbWlsYXJseSBge3tmb28tYmFyIHRoaXMuZm9vIG5hbWVkPXRoaXMuZm9vfX1gIGV0YylcbiAgICAgICAgLy8gYXJlIHNpbXBseSB0dXJuZWQgaW50byBge3tmb299fWAuIFRoZSBmaXggaXMgdG8gcHVzaCBpdCBiYWNrIG9udG8gdGhlXG4gICAgICAgIC8vIHBhcnRzIGFycmF5IGFuZCBsZXQgdGhlIHJ1bnRpbWUgc2VlIHRoZSBkaWZmZXJlbmNlLiBIb3dldmVyLCB3ZSBjYW5ub3RcbiAgICAgICAgLy8gc2ltcGx5IHVzZSB0aGUgc3RyaW5nIGB0aGlzYCBhcyBpdCBtZWFucyBsaXRlcmFsbHkgdGhlIHByb3BlcnR5IGNhbGxlZFxuICAgICAgICAvLyBcInRoaXNcIiBpbiB0aGUgY3VycmVudCBjb250ZXh0IChpdCBjYW4gYmUgZXhwcmVzc2VkIGluIHRoZSBzeW50YXggYXNcbiAgICAgICAgLy8gYHt7W3RoaXNdfX1gLCB3aGVyZSB0aGUgc3F1YXJlIGJyYWNrZXQgYXJlIGdlbmVyYWxseSBmb3IgdGhpcyBraW5kIG9mXG4gICAgICAgIC8vIGVzY2FwaW5nIOKAkyBzdWNoIGFzIGB7e2Zvby5bXCJiYXIuYmF6XCJdfX1gIHdvdWxkIG1lYW4gbG9va3VwIGEgcHJvcGVydHlcbiAgICAgICAgLy8gbmFtZWQgbGl0ZXJhbGx5IFwiYmFyLmJhelwiIG9uIGB0aGlzLmZvb2ApLiBCeSBjb252ZW50aW9uLCB3ZSB1c2UgYG51bGxgXG4gICAgICAgIC8vIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgICAgIGlmIChvcmlnaW5hbC5tYXRjaCgvXnRoaXMoXFwuLispPyQvKSkge1xuICAgICAgICAgICAgdGhpc0hlYWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnUGF0aEV4cHJlc3Npb24nLFxuICAgICAgICAgICAgb3JpZ2luYWw6IHBhdGgub3JpZ2luYWwsXG4gICAgICAgICAgICB0aGlzOiB0aGlzSGVhZCxcbiAgICAgICAgICAgIHBhcnRzLFxuICAgICAgICAgICAgZGF0YTogcGF0aC5kYXRhLFxuICAgICAgICAgICAgbG9jOiBwYXRoLmxvY1xuICAgICAgICB9O1xuICAgIH1cbiAgICBIYXNoKGhhc2gpIHtcbiAgICAgICAgbGV0IHBhaXJzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGFzaC5wYWlycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHBhaXIgPSBoYXNoLnBhaXJzW2ldO1xuICAgICAgICAgICAgcGFpcnMucHVzaChiLnBhaXIocGFpci5rZXksIHRoaXMuYWNjZXB0Tm9kZShwYWlyLnZhbHVlKSwgcGFpci5sb2MpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYi5oYXNoKHBhaXJzLCBoYXNoLmxvYyk7XG4gICAgfVxuICAgIFN0cmluZ0xpdGVyYWwoc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBiLmxpdGVyYWwoJ1N0cmluZ0xpdGVyYWwnLCBzdHJpbmcudmFsdWUsIHN0cmluZy5sb2MpO1xuICAgIH1cbiAgICBCb29sZWFuTGl0ZXJhbChib29sZWFuKSB7XG4gICAgICAgIHJldHVybiBiLmxpdGVyYWwoJ0Jvb2xlYW5MaXRlcmFsJywgYm9vbGVhbi52YWx1ZSwgYm9vbGVhbi5sb2MpO1xuICAgIH1cbiAgICBOdW1iZXJMaXRlcmFsKG51bWJlcikge1xuICAgICAgICByZXR1cm4gYi5saXRlcmFsKCdOdW1iZXJMaXRlcmFsJywgbnVtYmVyLnZhbHVlLCBudW1iZXIubG9jKTtcbiAgICB9XG4gICAgVW5kZWZpbmVkTGl0ZXJhbCh1bmRlZikge1xuICAgICAgICByZXR1cm4gYi5saXRlcmFsKCdVbmRlZmluZWRMaXRlcmFsJywgdW5kZWZpbmVkLCB1bmRlZi5sb2MpO1xuICAgIH1cbiAgICBOdWxsTGl0ZXJhbChudWwpIHtcbiAgICAgICAgcmV0dXJuIGIubGl0ZXJhbCgnTnVsbExpdGVyYWwnLCBudWxsLCBudWwubG9jKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjYWxjdWxhdGVSaWdodFN0cmlwcGVkT2Zmc2V0cyhvcmlnaW5hbCwgdmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgIC8vIGlmIGl0IGlzIGVtcHR5LCBqdXN0IHJldHVybiB0aGUgY291bnQgb2YgbmV3bGluZXNcbiAgICAgICAgLy8gaW4gb3JpZ2luYWxcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxpbmVzOiBvcmlnaW5hbC5zcGxpdChcIlxcblwiKS5sZW5ndGggLSAxLFxuICAgICAgICAgICAgY29sdW1uczogMFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBvdGhlcndpc2UsIHJldHVybiB0aGUgbnVtYmVyIG9mIG5ld2xpbmVzIHByaW9yIHRvXG4gICAgLy8gYHZhbHVlYFxuICAgIGxldCBkaWZmZXJlbmNlID0gb3JpZ2luYWwuc3BsaXQodmFsdWUpWzBdO1xuICAgIGxldCBsaW5lcyA9IGRpZmZlcmVuY2Uuc3BsaXQoL1xcbi8pO1xuICAgIGxldCBsaW5lQ291bnQgPSBsaW5lcy5sZW5ndGggLSAxO1xuICAgIHJldHVybiB7XG4gICAgICAgIGxpbmVzOiBsaW5lQ291bnQsXG4gICAgICAgIGNvbHVtbnM6IGxpbmVzW2xpbmVDb3VudF0ubGVuZ3RoXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZVRva2VuaXplckxvY2F0aW9uKHRva2VuaXplciwgY29udGVudCkge1xuICAgIGxldCBsaW5lID0gY29udGVudC5sb2Muc3RhcnQubGluZTtcbiAgICBsZXQgY29sdW1uID0gY29udGVudC5sb2Muc3RhcnQuY29sdW1uO1xuICAgIGxldCBvZmZzZXRzID0gY2FsY3VsYXRlUmlnaHRTdHJpcHBlZE9mZnNldHMoY29udGVudC5vcmlnaW5hbCwgY29udGVudC52YWx1ZSk7XG4gICAgbGluZSA9IGxpbmUgKyBvZmZzZXRzLmxpbmVzO1xuICAgIGlmIChvZmZzZXRzLmxpbmVzKSB7XG4gICAgICAgIGNvbHVtbiA9IG9mZnNldHMuY29sdW1ucztcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW4gPSBjb2x1bW4gKyBvZmZzZXRzLmNvbHVtbnM7XG4gICAgfVxuICAgIHRva2VuaXplci5saW5lID0gbGluZTtcbiAgICB0b2tlbml6ZXIuY29sdW1uID0gY29sdW1uO1xufVxuZnVuY3Rpb24gYWNjZXB0Q2FsbE5vZGVzKGNvbXBpbGVyLCBub2RlKSB7XG4gICAgbGV0IHBhdGggPSBjb21waWxlci5QYXRoRXhwcmVzc2lvbihub2RlLnBhdGgpO1xuICAgIGxldCBwYXJhbXMgPSBub2RlLnBhcmFtcyA/IG5vZGUucGFyYW1zLm1hcChlID0+IGNvbXBpbGVyLmFjY2VwdE5vZGUoZSkpIDogW107XG4gICAgbGV0IGhhc2ggPSBub2RlLmhhc2ggPyBjb21waWxlci5IYXNoKG5vZGUuaGFzaCkgOiBiLmhhc2goKTtcbiAgICByZXR1cm4geyBwYXRoLCBwYXJhbXMsIGhhc2ggfTtcbn1cbmZ1bmN0aW9uIGFkZEVsZW1lbnRNb2RpZmllcihlbGVtZW50LCBtdXN0YWNoZSkge1xuICAgIGxldCB7IHBhdGgsIHBhcmFtcywgaGFzaCwgbG9jIH0gPSBtdXN0YWNoZTtcbiAgICBpZiAoaXNMaXRlcmFsKHBhdGgpKSB7XG4gICAgICAgIGxldCBtb2RpZmllciA9IGB7eyR7cHJpbnRMaXRlcmFsKHBhdGgpfX19YDtcbiAgICAgICAgbGV0IHRhZyA9IGA8JHtlbGVtZW50Lm5hbWV9IC4uLiAke21vZGlmaWVyfSAuLi5gO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEluICR7dGFnfSwgJHttb2RpZmllcn0gaXMgbm90IGEgdmFsaWQgbW9kaWZpZXI6IFwiJHtwYXRoLm9yaWdpbmFsfVwiIG9uIGxpbmUgJHtsb2MgJiYgbG9jLnN0YXJ0LmxpbmV9LmAsIG11c3RhY2hlLmxvYyk7XG4gICAgfVxuICAgIGxldCBtb2RpZmllciA9IGIuZWxlbWVudE1vZGlmaWVyKHBhdGgsIHBhcmFtcywgaGFzaCwgbG9jKTtcbiAgICBlbGVtZW50Lm1vZGlmaWVycy5wdXNoKG1vZGlmaWVyKTtcbn1cbmZ1bmN0aW9uIGFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQoYXR0cmlidXRlLCBwYXJ0KSB7XG4gICAgYXR0cmlidXRlLmlzRHluYW1pYyA9IHRydWU7XG4gICAgYXR0cmlidXRlLnBhcnRzLnB1c2gocGFydCk7XG59Il19