UNPKG

@glimmer/syntax

Version:
563 lines (482 loc) 55.9 kB
import { Parser } from '../parser'; import { NON_EXISTENT_LOCATION } from '../source/location'; import { generateSyntaxError } from '../syntax-error'; import { appendChild, isHBSLiteral, printLiteral } from '../utils'; import { PathExpressionImplV1 } from '../v1/legacy-interop'; import b from '../v1/parser-builders'; export class HandlebarsNodeVisitors extends Parser { get isTopLevel() { return this.elementStack.length === 0; } Program(program) { let body = []; let node; if (this.isTopLevel) { node = b.template({ body, blockParams: program.blockParams, loc: this.source.spanFor(program.loc) }); } else { node = b.blockItself({ body, blockParams: program.blockParams, chained: program.chained, loc: this.source.spanFor(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 generateSyntaxError(`Unclosed element \`${elementNode.tag}\``, elementNode.loc); } return node; } BlockStatement(block) { if (this.tokenizer.state === "comment" /* comment */ ) { this.appendToCommentData(this.sourceForNode(block)); return; } if (this.tokenizer.state !== "data" /* data */ && this.tokenizer.state !== "beforeData" /* beforeData */ ) { throw generateSyntaxError('A block may only be used inside an HTML element or another block.', this.source.spanFor(block.loc)); } let { path, params, hash } = acceptCallNodes(this, block); // These are bugs in Handlebars upstream if (!block.program.loc) { block.program.loc = NON_EXISTENT_LOCATION; } if (block.inverse && !block.inverse.loc) { block.inverse.loc = NON_EXISTENT_LOCATION; } let program = this.Program(block.program); let inverse = block.inverse ? this.Program(block.inverse) : null; let node = b.block({ path, params, hash, defaultBlock: program, elseBlock: inverse, loc: this.source.spanFor(block.loc), openStrip: block.openStrip, inverseStrip: block.inverseStrip, closeStrip: block.closeStrip }); let parentProgram = this.currentElement(); appendChild(parentProgram, node); } MustacheStatement(rawMustache) { let { tokenizer } = this; if (tokenizer.state === 'comment') { this.appendToCommentData(this.sourceForNode(rawMustache)); return; } let mustache; let { escaped, loc, strip } = rawMustache; if (isHBSLiteral(rawMustache.path)) { mustache = b.mustache({ path: this.acceptNode(rawMustache.path), params: [], hash: b.hash([], this.source.spanFor(rawMustache.path.loc).collapse('end')), trusting: !escaped, loc: this.source.spanFor(loc), strip }); } else { let { path, params, hash } = acceptCallNodes(this, rawMustache); mustache = b.mustache({ path, params, hash, trusting: !escaped, loc: this.source.spanFor(loc), strip }); } switch (tokenizer.state) { // Tag helpers case "tagOpen" /* tagOpen */ : case "tagName" /* tagName */ : throw generateSyntaxError(`Cannot use mustaches in an elements tagname`, mustache.loc); case "beforeAttributeName" /* beforeAttributeName */ : addElementModifier(this.currentStartTag, mustache); break; case "attributeName" /* attributeName */ : case "afterAttributeName" /* afterAttributeName */ : this.beginAttributeValue(false); this.finishAttributeValue(); addElementModifier(this.currentStartTag, mustache); tokenizer.transitionTo("beforeAttributeName" /* beforeAttributeName */ ); break; case "afterAttributeValueQuoted" /* afterAttributeValueQuoted */ : addElementModifier(this.currentStartTag, mustache); tokenizer.transitionTo("beforeAttributeName" /* beforeAttributeName */ ); break; // Attribute values case "beforeAttributeValue" /* beforeAttributeValue */ : this.beginAttributeValue(false); this.appendDynamicAttributeValuePart(mustache); tokenizer.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */ ); break; case "attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */ : case "attributeValueSingleQuoted" /* attributeValueSingleQuoted */ : case "attributeValueUnquoted" /* attributeValueUnquoted */ : this.appendDynamicAttributeValuePart(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; } appendDynamicAttributeValuePart(part) { this.finalizeTextPart(); let attr = this.currentAttr; attr.isDynamic = true; attr.parts.push(part); } finalizeTextPart() { let attr = this.currentAttr; let text = attr.currentPart; if (text !== null) { this.currentAttr.parts.push(text); this.startTextPart(); } } startTextPart() { this.currentAttr.currentPart = null; } ContentStatement(content) { updateTokenizerLocation(this.tokenizer, content); this.tokenizer.tokenizePart(content.value); this.tokenizer.flushData(); } CommentStatement(rawComment) { let { tokenizer } = this; if (tokenizer.state === "comment" /* comment */ ) { this.appendToCommentData(this.sourceForNode(rawComment)); return null; } let { value, loc } = rawComment; let comment = b.mustacheComment(value, this.source.spanFor(loc)); switch (tokenizer.state) { case "beforeAttributeName" /* beforeAttributeName */ : case "afterAttributeName" /* afterAttributeName */ : this.currentStartTag.comments.push(comment); break; case "beforeData" /* beforeData */ : case "data" /* data */ : appendChild(this.currentElement(), comment); break; default: throw generateSyntaxError(`Using a Handlebars comment when in the \`${tokenizer['state']}\` state is not supported`, this.source.spanFor(rawComment.loc)); } return comment; } PartialStatement(partial) { throw generateSyntaxError(`Handlebars partials are not supported`, this.source.spanFor(partial.loc)); } PartialBlockStatement(partialBlock) { throw generateSyntaxError(`Handlebars partial blocks are not supported`, this.source.spanFor(partialBlock.loc)); } Decorator(decorator) { throw generateSyntaxError(`Handlebars decorators are not supported`, this.source.spanFor(decorator.loc)); } DecoratorBlock(decoratorBlock) { throw generateSyntaxError(`Handlebars decorator blocks are not supported`, this.source.spanFor(decoratorBlock.loc)); } SubExpression(sexpr) { let { path, params, hash } = acceptCallNodes(this, sexpr); return b.sexpr({ path, params, hash, loc: this.source.spanFor(sexpr.loc) }); } PathExpression(path) { let { original } = path; let parts; if (original.indexOf('/') !== -1) { if (original.slice(0, 2) === './') { throw generateSyntaxError(`Using "./" is not supported in Glimmer and unnecessary`, this.source.spanFor(path.loc)); } if (original.slice(0, 3) === '../') { throw generateSyntaxError(`Changing context using "../" is not supported in Glimmer`, this.source.spanFor(path.loc)); } if (original.indexOf('.') !== -1) { throw generateSyntaxError(`Mixing '.' and '/' in paths is not supported in Glimmer; use only '.' to separate property paths`, this.source.spanFor(path.loc)); } parts = [path.parts.join('/')]; } else if (original === '.') { throw generateSyntaxError(`'.' is not a supported path in Glimmer; check for a path with a trailing '.'`, this.source.spanFor(path.loc)); } 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; } let pathHead; if (thisHead) { pathHead = { type: 'ThisHead', loc: { start: path.loc.start, end: { line: path.loc.start.line, column: path.loc.start.column + 4 } } }; } else if (path.data) { let head = parts.shift(); if (head === undefined) { throw generateSyntaxError(`Attempted to parse a path expression, but it was not valid. Paths beginning with @ must start with a-z.`, this.source.spanFor(path.loc)); } pathHead = { type: 'AtHead', name: `@${head}`, loc: { start: path.loc.start, end: { line: path.loc.start.line, column: path.loc.start.column + head.length + 1 } } }; } else { let head = parts.shift(); if (head === undefined) { throw generateSyntaxError(`Attempted to parse a path expression, but it was not valid. Paths must start with a-z or A-Z.`, this.source.spanFor(path.loc)); } pathHead = { type: 'VarHead', name: head, loc: { start: path.loc.start, end: { line: path.loc.start.line, column: path.loc.start.column + head.length } } }; } return new PathExpressionImplV1(path.original, pathHead, parts, this.source.spanFor(path.loc)); } Hash(hash) { let pairs = []; for (let i = 0; i < hash.pairs.length; i++) { let pair = hash.pairs[i]; pairs.push(b.pair({ key: pair.key, value: this.acceptNode(pair.value), loc: this.source.spanFor(pair.loc) })); } return b.hash(pairs, this.source.spanFor(hash.loc)); } StringLiteral(string) { return b.literal({ type: 'StringLiteral', value: string.value, loc: string.loc }); } BooleanLiteral(boolean) { return b.literal({ type: 'BooleanLiteral', value: boolean.value, loc: boolean.loc }); } NumberLiteral(number) { return b.literal({ type: 'NumberLiteral', value: number.value, loc: number.loc }); } UndefinedLiteral(undef) { return b.literal({ type: 'UndefinedLiteral', value: undefined, loc: undef.loc }); } NullLiteral(nul) { return b.literal({ type: 'NullLiteral', value: null, loc: nul.loc }); } } 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) { if (node.path.type.endsWith('Literal')) { const path = node.path; let value = ''; if (path.type === 'BooleanLiteral') { value = path.original.toString(); } else if (path.type === 'StringLiteral') { value = `"${path.original}"`; } else if (path.type === 'NullLiteral') { value = 'null'; } else if (path.type === 'NumberLiteral') { value = path.value.toString(); } else { value = 'undefined'; } throw generateSyntaxError(`${path.type} "${path.type === 'StringLiteral' ? path.original : value}" cannot be called as a sub-expression, replace (${value}) with ${value}`, compiler.source.spanFor(path.loc)); } let path = node.path.type === 'PathExpression' ? compiler.PathExpression(node.path) : compiler.SubExpression(node.path); let params = node.params ? node.params.map(e => compiler.acceptNode(e)) : []; // if there is no hash, position it as a collapsed node immediately after the last param (or the // path, if there are also no params) let end = params.length > 0 ? params[params.length - 1].loc : path.loc; let hash = node.hash ? compiler.Hash(node.hash) : { type: 'Hash', pairs: [], loc: compiler.source.spanFor(end).collapse('end') }; return { path, params, hash }; } function addElementModifier(element, mustache) { let { path, params, hash, loc } = mustache; if (isHBSLiteral(path)) { let modifier = `{{${printLiteral(path)}}}`; let tag = `<${element.name} ... ${modifier} ...`; throw generateSyntaxError(`In ${tag}, ${modifier} is not a valid modifier`, mustache.loc); } let modifier = b.elementModifier({ path, params, hash, loc }); element.modifiers.push(modifier); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvcGFyc2VyL2hhbmRsZWJhcnMtbm9kZS12aXNpdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxTQUFTLE1BQVQsUUFBK0MsV0FBL0M7QUFDQSxTQUFTLHFCQUFULFFBQXNDLG9CQUF0QztBQUNBLFNBQVMsbUJBQVQsUUFBb0MsaUJBQXBDO0FBQ0EsU0FBUyxXQUFULEVBQXNCLFlBQXRCLEVBQW9DLFlBQXBDLFFBQXdELFVBQXhEO0FBR0EsU0FBUyxvQkFBVCxRQUFxQyxzQkFBckM7QUFDQSxPQUFPLENBQVAsTUFBYyx1QkFBZDtBQUVBLE9BQU0sTUFBZ0Isc0JBQWhCLFNBQStDLE1BQS9DLENBQXFEO0FBS3pELE1BQVksVUFBWixHQUFzQjtBQUNwQixXQUFPLEtBQUssWUFBTCxDQUFrQixNQUFsQixLQUE2QixDQUFwQztBQUNEOztBQUtELEVBQUEsT0FBTyxDQUFDLE9BQUQsRUFBcUI7QUFDMUIsUUFBSSxJQUFJLEdBQXNCLEVBQTlCO0FBQ0EsUUFBSSxJQUFKOztBQUVBLFFBQUksS0FBSyxVQUFULEVBQXFCO0FBQ25CLE1BQUEsSUFBSSxHQUFHLENBQUMsQ0FBQyxRQUFGLENBQVc7QUFDaEIsUUFBQSxJQURnQjtBQUVoQixRQUFBLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FGTDtBQUdoQixRQUFBLEdBQUcsRUFBRSxLQUFLLE1BQUwsQ0FBWSxPQUFaLENBQW9CLE9BQU8sQ0FBQyxHQUE1QjtBQUhXLE9BQVgsQ0FBUDtBQUtELEtBTkQsTUFNTztBQUNMLE1BQUEsSUFBSSxHQUFHLENBQUMsQ0FBQyxXQUFGLENBQWM7QUFDbkIsUUFBQSxJQURtQjtBQUVuQixRQUFBLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FGRjtBQUduQixRQUFBLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FIRTtBQUluQixRQUFBLEdBQUcsRUFBRSxLQUFLLE1BQUwsQ0FBWSxPQUFaLENBQW9CLE9B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QUEsTUFBUjtBQUFnQixJQUFBLElBQWhCO0FBQXNCLElBQUE7QUFBdEIsR0FBbEIsQ0FBZjtBQUNBLEVBQUEsT0FBTyxDQUFDLFNBQVIsQ0FBa0IsSUFBbEIsQ0FBdUIsUUFBdkI7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9wdGlvbiwgUmVjYXN0IH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBUb2tlbml6ZXJTdGF0ZSB9IGZyb20gJ3NpbXBsZS1odG1sLXRva2VuaXplcic7XG5cbmltcG9ydCB7IFBhcnNlciwgUGFyc2VyTm9kZUJ1aWxkZXIsIFRhZyB9IGZyb20gJy4uL3BhcnNlcic7XG5pbXBvcnQgeyBOT05fRVhJU1RFTlRfTE9DQVRJT04gfSBmcm9tICcuLi9zb3VyY2UvbG9jYXRpb24nO1xuaW1wb3J0IHsgZ2VuZXJhdGVTeW50YXhFcnJvciB9IGZyb20gJy4uL3N5bnRheC1lcnJvcic7XG5pbXBvcnQgeyBhcHBlbmRDaGlsZCwgaXNIQlNMaXRlcmFsLCBwcmludExpdGVyYWwgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgKiBhcyBBU1R2MSBmcm9tICcuLi92MS9hcGknO1xuaW1wb3J0ICogYXMgSEJTIGZyb20gJy4uL3YxL2hhbmRsZWJhcnMtYXN0JztcbmltcG9ydCB7IFBhdGhFeHByZXNzaW9uSW1wbFYxIH0gZnJvbSAnLi4vdjEvbGVnYWN5LWludGVyb3AnO1xuaW1wb3J0IGIgZnJvbSAnLi4vdjEvcGFyc2VyLWJ1aWxkZXJzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEhhbmRsZWJhcnNOb2RlVmlzaXRvcnMgZXh0ZW5kcyBQYXJzZXIge1xuICBhYnN0cmFjdCBhcHBlbmRUb0NvbW1lbnREYXRhKHM6IHN0cmluZyk6IHZvaWQ7XG4gIGFic3RyYWN0IGJlZ2luQXR0cmlidXRlVmFsdWUocXVvdGVkOiBib29sZWFuKTogdm9pZDtcbiAgYWJzdHJhY3QgZmluaXNoQXR0cmlidXRlVmFsdWUoKTogdm9pZDtcblxuICBwcml2YXRlIGdldCBpc1RvcExldmVsKCkge1xuICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjay5sZW5ndGggPT09IDA7XG4gIH1cblxuICBQcm9ncmFtKHByb2dyYW06IEhCUy5Qcm9ncmFtKTogQVNUdjEuQmxvY2s7XG4gIFByb2dyYW0ocHJvZ3JhbTogSEJTLlByb2dyYW0pOiBBU1R2MS5UZW1wbGF0ZTtcbiAgUHJvZ3JhbShwcm9ncmFtOiBIQlMuUHJvZ3JhbSk6IEFTVHYxLlRlbXBsYXRlIHwgQVNUdjEuQmxvY2s7XG4gIFByb2dyYW0ocHJvZ3JhbTogSEJTLlByb2dyYW0pOiBBU1R2MS5CbG9jayB8IEFTVHYxLlRlbXBsYXRlIHtcbiAgICBsZXQgYm9keTogQVNUdjEuU3RhdGVtZW50W10gPSBbXTtcbiAgICBsZXQgbm9kZTtcblxuICAgIGlmICh0aGlzLmlzVG9wTGV2ZWwpIHtcbiAgICAgIG5vZGUgPSBiLnRlbXBsYXRlKHtcbiAgICAgICAgYm9keSxcbiAgICAgICAgYmxvY2tQYXJhbXM6IHByb2dyYW0uYmxvY2tQYXJhbXMsXG4gICAgICAgIGxvYzogdGhpcy5zb3VyY2Uuc3BhbkZvcihwcm9ncmFtLmxvYyksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZSA9IGIuYmxvY2tJdHNlbGYoe1xuICAgICAgICBib2R5LFxuICAgICAgICBibG9ja1BhcmFtczogcHJvZ3JhbS5ibG9ja1BhcmFtcyxcbiAgICAgICAgY2hhaW5lZDogcHJvZ3JhbS5jaGFpbmVkLFxuICAgICAgICBsb2M6IHRoaXMuc291cmNlLnNwYW5Gb3IocHJvZ3JhbS5sb2MpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IGksXG4gICAgICBsID0gcHJvZ3JhbS5ib2R5Lmxlbmd0aDtcblxuICAgIHRoaXMuZWxlbWVudFN0YWNrLnB1c2gobm9kZSk7XG5cbiAgICBpZiAobCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudFN0YWNrLnBvcCgpIGFzIEFTVHYxLkJsb2NrIHwgQVNUdjEuVGVtcGxhdGU7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5hY2NlcHROb2RlKHByb2dyYW0uYm9keVtpXSk7XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhhdCB0aGUgZWxlbWVudCBzdGFjayBpcyBiYWxhbmNlZCBwcm9wZXJseS5cbiAgICBsZXQgcG9wcGVkTm9kZSA9IHRoaXMuZWxlbWVudFN0YWNrLnBvcCgpO1xuICAgIGlmIChwb3BwZWROb2RlICE9PSBub2RlKSB7XG4gICAgICBsZXQgZWxlbWVudE5vZGUgPSBwb3BwZWROb2RlIGFzIEFTVHYxLkVsZW1lbnROb2RlO1xuXG4gICAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKGBVbmNsb3NlZCBlbGVtZW50IFxcYCR7ZWxlbWVudE5vZGUudGFnfVxcYGAsIGVsZW1lbnROb2RlLmxvYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBCbG9ja1N0YXRlbWVudChibG9jazogSEJTLkJsb2NrU3RhdGVtZW50KTogQVNUdjEuQmxvY2tTdGF0ZW1lbnQgfCB2b2lkIHtcbiAgICBpZiAodGhpcy50b2tlbml6ZXIuc3RhdGUgPT09IFRva2VuaXplclN0YXRlLmNvbW1lbnQpIHtcbiAgICAgIHRoaXMuYXBwZW5kVG9Db21tZW50RGF0YSh0aGlzLnNvdXJjZUZvck5vZGUoYmxvY2spKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnRva2VuaXplci5zdGF0ZSAhPT0gVG9rZW5pemVyU3RhdGUuZGF0YSAmJlxuICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgIT09IFRva2VuaXplclN0YXRlLmJlZm9yZURhdGFcbiAgICApIHtcbiAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgICdBIGJsb2NrIG1heSBvbmx5IGJlIHVzZWQgaW5zaWRlIGFuIEhUTUwgZWxlbWVudCBvciBhbm90aGVyIGJsb2NrLicsXG4gICAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IoYmxvY2subG9jKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgeyBwYXRoLCBwYXJhbXMsIGhhc2ggfSA9IGFjY2VwdENhbGxOb2Rlcyh0aGlzLCBibG9jayk7XG5cbiAgICAvLyBUaGVzZSBhcmUgYnVncyBpbiBIYW5kbGViYXJzIHVwc3RyZWFtXG4gICAgaWYgKCFibG9jay5wcm9ncmFtLmxvYykge1xuICAgICAgYmxvY2sucHJvZ3JhbS5sb2MgPSBOT05fRVhJU1RFTlRfTE9DQVRJT047XG4gICAgfVxuXG4gICAgaWYgKGJsb2NrLmludmVyc2UgJiYgIWJsb2NrLmludmVyc2UubG9jKSB7XG4gICAgICBibG9jay5pbnZlcnNlLmxvYyA9IE5PTl9FWElTVEVOVF9MT0NBVElPTjtcbiAgICB9XG5cbiAgICBsZXQgcHJvZ3JhbSA9IHRoaXMuUHJvZ3JhbShibG9jay5wcm9ncmFtKTtcbiAgICBsZXQgaW52ZXJzZSA9IGJsb2NrLmludmVyc2UgPyB0aGlzLlByb2dyYW0oYmxvY2suaW52ZXJzZSkgOiBudWxsO1xuXG4gICAgbGV0IG5vZGUgPSBiLmJsb2NrKHtcbiAgICAgIHBhdGgsXG4gICAgICBwYXJhbXMsXG4gICAgICBoYXNoLFxuICAgICAgZGVmYXVsdEJsb2NrOiBwcm9ncmFtLFxuICAgICAgZWxzZUJsb2NrOiBpbnZlcnNlLFxuICAgICAgbG9jOiB0aGlzLnNvdXJjZS5zcGFuRm9yKGJsb2NrLmxvYyksXG4gICAgICBvcGVuU3RyaXA6IGJsb2NrLm9wZW5TdHJpcCxcbiAgICAgIGludmVyc2VTdHJpcDogYmxvY2suaW52ZXJzZVN0cmlwLFxuICAgICAgY2xvc2VTdHJpcDogYmxvY2suY2xvc2VTdHJpcCxcbiAgICB9KTtcblxuICAgIGxldCBwYXJlbnRQcm9ncmFtID0gdGhpcy5jdXJyZW50RWxlbWVudCgpO1xuXG4gICAgYXBwZW5kQ2hpbGQocGFyZW50UHJvZ3JhbSwgbm9kZSk7XG4gIH1cblxuICBNdXN0YWNoZVN0YXRlbWVudChyYXdNdXN0YWNoZTogSEJTLk11c3RhY2hlU3RhdGVtZW50KTogQVNUdjEuTXVzdGFjaGVTdGF0ZW1lbnQgfCB2b2lkIHtcbiAgICBsZXQgeyB0b2tlbml6ZXIgfSA9IHRoaXM7XG5cbiAgICBpZiAodG9rZW5pemVyLnN0YXRlID09PSAnY29tbWVudCcpIHtcbiAgICAgIHRoaXMuYXBwZW5kVG9Db21tZW50RGF0YSh0aGlzLnNvdXJjZUZvck5vZGUocmF3TXVzdGFjaGUpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgbXVzdGFjaGU6IEFTVHYxLk11c3RhY2hlU3RhdGVtZW50O1xuICAgIGxldCB7IGVzY2FwZWQsIGxvYywgc3RyaXAgfSA9IHJhd011c3RhY2hlO1xuXG4gICAgaWYgKGlzSEJTTGl0ZXJhbChyYXdNdXN0YWNoZS5wYXRoKSkge1xuICAgICAgbXVzdGFjaGUgPSBiLm11c3RhY2hlKHtcbiAgICAgICAgcGF0aDogdGhpcy5hY2NlcHROb2RlPEFTVHYxLkxpdGVyYWw+KHJhd011c3RhY2hlLnBhdGgpLFxuICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICBoYXNoOiBiLmhhc2goW10sIHRoaXMuc291cmNlLnNwYW5Gb3IocmF3TXVzdGFjaGUucGF0aC5sb2MpLmNvbGxhcHNlKCdlbmQnKSksXG4gICAgICAgIHRydXN0aW5nOiAhZXNjYXBlZCxcbiAgICAgICAgbG9jOiB0aGlzLnNvdXJjZS5zcGFuRm9yKGxvYyksXG4gICAgICAgIHN0cmlwLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCB7IHBhdGgsIHBhcmFtcywgaGFzaCB9ID0gYWNjZXB0Q2FsbE5vZGVzKFxuICAgICAgICB0aGlzLFxuICAgICAgICByYXdNdXN0YWNoZSBhcyBIQlMuTXVzdGFjaGVTdGF0ZW1lbnQgJiB7XG4gICAgICAgICAgcGF0aDogSEJTLlBhdGhFeHByZXNzaW9uIHwgSEJTLlN1YkV4cHJlc3Npb247XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICBtdXN0YWNoZSA9IGIubXVzdGFjaGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBwYXJhbXMsXG4gICAgICAgIGhhc2gsXG4gICAgICAgIHRydXN0aW5nOiAhZXNjYXBlZCxcbiAgICAgICAgbG9jOiB0aGlzLnNvdXJjZS5zcGFuRm9yKGxvYyksXG4gICAgICAgIHN0cmlwLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0b2tlbml6ZXIuc3RhdGUpIHtcbiAgICAgIC8vIFRhZyBoZWxwZXJzXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLnRhZ09wZW46XG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLnRhZ05hbWU6XG4gICAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoYENhbm5vdCB1c2UgbXVzdGFjaGVzIGluIGFuIGVsZW1lbnRzIHRhZ25hbWVgLCBtdXN0YWNoZS5sb2MpO1xuXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmJlZm9yZUF0dHJpYnV0ZU5hbWU6XG4gICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYXR0cmlidXRlTmFtZTpcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYWZ0ZXJBdHRyaWJ1dGVOYW1lOlxuICAgICAgICB0aGlzLmJlZ2luQXR0cmlidXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICB0aGlzLmZpbmlzaEF0dHJpYnV0ZVZhbHVlKCk7XG4gICAgICAgIGFkZEVsZW1lbnRNb2RpZmllcih0aGlzLmN1cnJlbnRTdGFydFRhZywgbXVzdGFjaGUpO1xuICAgICAgICB0b2tlbml6ZXIudHJhbnNpdGlvblRvKFRva2VuaXplclN0YXRlLmJlZm9yZUF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYWZ0ZXJBdHRyaWJ1dGVWYWx1ZVF1b3RlZDpcbiAgICAgICAgYWRkRWxlbWVudE1vZGlmaWVyKHRoaXMuY3VycmVudFN0YXJ0VGFnLCBtdXN0YWNoZSk7XG4gICAgICAgIHRva2VuaXplci50cmFuc2l0aW9uVG8oVG9rZW5pemVyU3RhdGUuYmVmb3JlQXR0cmlidXRlTmFtZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICAvLyBBdHRyaWJ1dGUgdmFsdWVzXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmJlZm9yZUF0dHJpYnV0ZVZhbHVlOlxuICAgICAgICB0aGlzLmJlZ2luQXR0cmlidXRlVmFsdWUoZmFsc2UpO1xuICAgICAgICB0aGlzLmFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQobXVzdGFjaGUpO1xuICAgICAgICB0b2tlbml6ZXIudHJhbnNpdGlvblRvKFRva2VuaXplclN0YXRlLmF0dHJpYnV0ZVZhbHVlVW5xdW90ZWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVG9rZW5pemVyU3RhdGUuYXR0cmlidXRlVmFsdWVEb3VibGVRdW90ZWQ6XG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVkOlxuICAgICAgY2FzZSBUb2tlbml6ZXJTdGF0ZS5hdHRyaWJ1dGVWYWx1ZVVucXVvdGVkOlxuICAgICAgICB0aGlzLmFwcGVuZER5bmFtaWNBdHRyaWJ1dGVWYWx1ZVBhcnQobXVzdGFjaGUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gVE9ETzogT25seSBhcHBlbmQgY2hpbGQgd2hlbiB0aGUgdG9rZW5pemVyIHN0YXRlIG1ha2VzXG4gICAgICAvLyBzZW5zZSB0byBkbyBzbywgb3RoZXJ3aXNlIHRocm93IGFuIGVycm9yLlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXBwZW5kQ2hpbGQodGhpcy5jdXJyZW50RWxlbWVudCgpLCBtdXN0YWNoZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG11c3RhY2hlO1xuICB9XG5cbiAgYXBwZW5kRHluYW1pY0F0dHJpYnV0ZVZhbHVlUGFydChwYXJ0OiBBU1R2MS5NdXN0YWNoZVN0YXRlbWVudCk6IHZvaWQge1xuICAgIHRoaXMuZmluYWxpemVUZXh0UGFydCgpO1xuICAgIGxldCBhdHRyID0gdGhpcy5jdXJyZW50QXR0cjtcbiAgICBhdHRyLmlzRHluYW1pYyA9IHRydWU7XG4gICAgYXR0ci5wYXJ0cy5wdXNoKHBhcnQpO1xuICB9XG5cbiAgZmluYWxpemVUZXh0UGFydCgpOiB2b2lkIHtcbiAgICBsZXQgYXR0ciA9IHRoaXMuY3VycmVudEF0dHI7XG4gICAgbGV0IHRleHQgPSBhdHRyLmN1cnJlbnRQYXJ0O1xuICAgIGlmICh0ZXh0ICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmN1cnJlbnRBdHRyLnBhcnRzLnB1c2godGV4dCk7XG4gICAgICB0aGlzLnN0YXJ0VGV4dFBhcnQoKTtcbiAgICB9XG4gIH1cblxuICBzdGFydFRleHRQYXJ0KCk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudEF0dHIuY3VycmVudFBhcnQgPSBudWxsO1xuICB9XG5cbiAgQ29udGVudFN0YXRlbWVudChjb250ZW50OiBIQlMuQ29udGVudFN0YXRlbWVudCk6IHZvaWQge1xuICAgIHVwZGF0ZVRva2VuaXplckxvY2F0aW9uKHRoaXMudG9rZW5pemVyLCBjb250ZW50KTtcblxuICAgIHRoaXMudG9rZW5pemVyLnRva2VuaXplUGFydChjb250ZW50LnZhbHVlKTtcbiAgICB0aGlzLnRva2VuaXplci5mbHVzaERhdGEoKTtcbiAgfVxuXG4gIENvbW1lbnRTdGF0ZW1lbnQocmF3Q29tbWVudDogSEJTLkNvbW1lbnRTdGF0ZW1lbnQpOiBPcHRpb248QVNUdjEuTXVzdGFjaGVDb21tZW50U3RhdGVtZW50PiB7XG4gICAgbGV0IHsgdG9rZW5pemVyIH0gPSB0aGlzO1xuXG4gICAgaWYgKHRva2VuaXplci5zdGF0ZSA9PT0gVG9rZW5pemVyU3RhdGUuY29tbWVudCkge1xuICAgICAgdGhpcy5hcHBlbmRUb0NvbW1lbnREYXRhKHRoaXMuc291cmNlRm9yTm9kZShyYXdDb21tZW50KSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgeyB2YWx1ZSwgbG9jIH0gPSByYXdDb21tZW50O1xuICAgIGxldCBjb21tZW50ID0gYi5tdXN0YWNoZUNvbW1lbnQodmFsdWUsIHRoaXMuc291cmNlLnNwYW5Gb3IobG9jKSk7XG5cbiAgICBzd2l0Y2ggKHRva2VuaXplci5zdGF0ZSkge1xuICAgICAgY2FzZSBUb2tlbml6ZXJTdGF0ZS5iZWZvcmVBdHRyaWJ1dGVOYW1lOlxuICAgICAgY2FzZSBUb2tlbml6ZXJTdGF0ZS5hZnRlckF0dHJpYnV0ZU5hbWU6XG4gICAgICAgIHRoaXMuY3VycmVudFN0YXJ0VGFnLmNvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmJlZm9yZURhdGE6XG4gICAgICBjYXNlIFRva2VuaXplclN0YXRlLmRhdGE6XG4gICAgICAgIGFwcGVuZENoaWxkKHRoaXMuY3VycmVudEVsZW1lbnQoKSwgY29tbWVudCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgICAgIGBVc2luZyBhIEhhbmRsZWJhcnMgY29tbWVudCB3aGVuIGluIHRoZSBcXGAke3Rva2VuaXplclsnc3RhdGUnXX1cXGAgc3RhdGUgaXMgbm90IHN1cHBvcnRlZGAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihyYXdDb21tZW50LmxvYylcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tbWVudDtcbiAgfVxuXG4gIFBhcnRpYWxTdGF0ZW1lbnQocGFydGlhbDogSEJTLlBhcnRpYWxTdGF0ZW1lbnQpOiBuZXZlciB7XG4gICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgIGBIYW5kbGViYXJzIHBhcnRpYWxzIGFyZSBub3Qgc3VwcG9ydGVkYCxcbiAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IocGFydGlhbC5sb2MpXG4gICAgKTtcbiAgfVxuXG4gIFBhcnRpYWxCbG9ja1N0YXRlbWVudChwYXJ0aWFsQmxvY2s6IEhCUy5QYXJ0aWFsQmxvY2tTdGF0ZW1lbnQpOiBuZXZlciB7XG4gICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgIGBIYW5kbGViYXJzIHBhcnRpYWwgYmxvY2tzIGFyZSBub3Qgc3VwcG9ydGVkYCxcbiAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IocGFydGlhbEJsb2NrLmxvYylcbiAgICApO1xuICB9XG5cbiAgRGVjb3JhdG9yKGRlY29yYXRvcjogSEJTLkRlY29yYXRvcik6IG5ldmVyIHtcbiAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgYEhhbmRsZWJhcnMgZGVjb3JhdG9ycyBhcmUgbm90IHN1cHBvcnRlZGAsXG4gICAgICB0aGlzLnNvdXJjZS5zcGFuRm9yKGRlY29yYXRvci5sb2MpXG4gICAgKTtcbiAgfVxuXG4gIERlY29yYXRvckJsb2NrKGRlY29yYXRvckJsb2NrOiBIQlMuRGVjb3JhdG9yQmxvY2spOiBuZXZlciB7XG4gICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgIGBIYW5kbGViYXJzIGRlY29yYXRvciBibG9ja3MgYXJlIG5vdCBzdXBwb3J0ZWRgLFxuICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihkZWNvcmF0b3JCbG9jay5sb2MpXG4gICAgKTtcbiAgfVxuXG4gIFN1YkV4cHJlc3Npb24oc2V4cHI6IEhCUy5TdWJFeHByZXNzaW9uKTogQVNUdjEuU3ViRXhwcmVzc2lvbiB7XG4gICAgbGV0IHsgcGF0aCwgcGFyYW1zLCBoYXNoIH0gPSBhY2NlcHRDYWxsTm9kZXModGhpcywgc2V4cHIpO1xuICAgIHJldHVybiBiLnNleHByKHsgcGF0aCwgcGFyYW1zLCBoYXNoLCBsb2M6IHRoaXMuc291cmNlLnNwYW5Gb3Ioc2V4cHIubG9jKSB9KTtcbiAgfVxuXG4gIFBhdGhFeHByZXNzaW9uKHBhdGg6IEhCUy5QYXRoRXhwcmVzc2lvbik6IEFTVHYxLlBhdGhFeHByZXNzaW9uIHtcbiAgICBsZXQgeyBvcmlnaW5hbCB9ID0gcGF0aDtcbiAgICBsZXQgcGFydHM6IHN0cmluZ1tdO1xuXG4gICAgaWYgKG9yaWdpbmFsLmluZGV4T2YoJy8nKSAhPT0gLTEpIHtcbiAgICAgIGlmIChvcmlnaW5hbC5zbGljZSgwLCAyKSA9PT0gJy4vJykge1xuICAgICAgICB0aHJvdyBnZW5lcmF0ZVN5bnRheEVycm9yKFxuICAgICAgICAgIGBVc2luZyBcIi4vXCIgaXMgbm90IHN1cHBvcnRlZCBpbiBHbGltbWVyIGFuZCB1bm5lY2Vzc2FyeWAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbC5zbGljZSgwLCAzKSA9PT0gJy4uLycpIHtcbiAgICAgICAgdGhyb3cgZ2VuZXJhdGVTeW50YXhFcnJvcihcbiAgICAgICAgICBgQ2hhbmdpbmcgY29udGV4dCB1c2luZyBcIi4uL1wiIGlzIG5vdCBzdXBwb3J0ZWQgaW4gR2xpbW1lcmAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbC5pbmRleE9mKCcuJykgIT09IC0xKSB7XG4gICAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgICAgYE1peGluZyAnLicgYW5kICcvJyBpbiBwYXRocyBpcyBub3Qgc3VwcG9ydGVkIGluIEdsaW1tZXI7IHVzZSBvbmx5ICcuJyB0byBzZXBhcmF0ZSBwcm9wZXJ0eSBwYXRoc2AsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHBhcnRzID0gW3BhdGgucGFydHMuam9pbignLycpXTtcbiAgICB9IGVsc2UgaWYgKG9yaWdpbmFsID09PSAnLicpIHtcbiAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgIGAnLicgaXMgbm90IGEgc3VwcG9ydGVkIHBhdGggaW4gR2xpbW1lcjsgY2hlY2sgZm9yIGEgcGF0aCB3aXRoIGEgdHJhaWxpbmcgJy4nYCxcbiAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcnRzID0gcGF0aC5wYXJ0cztcbiAgICB9XG5cbiAgICBsZXQgdGhpc0hlYWQgPSBmYWxzZTtcblxuICAgIC8vIFRoaXMgaXMgdG8gZml4IGEgYnVnIGluIHRoZSBIYW5kbGViYXJzIEFTVCB3aGVyZSB0aGUgcGF0aCBleHByZXNzaW9ucyBpblxuICAgIC8vIGB7e3RoaXMuZm9vfX1gIChhbmQgc2ltaWxhcmx5IGB7e2Zvby1iYXIgdGhpcy5mb28gbmFtZWQ9dGhpcy5mb299fWAgZXRjKVxuICAgIC8vIGFyZSBzaW1wbHkgdHVybmVkIGludG8gYHt7Zm9vfX1gLiBUaGUgZml4IGlzIHRvIHB1c2ggaXQgYmFjayBvbnRvIHRoZVxuICAgIC8vIHBhcnRzIGFycmF5IGFuZCBsZXQgdGhlIHJ1bnRpbWUgc2VlIHRoZSBkaWZmZXJlbmNlLiBIb3dldmVyLCB3ZSBjYW5ub3RcbiAgICAvLyBzaW1wbHkgdXNlIHRoZSBzdHJpbmcgYHRoaXNgIGFzIGl0IG1lYW5zIGxpdGVyYWxseSB0aGUgcHJvcGVydHkgY2FsbGVkXG4gICAgLy8gXCJ0aGlzXCIgaW4gdGhlIGN1cnJlbnQgY29udGV4dCAoaXQgY2FuIGJlIGV4cHJlc3NlZCBpbiB0aGUgc3ludGF4IGFzXG4gICAgLy8gYHt7W3RoaXNdfX1gLCB3aGVyZSB0aGUgc3F1YXJlIGJyYWNrZXQgYXJlIGdlbmVyYWxseSBmb3IgdGhpcyBraW5kIG9mXG4gICAgLy8gZXNjYXBpbmcg4oCTIHN1Y2ggYXMgYHt7Zm9vLltcImJhci5iYXpcIl19fWAgd291bGQgbWVhbiBsb29rdXAgYSBwcm9wZXJ0eVxuICAgIC8vIG5hbWVkIGxpdGVyYWxseSBcImJhci5iYXpcIiBvbiBgdGhpcy5mb29gKS4gQnkgY29udmVudGlvbiwgd2UgdXNlIGBudWxsYFxuICAgIC8vIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgaWYgKG9yaWdpbmFsLm1hdGNoKC9edGhpcyhcXC4uKyk/JC8pKSB7XG4gICAgICB0aGlzSGVhZCA9IHRydWU7XG4gICAgfVxuXG4gICAgbGV0IHBhdGhIZWFkOiBBU1R2MS5QYXRoSGVhZDtcbiAgICBpZiAodGhpc0hlYWQpIHtcbiAgICAgIHBhdGhIZWFkID0ge1xuICAgICAgICB0eXBlOiAnVGhpc0hlYWQnLFxuICAgICAgICBsb2M6IHtcbiAgICAgICAgICBzdGFydDogcGF0aC5sb2Muc3RhcnQsXG4gICAgICAgICAgZW5kOiB7IGxpbmU6IHBhdGgubG9jLnN0YXJ0LmxpbmUsIGNvbHVtbjogcGF0aC5sb2Muc3RhcnQuY29sdW1uICsgNCB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHBhdGguZGF0YSkge1xuICAgICAgbGV0IGhlYWQgPSBwYXJ0cy5zaGlmdCgpO1xuXG4gICAgICBpZiAoaGVhZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgICAgYEF0dGVtcHRlZCB0byBwYXJzZSBhIHBhdGggZXhwcmVzc2lvbiwgYnV0IGl0IHdhcyBub3QgdmFsaWQuIFBhdGhzIGJlZ2lubmluZyB3aXRoIEAgbXVzdCBzdGFydCB3aXRoIGEtei5gLFxuICAgICAgICAgIHRoaXMuc291cmNlLnNwYW5Gb3IocGF0aC5sb2MpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHBhdGhIZWFkID0ge1xuICAgICAgICB0eXBlOiAnQXRIZWFkJyxcbiAgICAgICAgbmFtZTogYEAke2hlYWR9YCxcbiAgICAgICAgbG9jOiB7XG4gICAgICAgICAgc3RhcnQ6IHBhdGgubG9jLnN0YXJ0LFxuICAgICAgICAgIGVuZDogeyBsaW5lOiBwYXRoLmxvYy5zdGFydC5saW5lLCBjb2x1bW46IHBhdGgubG9jLnN0YXJ0LmNvbHVtbiArIGhlYWQubGVuZ3RoICsgMSB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGhlYWQgPSBwYXJ0cy5zaGlmdCgpO1xuXG4gICAgICBpZiAoaGVhZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IGdlbmVyYXRlU3ludGF4RXJyb3IoXG4gICAgICAgICAgYEF0dGVtcHRlZCB0byBwYXJzZSBhIHBhdGggZXhwcmVzc2lvbiwgYnV0IGl0IHdhcyBub3QgdmFsaWQuIFBhdGhzIG11c3Qgc3RhcnQgd2l0aCBhLXogb3IgQS1aLmAsXG4gICAgICAgICAgdGhpcy5zb3VyY2Uuc3BhbkZvcihwYXRoLmxvYylcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcGF0aEhlYWQgPSB7XG4gICAgICAgIHR5cGU6ICdWYXJIZWFkJyxcbiAgICAgICAgbmFtZTogaGVhZCxcbiAgICAgICAgbG9jOiB7XG4gICAgICAgICAgc3RhcnQ6IHBhdGgubG9jLnN0YXJ0LFxuICAgICAgICAgIGVuZDogeyBsaW5lOiBwYXRoLmxvYy5zdGFydC5saW5lLCBjb2x1bW46IHBhdGgubG9jLnN0YXJ0LmNvbHVtbiArIGhlYWQubGVuZ3RoIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGF0aEV4cHJlc3Npb25JbXBsVjEocGF0aC5vcmlnaW5hbCwgcGF0aEhlYWQsIHBhcnRzLCB0aGlzLnNvdXJjZS5zcGFuRm9yKHBhdGgubG9jKSk7XG4gIH1cblxuICBIYXNoKGhhc2g6IEhCUy5IYXNoKTogQVNUdjEuSGFzaCB7XG4gICAgbGV0IHBhaXJzOiBBU1R2MS5IYXNoUGFpcltdID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhhc2gucGFpcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBwYWlyID0gaGFzaC5wYWlyc1tpXTtcbiAgICAgIHBhaXJzLnB1c2goXG4gICAgICAgIGIucGFpcih7XG4gICAgICAgICAga2V5OiBwYWlyLmtleSxcbiAgICAgICAgICB2YWx1ZTogdGhpcy5hY2NlcHROb2RlKHBhaXIudmFsdWUpLFxuICAgICAgICAgIGxvYzogdGhpcy5zb3VyY2Uuc3BhbkZvcihwYWlyLmxvYyksXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBiLmhhc2gocGFpcnMsIHRoaXMuc291cmNlLnNwYW5Gb3IoaGFzaC5sb2MpKTtcbiAgfVxuXG4gIFN0cmluZ0xpdGVyYWwoc3RyaW5nOiBIQlMuU3RyaW5nTGl0ZXJhbCk6IEFTVHYxLlN0cmluZ0xpdGVyYWwge1xuICA