ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
326 lines (288 loc) • 44.8 kB
JavaScript
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); }
import b from "../builders";
import { appendChild, isLiteral, printLiteral } from "../utils";
import { Parser } from '../parser';
import SyntaxError from '../errors/syntax-error';
export var 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 = b.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 SyntaxError("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 SyntaxError("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 = b.block(path, params, hash, program, inverse, block.loc);
var parentProgram = this.currentElement();
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: b.hash(),
escaped: escaped,
loc: loc
};
} else {
var _acceptCallNodes2 = acceptCallNodes(this, rawMustache),
path = _acceptCallNodes2.path,
params = _acceptCallNodes2.params,
hash = _acceptCallNodes2.hash;
mustache = b.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:
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 = b.mustacheComment(value, loc);
switch (tokenizer.state) {
case "beforeAttributeName":
this.currentStartTag.comments.push(comment);
break;
case 'beforeData':
case 'data':
appendChild(this.currentElement(), comment);
break;
default:
throw new SyntaxError("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 SyntaxError("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 SyntaxError("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 SyntaxError("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 SyntaxError("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 b.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 SyntaxError("Using \"./\" is not supported in Glimmer and unnecessary: \"" + path.original + "\" on line " + loc.start.line + ".", path.loc);
}
if (original.slice(0, 3) === '../') {
throw new SyntaxError("Changing context using \"../\" is not supported in Glimmer: \"" + path.original + "\" on line " + loc.start.line + ".", path.loc);
}
if (original.indexOf('.') !== -1) {
throw new SyntaxError("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(b.pair(pair.key, this.acceptNode(pair.value), pair.loc));
}
return b.hash(pairs, hash.loc);
};
HandlebarsNodeVisitors.prototype.StringLiteral = function StringLiteral(string) {
return b.literal('StringLiteral', string.value, string.loc);
};
HandlebarsNodeVisitors.prototype.BooleanLiteral = function BooleanLiteral(boolean) {
return b.literal('BooleanLiteral', boolean.value, boolean.loc);
};
HandlebarsNodeVisitors.prototype.NumberLiteral = function NumberLiteral(number) {
return b.literal('NumberLiteral', number.value, number.loc);
};
HandlebarsNodeVisitors.prototype.UndefinedLiteral = function UndefinedLiteral(undef) {
return b.literal('UndefinedLiteral', undefined, undef.loc);
};
HandlebarsNodeVisitors.prototype.NullLiteral = function NullLiteral(nul) {
return b.literal('NullLiteral', null, nul.loc);
};
return HandlebarsNodeVisitors;
}(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) : b.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 (isLiteral(path)) {
var _modifier = "{{" + printLiteral(path) + "}}";
var tag = "<" + element.name + " ... " + _modifier + " ...";
throw new SyntaxError("In " + tag + ", " + _modifier + " is not a valid modifier: \"" + path.original + "\" on line " + (loc && loc.start.line) + ".", mustache.loc);
}
var modifier = b.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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9wYXJzZXIvaGFuZGxlYmFycy1ub2RlLXZpc2l0b3JzLmpzIl0sIm5hbWVzIjpbImIiLCJhcHBlbmRDaGlsZCIsImlzTGl0ZXJhbCIsInByaW50TGl0ZXJhbCIsIlBhcnNlciIsIlN5bnRheEVycm9yIiwiSGFuZGxlYmFyc05vZGVWaXNpdG9ycyIsIlByb2dyYW0iLCJwcm9ncmFtIiwiYm9keSIsIm5vZGUiLCJibG9ja1BhcmFtcyIsImxvYyIsImkiLCJsIiwibGVuZ3RoIiwiZWxlbWVudFN0YWNrIiwicHVzaCIsInBvcCIsImFjY2VwdE5vZGUiLCJwb3BwZWROb2RlIiwiZWxlbWVudE5vZGUiLCJ0YWciLCJzdGFydCIsImxpbmUiLCJCbG9ja1N0YXRlbWVudCIsImJsb2NrIiwidG9rZW5pemVyIiwiYXBwZW5kVG9Db21tZW50RGF0YSIsInNvdXJjZUZvck5vZGUiLCJhY2NlcHRDYWxsTm9kZXMiLCJwYXRoIiwicGFyYW1zIiwiaGFzaCIsImludmVyc2UiLCJwYXJlbnRQcm9ncmFtIiwiY3VycmVudEVsZW1lbnQiLCJNdXN0YWNoZVN0YXRlbWVudCIsInJhd011c3RhY2hlIiwibXVzdGFjaGUiLCJlc2NhcGVkIiwidHlwZSIsIm1hdGNoIiwic3RhdGUiLCJhZGRFbGVtZW50TW9kaWZpZXIiLCJjdXJyZW50U3RhcnRUYWciLCJiZWdpbkF0dHJpYnV0ZVZhbHVlIiwiZmluaXNoQXR0cmlidXRlVmFsdWUiLCJhcHBlbmREeW5hbWljQXR0cmlidXRlVmFsdWVQYXJ0IiwiY3VycmVudEF0dHJpYnV0ZSIsIkNvbnRlbnRTdGF0ZW1lbnQiLCJjb250ZW50IiwidXBkYXRlVG9rZW5pemVyTG9jYXRpb24iLCJ0b2tlbml6ZVBhcnQiLCJ2YWx1ZSIsImZsdXNoRGF0YSIsIkNvbW1lbnRTdGF0ZW1lbnQiLCJyYXdDb21tZW50IiwiY29tbWVudCIsIm11c3RhY2hlQ29tbWVudCIsImNvbW1lbnRzIiwiY29sdW1uIiwiUGFydGlhbFN0YXRlbWVudCIsInBhcnRpYWwiLCJuYW1lIiwiUGFydGlhbEJsb2NrU3RhdGVtZW50IiwicGFydGlhbEJsb2NrIiwiRGVjb3JhdG9yIiwiZGVjb3JhdG9yIiwiRGVjb3JhdG9yQmxvY2siLCJkZWNvcmF0b3JCbG9jayIsIlN1YkV4cHJlc3Npb24iLCJzZXhwciIsIlBhdGhFeHByZXNzaW9uIiwib3JpZ2luYWwiLCJwYXJ0cyIsImluZGV4T2YiLCJzbGljZSIsImpvaW4iLCJ0aGlzSGVhZCIsInRoaXMiLCJkYXRhIiwiSGFzaCIsInBhaXJzIiwicGFpciIsImtleSIsIlN0cmluZ0xpdGVyYWwiLCJzdHJpbmciLCJsaXRlcmFsIiwiQm9vbGVhbkxpdGVyYWwiLCJib29sZWFuIiwiTnVtYmVyTGl0ZXJhbCIsIm51bWJlciIsIlVuZGVmaW5lZExpdGVyYWwiLCJ1bmRlZiIsInVuZGVmaW5lZCIsIk51bGxMaXRlcmFsIiwibnVsIiwiY2FsY3VsYXRlUmlnaHRTdHJpcHBlZE9mZnNldHMiLCJsaW5lcyIsInNwbGl0IiwiY29sdW1ucyIsImRpZmZlcmVuY2UiLCJsaW5lQ291bnQiLCJvZmZzZXRzIiwiY29tcGlsZXIiLCJtYXAiLCJlIiwiZWxlbWVudCIsIm1vZGlmaWVyIiwiZWxlbWVudE1vZGlmaWVyIiwibW9kaWZpZXJzIiwiYXR0cmlidXRlIiwicGFydCIsImlzRHluYW1pYyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQSxPQUFPQSxDQUFQLE1BQWMsYUFBZDtBQUNBLFNBQVNDLFdBQVQsRUFBc0JDLFNBQXRCLEVBQWlDQyxZQUFqQyxRQUFxRCxVQUFyRDtBQUNBLFNBQVNDLE1BQVQsUUFBdUIsV0FBdkI7QUFDQSxPQUFPQyxXQUFQLE1BQXdCLHdCQUF4QjtBQUNBLFdBQWFDLHNCQUFiO0FBQUE7O0FBQUE7QUFBQTs7QUFBQTtBQUFBOztBQUFBLHFDQUNJQyxPQURKLG9CQUNZQyxPQURaLEVBQ3FCO0FBQ2IsWUFBSUMsT0FBTyxFQUFYO0FBQ0EsWUFBSUMsT0FBT1YsRUFBRVEsT0FBRixDQUFVQyxJQUFWLEVBQWdCRCxRQUFRRyxXQUF4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QXNCaUIsR0FBdEIsVUFBOEJ1RixTQUE5QixvQ0FBb0U5RSxLQUFLMkMsUUFBekUsb0JBQThGOUQsT0FBT0EsSUFBSVcsS0FBSixDQUFVQyxJQUEvRyxTQUF3SGUsU0FBUzNCLEdBQWpJLENBQU47QUFDSDtBQUNELFFBQUlpRyxXQUFXN0csRUFBRThHLGVBQUYsQ0FBa0IvRSxJQUFsQixFQUF3QkMsTUFBeEIsRUFBZ0NDLElBQWhDLEVBQXNDckIsR0FBdEMsQ0FBZjtBQUNBZ0csWUFBUUcsU0FBUixDQUFrQjlGLElBQWxCLENBQXVCNEYsUUFBdkI7QUFDSDtBQUNELFNBQVM3RCwrQkFBVCxDQUF5Q2dFLFNBQXpDLEVBQW9EQyxJQUFwRCxFQUEwRDtBQUN0REQsY0FBVUUsU0FBVixHQUFzQixJQUF0QjtBQUNBRixjQUFVckMsS0FBVixDQUFnQjFELElBQWhCLENBQXFCZ0csSUFBckI7QUFDSCIsImZpbGUiOiJsaWIvcGFyc2VyL2hhbmRsZWJhcnMtbm9kZS12aXNpdG9ycy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBiIGZyb20gXCIuLi9idWlsZGVyc1wiO1xuaW1wb3J0IHsgYXBwZW5kQ2hpbGQsIGlzTGl0ZXJhbCwgcHJpbnRMaXRlcmFsIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBQYXJzZXIgfSBmcm9tICcuLi9wYXJzZXInO1xuaW1wb3J0IFN5bnRheEVycm9yIGZyb20gJy4uL2Vycm9ycy9zeW50YXgtZXJyb3InO1xuZXhwb3J0IGNsYXNzIEhhbmRsZWJhcnNOb2RlVmlzaXRvcnMgZXh0ZW5kcyBQYXJzZXIge1xuICAgIFByb2dyYW0ocHJvZ3JhbSkge1xuICAgICAgICBsZXQgYm9keSA9IFtdO1xuICAgICAgICBsZXQgbm9kZSA9IGIucHJvZ3JhbShib2R5LCBwcm9ncmFtLmJsb2NrUGFyYW1zLCBwcm9ncmFtLmxvYyk7XG4gICAgICAgIGxldCBpLFxuICAgICAgICAgICAgbCA9IHByb2dyYW0uYm9keS5sZW5ndGg7XG4gICAgICAgIHRoaXMuZWxlbWVudFN0YWNrLnB1c2gobm9kZSk7XG4gICAgICAgIGlmIChsID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50U3RhY2sucG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5hY2NlcHROb2RlKHByb2dyYW0uYm9keVtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhhdCB0aGUgZWxlbWVudCBzdGFjayBpcyBiYWxhbmNlZCBwcm9wZXJseS5cbiAgICAgICAgbGV0IHBvcHBlZE5vZGUgPSB0aGlzLmVsZW1lbnRTdGFjay5wb3AoKTtcbiAgICAgICAgaWYgKHBvcHBlZE5vZGUgIT09IG5vZGUpIHtcbiAgICAgICAgICAgIGxldCBlbGVtZW50Tm9kZSA9IHBvcHBlZE5vZGU7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJVbmNsb3NlZCBlbGVtZW50IGBcIiArIGVsZW1lbnROb2RlLnRhZyArIFwiYCAob24gbGluZSBcIiArIGVsZW1lbnROb2RlLmxvYy5zdGFydC5saW5lICsgXCIpLlwiLCBlbGVtZW50Tm9kZS5sb2MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICBCbG9ja1N0YXRlbWVudChibG9jaykge1xuICAgICAgICBpZiAodGhpcy50b2tlbml6ZXJbJ3N0YXRlJ10gPT09ICdjb21tZW50Jykge1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRUb0NvbW1lbnREYXRhKHRoaXMuc291cmNlRm9yTm9kZShibG9jaykpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRva2VuaXplclsnc3RhdGUnXSAhPT0gJ2NvbW1lbnQnICYmIHRoaXMudG9rZW5pemVyWydzdGF0ZSddICE9PSAnZGF0YScgJiYgdGhpcy50b2tlbml6ZXJbJ3N0YXRlJ10gIT09ICdiZWZvcmVEYXRhJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiQSBibG9jayBtYXkgb25seSBiZSB1c2VkIGluc2lkZSBhbiBIVE1MIGVsZW1lbnQgb3IgYW5vdGhlciBibG9jay5cIiwgYmxvY2subG9jKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCBibG9jayk7XG4gICAgICAgIGxldCBwcm9ncmFtID0gdGhpcy5Qcm9ncmFtKGJsb2NrLnByb2dyYW0pO1xuICAgICAgICBsZXQgaW52ZXJzZSA9IGJsb2NrLmludmVyc2UgPyB0aGlzLlByb2dyYW0oYmxvY2suaW52ZXJzZSkgOiBudWxsO1xuICAgICAgICBsZXQgbm9kZSA9IGIuYmxvY2socGF0aCwgcGFyYW1zLCBoYXNoLCBwcm9ncmFtLCBpbnZlcnNlLCBibG9jay5sb2MpO1xuICAgICAgICBsZXQgcGFyZW50UHJvZ3JhbSA9IHRoaXMuY3VycmVudEVsZW1lbnQoKTtcbiAgICAgICAgYXBwZW5kQ2hpbGQocGFyZW50UHJvZ3JhbSwgbm9kZSk7XG4gICAgfVxuICAgIE11c3RhY2hlU3RhdGVtZW50KHJhd011c3RhY2hlKSB7XG4gICAgICAgIGxldCB7IHRva2VuaXplciB9ID0gdGhpcztcbiAgICAgICAgaWYgKHRva2VuaXplclsnc3RhdGUnXSA9PT0gJ2NvbW1lbnQnKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZFRvQ29tbWVudERhdGEodGhpcy5zb3VyY2VGb3JOb2RlKHJhd011c3RhY2hlKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG11c3RhY2hlO1xuICAgICAgICBsZXQgeyBlc2NhcGVkLCBsb2MgfSA9IHJhd011c3RhY2hlO1xuICAgICAgICBpZiAocmF3TXVzdGFjaGUucGF0aC50eXBlLm1hdGNoKC9MaXRlcmFsJC8pKSB7XG4gICAgICAgICAgICBtdXN0YWNoZSA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnTXVzdGFjaGVTdGF0ZW1lbnQnLFxuICAgICAgICAgICAgICAgIHBhdGg6IHRoaXMuYWNjZXB0Tm9kZShyYXdNdXN0YWNoZS5wYXRoKSxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICAgICAgICAgIGhhc2g6IGIuaGFzaCgpLFxuICAgICAgICAgICAgICAgIGVzY2FwZWQsXG4gICAgICAgICAgICAgICAgbG9jXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IHsgcGF0aCwgcGFyYW1zLCBoYXNoIH0gPSBhY2NlcHRDYWxsTm9kZXModGhpcywgcmF3TXVzdGFjaGUpO1xuICAgICAgICAgICAgbXVzdGFjaGUgPSBiLm11c3RhY2hlKHBhdGgsIHBhcmFtcywgaGFzaCwgIWVzY2FwZWQsIGxvYyk7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoICh0b2tlbml6ZXIuc3RhdGUpIHtcbiAgICAgICAgICAgIC8vIFRhZyBoZWxwZXJzXG4gICAgICAgICAgICBjYXNlIFwidGFnTmFtZVwiOlxuICAgICAgICAgICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIHRva2VuaXplci5zdGF0ZSA9IFwiYmVmb3JlQXR0cmlidXRlTmFtZVwiO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImJlZm9yZUF0dHJpYnV0ZU5hbWVcIjpcbiAgICAgICAgICAgICAgICBhZGRFbGVtZW50TW9kaWZpZXIodGhpcy5jdXJyZW50U3RhcnRUYWcsIG11c3RhY2hlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJhdHRyaWJ1dGVOYW1lXCI6XG4gICAgICAgICAgICBjYXNlIFwiYWZ0ZXJBdHRyaWJ1dGVOYW1lXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5iZWdpbkF0dHJpYnV0ZVZhbHVlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbmlzaEF0dHJpYnV0ZVZhbHVlKCk7XG4gICAgICAgICAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgICAgICAgICAgdG9rZW5pemVyLnN0YXRlID0gXCJiZWZvcmVBdHRyaWJ1dGVOYW1lXCI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiYWZ0ZXJBdHRyaWJ1dGVWYWx1ZVF1b3RlZFwiOlxuICAgICAgICAgICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIHRva2VuaXplci5zdGF0ZSA9IFwiYmVmb3JlQXR0cmlidXRlTmFtZVwiO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgLy8gQXR0cmlidXRlIHZhbHVlc1xuICAgICAgICAgICAgY2FzZSBcImJlZm9yZUF0dHJpYnV0ZVZhbHVlXCI6XG4gICAgICAgICAgICAgICAgYXBwZW5kRHluYW1pY0F0dHJpYnV0ZVZhbHVlUGFydCh0aGlzLmN1cnJlbnRBdHRyaWJ1dGUsIG11c3RhY2hlKTtcbiAgICAgICAgICAgICAgICB0b2tlbml6ZXIuc3RhdGUgPSAnYXR0cmlidXRlVmFsdWVVbnF1b3RlZCc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiYXR0cmlidXRlVmFsdWVEb3VibGVRdW90ZWRcIjpcbiAgICAgICAgICAgIGNhc2UgXCJhdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3RlZFwiOlxuICAgICAgICAgICAgY2FzZSBcImF0dHJpYnV0ZVZhbHVlVW5xdW90ZWRcIjpcbiAgICAgICAgICAgICAgICBhcHBlbmREeW5hbWljQXR0cmlidXRlVmFsdWVQYXJ0KHRoaXMuY3VycmVudEF0dHJpYnV0ZSwgbXVzdGFjaGUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgLy8gVE9ETzogT25seSBhcHBlbmQgY2hpbGQgd2hlbiB0aGUgdG9rZW5pemVyIHN0YXRlIG1ha2VzXG4gICAgICAgICAgICAvLyBzZW5zZSB0byBkbyBzbywgb3RoZXJ3aXNlIHRocm93IGFuIGVycm9yLlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBhcHBlbmRDaGlsZCh0aGlzLmN1cnJlbnRFbGVtZW50KCksIG11c3RhY2hlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXVzdGFjaGU7XG4gICAgfVxuICAgIENvbnRlbnRTdGF0ZW1lbnQoY29udGVudCkge1xuICAgICAgICB1cGRhdGVUb2tlbml6ZXJMb2NhdGlvbih0aGlzLnRva2VuaXplciwgY29udGVudCk7XG4gICAgICAgIHRoaXMudG9rZW5pemVyLnRva2VuaXplUGFydChjb250ZW50LnZhbHVlKTtcbiAgICAgICAgdGhpcy50b2tlbml6ZXIuZmx1c2hEYXRhKCk7XG4gICAgfVxuICAgIENvbW1lbnRTdGF0ZW1lbnQocmF3Q29tbWVudCkge1xuICAgICAgICBsZXQgeyB0b2tlbml6ZXIgfSA9IHRoaXM7XG4gICAgICAgIGlmICh0b2tlbml6ZXIuc3RhdGUgPT09ICdjb21tZW50Jykge1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRUb0NvbW1lbnREYXRhKHRoaXMuc291cmNlRm9yTm9kZShyYXdDb21tZW50KSk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyB2YWx1ZSwgbG9jIH0gPSByYXdDb21tZW50O1xuICAgICAgICBsZXQgY29tbWVudCA9IGIubXVzdGFjaGVDb21tZW50KHZhbHVlLCBsb2MpO1xuICAgICAgICBzd2l0Y2ggKHRva2VuaXplci5zdGF0ZSkge1xuICAgICAgICAgICAgY2FzZSBcImJlZm9yZUF0dHJpYnV0ZU5hbWVcIjpcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGFydFRhZy5jb21tZW50cy5wdXNoKGNvbW1lbnQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYmVmb3JlRGF0YSc6XG4gICAgICAgICAgICBjYXNlICdkYXRhJzpcbiAgICAgICAgICAgICAgICBhcHBlbmRDaGlsZCh0aGlzLmN1cnJlbnRFbGVtZW50KCksIGNvbW1lbnQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYFVzaW5nIGEgSGFuZGxlYmFycyBjb21tZW50IHdoZW4gaW4gdGhlIFxcYCR7dG9rZW5pemVyLnN0YXRlfVxcYCBzdGF0ZSBpcyBub3Qgc3VwcG9ydGVkOiBcIiR7Y29tbWVudC52YWx1ZX1cIiBvbiBsaW5lICR7bG9jLnN0YXJ0LmxpbmV9OiR7bG9jLnN0YXJ0LmNvbHVtbn1gLCByYXdDb21tZW50LmxvYyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbW1lbnQ7XG4gICAgfVxuICAgIFBhcnRpYWxTdGF0ZW1lbnQocGFydGlhbCkge1xuICAgICAgICBsZXQgeyBsb2MgfSA9IHBhcnRpYWw7XG4gICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgSGFuZGxlYmFycyBwYXJ0aWFscyBhcmUgbm90IHN1cHBvcnRlZDogXCIke3RoaXMuc291cmNlRm9yTm9kZShwYXJ0aWFsLCBwYXJ0aWFsLm5hbWUpfVwiIGF0IEwke2xvYy5zdGFydC5saW5lfTpDJHtsb2Muc3RhcnQuY29sdW1ufWAsIHBhcnRpYWwubG9jKTtcbiAgICB9XG4gICAgUGFydGlhbEJsb2NrU3RhdGVtZW50KHBhcnRpYWxCbG9jaykge1xuICAgICAgICBsZXQgeyBsb2MgfSA9IHBhcnRpYWxCbG9jaztcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBIYW5kbGViYXJzIHBhcnRpYWwgYmxvY2tzIGFyZSBub3Qgc3VwcG9ydGVkOiBcIiR7dGhpcy5zb3VyY2VGb3JOb2RlKHBhcnRpYWxCbG9jaywgcGFydGlhbEJsb2NrLm5hbWUpfVwiIGF0IEwke2xvYy5zdGFydC5saW5lfTpDJHtsb2Muc3RhcnQuY29sdW1ufWAsIHBhcnRpYWxCbG9jay5sb2MpO1xuICAgIH1cbiAgICBEZWNvcmF0b3IoZGVjb3JhdG9yKSB7XG4gICAgICAgIGxldCB7IGxvYyB9ID0gZGVjb3JhdG9yO1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYEhhbmRsZWJhcnMgZGVjb3JhdG9ycyBhcmUgbm90IHN1cHBvcnRlZDogXCIke3RoaXMuc291cmNlRm9yTm9kZShkZWNvcmF0b3IsIGRlY29yYXRvci5wYXRoKX1cIiBhdCBMJHtsb2Muc3RhcnQubGluZX06QyR7bG9jLnN0YXJ0LmNvbHVtbn1gLCBkZWNvcmF0b3IubG9jKTtcbiAgICB9XG4gICAgRGVjb3JhdG9yQmxvY2soZGVjb3JhdG9yQmxvY2spIHtcbiAgICAgICAgbGV0IHsgbG9jIH0gPSBkZWNvcmF0b3JCbG9jaztcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBIYW5kbGViYXJzIGRlY29yYXRvciBibG9ja3MgYXJlIG5vdCBzdXBwb3J0ZWQ6IFwiJHt0aGlzLnNvdXJjZUZvck5vZGUoZGVjb3JhdG9yQmxvY2ssIGRlY29yYXRvckJsb2NrLnBhdGgpfVwiIGF0IEwke2xvYy5zdGFydC5saW5lfTpDJHtsb2Muc3RhcnQuY29sdW1ufWAsIGRlY29yYXRvckJsb2NrLmxvYyk7XG4gICAgfVxuICAgIFN1YkV4cHJlc3Npb24oc2V4cHIpIHtcbiAgICAgICAgbGV0IHsgcGF0aCwgcGFyYW1zLCBoYXNoIH0gPSBhY2NlcHRDYWxsTm9kZXModGhpcywgc2V4cHIpO1xuICAgICAgICByZXR1cm4gYi5zZXhwcihwYXRoLCBwYXJhbXMsIGhhc2gsIHNleHByLmxvYyk7XG4gICAgfVxuICAgIFBhdGhFeHByZXNzaW9uKHBhdGgpIHtcbiAgICAgICAgbGV0IHsgb3JpZ2luYWwsIGxvYyB9ID0gcGF0aDtcbiAgICAgICAgbGV0IHBhcnRzO1xuICAgICAgICBpZiAob3JpZ2luYWwuaW5kZXhPZignLycpICE9PSAtMSkge1xuICAgICAgICAgICAgaWYgKG9yaWdpbmFsLnNsaWNlKDAsIDIpID09PSAnLi8nKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBVc2luZyBcIi4vXCIgaXMgbm90IHN1cHBvcnRlZCBpbiBHbGltbWVyIGFuZCB1bm5lY2Vzc2FyeTogXCIke3BhdGgub3JpZ2luYWx9XCIgb24gbGluZSAke2xvYy5zdGFydC5saW5lfS5gLCBwYXRoLmxvYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3JpZ2luYWwuc2xpY2UoMCwgMykgPT09ICcuLi8nKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBDaGFuZ2luZyBjb250ZXh0IHVzaW5nIFwiLi4vXCIgaXMgbm90IHN1cHBvcnRlZCBpbiBHbGltbWVyOiBcIiR7cGF0aC5vcmlnaW5hbH1cIiBvbiBsaW5lICR7bG9jLnN0YXJ0LmxpbmV9LmAsIHBhdGgubG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcmlnaW5hbC5pbmRleE9mKCcuJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBNaXhpbmcgJy4nIGFuZCAnLycgaW4gcGF0aHMgaXMgbm90IHN1cHBvcnRlZCBpbiBHbGltbWVyOyB1c2Ugb25seSAnLicgdG8gc2VwYXJhdGUgcHJvcGVydHkgcGF0aHM6IFwiJHtwYXRoLm9yaWdpbmFsfVwiIG9uIGxpbmUgJHtsb2Muc3RhcnQubGluZX0uYCwgcGF0aC5sb2MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGFydHMgPSBbcGF0aC5wYXJ0cy5qb2luKCcvJyldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFydHMgPSBwYXRoLnBhcnRzO1xuICAgICAgICB9XG4gICAgICAgIGxldCB0aGlzSGVhZCA9IGZhbHNlO1xuICAgICAgICAvLyBUaGlzIGlzIHRvIGZpeCBhIGJ1ZyBpbiB0aGUgSGFuZGxlYmFycyBBU1Qgd2hlcmUgdGhlIHBhdGggZXhwcmVzc2lvbnMgaW5cbiAgICAgICAgLy8gYHt7dGhpcy5mb299fWAgKGFuZCBzaW1pbGFybHkgYHt7Zm9vLWJhciB0aGlzLmZvbyBuYW1lZD10aGlzLmZvb319YCBldGMpXG4gICAgICAgIC8vIGFyZSBzaW1wbHkgdHVybmVkIGludG8gYHt7Zm9vfX1gLiBUaGUgZml4IGlzIHRvIHB1c2ggaXQgYmFjayBvbnRvIHRoZVxuICAgICAgICAvLyBwYXJ0cyBhcnJheSBhbmQgbGV0IHRoZSBydW50aW1lIHNlZSB0aGUgZGlmZmVyZW5jZS4gSG93ZXZlciwgd2UgY2Fubm90XG4gICAgICAgIC8vIHNpbXBseSB1c2UgdGhlIHN0cmluZyBgdGhpc2AgYXMgaXQgbWVhbnMgbGl0ZXJhbGx5IHRoZSBwcm9wZXJ0eSBjYWxsZWRcbiAgICAgICAgLy8gXCJ0aGlzXCIgaW4gdGhlIGN1cnJlbnQgY29udGV4dCAoaXQgY2FuIGJlIGV4cHJlc3NlZCBpbiB0aGUgc3ludGF4IGFzXG4gICAgICAgIC8vIGB7e1t0aGlzXX19YCwgd2hlcmUgdGhlIHNxdWFyZSBicmFja2V0IGFyZSBnZW5lcmFsbHkgZm9yIHRoaXMga2luZCBvZlxuICAgICAgICAvLyBlc2NhcGluZyDigJMgc3VjaCBhcyBge3tmb28uW1wiYmFyLmJhelwiXX19YCB3b3VsZCBtZWFuIGxvb2t1cCBhIHByb3BlcnR5XG4gICAgICAgIC8vIG5hbWVkIGxpdGVyYWxseSBcImJhci5iYXpcIiBvbiBgdGhpcy5mb29gKS4gQnkgY29udmVudGlvbiwgd2UgdXNlIGBudWxsYFxuICAgICAgICAvLyBmb3IgdGhpcyBwdXJwb3NlLlxuICAgICAgICBpZiAob3JpZ2luYWwubWF0Y2goL150aGlzKFxcLi4rKT8kLykpIHtcbiAgICAgICAgICAgIHRoaXNIZWFkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1BhdGhFeHByZXNzaW9uJyxcbiAgICAgICAgICAgIG9yaWdpbmFsOiBwYXRoLm9yaWdpbmFsLFxuICAgICAgICAgICAgdGhpczogdGhpc0hlYWQsXG4gICAgICAgICAgICBwYXJ0cyxcbiAgICAgICAgICAgIGRhdGE6IHBhdGguZGF0YSxcbiAgICAgICAgICAgIGxvYzogcGF0aC5sb2NcbiAgICAgICAgfTtcbiAgICB9XG4gICAgSGFzaChoYXNoKSB7XG4gICAgICAgIGxldCBwYWlycyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhhc2gucGFpcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBwYWlyID0gaGFzaC5wYWlyc1tpXTtcbiAgICAgICAgICAgIHBhaXJzLnB1c2goYi5wYWlyKHBhaXIua2V5LCB0aGlzLmFjY2VwdE5vZGUocGFpci52YWx1ZSksIHBhaXIubG9jKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGIuaGFzaChwYWlycywgaGFzaC5sb2MpO1xuICAgIH1cbiAgICBTdHJpbmdMaXRlcmFsKHN0cmluZykge1xuICAgICAgICByZXR1cm4gYi5saXRlcmFsKCdTdHJpbmdMaXRlcmFsJywgc3RyaW5nLnZhbHVlLCBzdHJpbmcubG9jKTtcbiAgICB9XG4gICAgQm9vbGVhbkxpdGVyYWwoYm9vbGVhbikge1xuICAgICAgICByZXR1cm4gYi5saXRlcmFsKCdCb29sZWFuTGl0ZXJhbCcsIGJvb2xlYW4udmFsdWUsIGJvb2xlYW4ubG9jKTtcbiAgICB9XG4gICAgTnVtYmVyTGl0ZXJhbChudW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGIubGl0ZXJhbCgnTnVtYmVyTGl0ZXJhbCcsIG51bWJlci52YWx1ZSwgbnVtYmVyLmxvYyk7XG4gICAgfVxuICAgIFVuZGVmaW5lZExpdGVyYWwodW5kZWYpIHtcbiAgICAgICAgcmV0dXJuIGIubGl0ZXJhbCgnVW5kZWZpbmVkTGl0ZXJhbCcsIHVuZGVmaW5lZCwgdW5kZWYubG9jKTtcbiAgICB9XG4gICAgTnVsbExpdGVyYWwobnVsKSB7XG4gICAgICAgIHJldHVybiBiLmxpdGVyYWwoJ051bGxMaXRlcmFsJywgbnVsbCwgbnVsLmxvYyk7XG4gICAgfVxufVxuZnVuY3Rpb24gY2FsY3VsYXRlUmlnaHRTdHJpcHBlZE9mZnNldHMob3JpZ2luYWwsIHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSAnJykge1xuICAgICAgICAvLyBpZiBpdCBpcyBlbXB0eSwganVzdCByZXR1cm4gdGhlIGNvdW50IG9mIG5ld2xpbmVzXG4gICAgICAgIC8vIGluIG9yaWdpbmFsXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsaW5lczogb3JpZ2luYWwuc3BsaXQoXCJcXG5cIikubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgIGNvbHVtbnM6IDBcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gb3RoZXJ3aXNlLCByZXR1cm4gdGhlIG51bWJlciBvZiBuZXdsaW5lcyBwcmlvciB0b1xuICAgIC8vIGB2YWx1ZWBcbiAgICBsZXQgZGlmZmVyZW5jZSA9IG9yaWdpbmFsLnNwbGl0KHZhbHVlKVswXTtcbiAgICBsZXQgbGluZXMgPSBkaWZmZXJlbmNlLnNwbGl0KC9cXG4vKTtcbiAgICBsZXQgbGluZUNvdW50ID0gbGluZXMubGVuZ3RoIC0gMTtcbiAgICByZXR1cm4ge1xuICAgICAgICBsaW5lczogbGluZUNvdW50LFxuICAgICAgICBjb2x1bW5zOiBsaW5lc1tsaW5lQ291bnRdLmxlbmd0aFxuICAgIH07XG59XG5mdW5jdGlvbiB1cGRhdGVUb2tlbml6ZXJMb2NhdGlvbih0b2tlbml6ZXIsIGNvbnRlbnQpIHtcbiAgICBsZXQgbGluZSA9IGNvbnRlbnQubG9jLnN0YXJ0LmxpbmU7XG4gICAgbGV0IGNvbHVtbiA9IGNvbnRlbnQubG9jLnN0YXJ0LmNvbHVtbjtcbiAgICBsZXQgb2Zmc2V0cyA9IGNhbGN1bGF0ZVJpZ2h0U3RyaXBwZWRPZmZzZXRzKGNvbnRlbnQub3JpZ2luYWwsIGNvbnRlbnQudmFsdWUpO1xuICAgIGxpbmUgPSBsaW5lICsgb2Zmc2V0cy5saW5lcztcbiAgICBpZiAob2Zmc2V0cy5saW5lcykge1xuICAgICAgICBjb2x1bW4gPSBvZmZzZXRzLmNvbHVtbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29sdW1uID0gY29sdW1uICsgb2Zmc2V0cy5jb2x1bW5zO1xuICAgIH1cbiAgICB0b2tlbml6ZXIubGluZSA9IGxpbmU7XG4gICAgdG9rZW5pemVyLmNvbHVtbiA9IGNvbHVtbjtcbn1cbmZ1bmN0aW9uIGFjY2VwdENhbGxOb2Rlcyhjb21waWxlciwgbm9kZSkge1xuICAgIGxldCBwYXRoID0gY29tcGlsZXIuUGF0aEV4cHJlc3Npb24obm9kZS5wYXRoKTtcbiAgICBsZXQgcGFyYW1zID0gbm9kZS5wYXJhbXMgPyBub2RlLnBhcmFtcy5tYXAoZSA9PiBjb21waWxlci5hY2NlcHROb2RlKGUpKSA6IFtdO1xuICAgIGxldCBoYXNoID0gbm9kZS5oYXNoID8gY29tcGlsZXIuSGFzaChub2RlLmhhc2gpIDogYi5oYXNoKCk7XG4gICAgcmV0dXJuIHsgcGF0aCwgcGFyYW1zLCBoYXNoIH07XG59XG5mdW5jdGlvbiBhZGRFbGVtZW50TW9kaWZpZXIoZWxlbWVudCwgbXVzdGFjaGUpIHtcbiAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2gsIGxvYyB9ID0gbXVzdGFjaGU7XG4gICAgaWYgKGlzTGl0ZXJhbChwYXRoKSkge1xuICAgICAgICBsZXQgbW9kaWZpZXIgPSBge3ske3ByaW50TGl0ZXJhbChwYXRoKX19fWA7XG4gICAgICAgIGxldCB0YWcgPSBgPCR7ZWxlbWVudC5uYW1lfSAuLi4gJHttb2RpZmllcn0gLi4uYDtcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKGBJbiAke3RhZ30sICR7bW9kaWZpZXJ9IGlzIG5vdCBhIHZhbGlkIG1vZGlmaWVyOiBcIiR7cGF0aC5vcmlnaW5hbH1cIiBvbiBsaW5lICR7bG9jICYmIGxvYy5zdGFydC5saW5lfS5gLCBtdXN0YWNoZS5sb2MpO1xuICAgIH1cbiAgICBsZXQgbW9kaWZpZXIgPSBiLmVsZW1lbnRNb2RpZmllcihwYXRoLCBwYXJhbXMsIGhhc2gsIGxvYyk7XG4gICAgZWxlbWVudC5tb2RpZmllcnMucHVzaChtb2RpZmllcik7XG59XG5mdW5jdGlvbiBhcHBlbmREeW5hbWljQXR0cmlidXRlVmFsdWVQYXJ0KGF0dHJpYnV0ZSwgcGFydCkge1xuICAgIGF0dHJpYnV0ZS5pc0R5bmFtaWMgPSB0cnVlO1xuICAgIGF0dHJpYnV0ZS5wYXJ0cy5wdXNoKHBhcnQpO1xufSJdfQ==