UNPKG

oidc-client

Version:

OpenID Connect (OIDC) & OAuth2 client library

268 lines (266 loc) 39.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ const source_map_1 = require("source-map"); // Matches <%= expr %>. This does not support structural JavaScript (for/if/...). const kInterpolateRe = /<%=([\s\S]+?)%>/g; // Matches <%# text %>. It's a comment and will be entirely ignored. const kCommentRe = /<%#([\s\S]+?)%>/g; // Used to match template delimiters. // <%- expr %>: HTML escape the value. // <% ... %>: Structural template code. const kEscapeRe = /<%-([\s\S]+?)%>/g; const kEvaluateRe = /<%([\s\S]+?)%>/g; /** Used to map characters to HTML entities. */ const kHtmlEscapes = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;', '`': '&#96;', }; // Used to match HTML entities and HTML characters. const reUnescapedHtml = new RegExp(`[${Object.keys(kHtmlEscapes).join('')}]`, 'g'); function _positionFor(content, offset) { let line = 1; let column = 0; for (let i = 0; i < offset - 1; i++) { if (content[i] == '\n') { line++; column = 0; } else { column++; } } return { line, column, }; } /** * Given a source text (and a fileName), returns a TemplateAst. */ function templateParser(sourceText, fileName) { const children = []; // Compile the regexp to match each delimiter. const reExpressions = [kEscapeRe, kCommentRe, kInterpolateRe, kEvaluateRe]; const reDelimiters = RegExp(reExpressions.map(x => x.source).join('|') + '|$', 'g'); const parsed = sourceText.split(reDelimiters); let offset = 0; // Optimization that uses the fact that the end of a node is always the beginning of the next // node, so we keep the positioning of the nodes in memory. let start = _positionFor(sourceText, offset); let end; const increment = reExpressions.length + 1; for (let i = 0; i < parsed.length; i += increment) { const [content, escape, comment, interpolate, evaluate] = parsed.slice(i, i + increment); if (content) { end = _positionFor(sourceText, offset + content.length); offset += content.length; children.push({ kind: 'content', content, start, end }); start = end; } if (escape) { end = _positionFor(sourceText, offset + escape.length + 5); offset += escape.length + 5; children.push({ kind: 'escape', expression: escape, start, end }); start = end; } if (comment) { end = _positionFor(sourceText, offset + comment.length + 5); offset += comment.length + 5; children.push({ kind: 'comment', text: comment, start, end }); start = end; } if (interpolate) { end = _positionFor(sourceText, offset + interpolate.length + 5); offset += interpolate.length + 5; children.push({ kind: 'interpolate', expression: interpolate, start, end, }); start = end; } if (evaluate) { end = _positionFor(sourceText, offset + evaluate.length + 5); offset += evaluate.length + 5; children.push({ kind: 'evaluate', expression: evaluate, start, end }); start = end; } } return { fileName, content: sourceText, children, }; } exports.templateParser = templateParser; /** * Fastest implementation of the templating algorithm. It only add strings and does not bother * with source maps. */ function templateFast(ast, options) { const module = options && options.module ? 'module.exports.default =' : ''; const reHtmlEscape = reUnescapedHtml.source.replace(/[']/g, '\\\\\\\''); return ` return ${module} function(obj) { obj || (obj = {}); let __t; let __p = ''; const __escapes = ${JSON.stringify(kHtmlEscapes)}; const __escapesre = new RegExp('${reHtmlEscape}', 'g'); const __e = function(s) { return s ? s.replace(__escapesre, function(key) { return __escapes[key]; }) : ''; }; with (obj) { ${ast.children.map(node => { switch (node.kind) { case 'content': return `__p += ${JSON.stringify(node.content)};`; case 'interpolate': return `__p += ((__t = (${node.expression})) == null) ? '' : __t;`; case 'escape': return `__p += __e(${node.expression});`; case 'evaluate': return node.expression; } }).join('\n')} } return __p; }; `; } /** * Templating algorithm with source map support. The map is outputted as //# sourceMapUrl=... */ function templateWithSourceMap(ast, options) { const sourceUrl = ast.fileName; const module = options && options.module ? 'module.exports.default =' : ''; const reHtmlEscape = reUnescapedHtml.source.replace(/[']/g, '\\\\\\\''); const preamble = (new source_map_1.SourceNode(1, 0, sourceUrl, '')) .add(new source_map_1.SourceNode(1, 0, sourceUrl, [ `return ${module} function(obj) {\n`, ' obj || (obj = {});\n', ' let __t;\n', ' let __p = "";\n', ` const __escapes = ${JSON.stringify(kHtmlEscapes)};\n`, ` const __escapesre = new RegExp('${reHtmlEscape}', 'g');\n`, `\n`, ` const __e = function(s) { `, ` return s ? s.replace(__escapesre, function(key) { return __escapes[key]; }) : '';`, ` };\n`, ` with (obj) {\n`, ])); const end = ast.children.length ? ast.children[ast.children.length - 1].end : { line: 0, column: 0 }; const nodes = ast.children.reduce((chunk, node) => { let code = ''; switch (node.kind) { case 'content': code = [ new source_map_1.SourceNode(node.start.line, node.start.column, sourceUrl, '__p = __p'), ...node.content.split('\n').map((line, i, arr) => { return new source_map_1.SourceNode(node.start.line + i, i == 0 ? node.start.column : 0, sourceUrl, '\n + ' + JSON.stringify(line + (i == arr.length - 1 ? '' : '\n'))); }), new source_map_1.SourceNode(node.end.line, node.end.column, sourceUrl, ';\n'), ]; break; case 'interpolate': code = [ new source_map_1.SourceNode(node.start.line, node.start.column, sourceUrl, '__p += ((__t = '), ...node.expression.split('\n').map((line, i, arr) => { return new source_map_1.SourceNode(node.start.line + i, i == 0 ? node.start.column : 0, sourceUrl, line + ((i == arr.length - 1) ? '' : '\n')); }), new source_map_1.SourceNode(node.end.line, node.end.column, sourceUrl, ') == null ? "" : __t);\n'), ]; break; case 'escape': code = [ new source_map_1.SourceNode(node.start.line, node.start.column, sourceUrl, '__p += __e('), ...node.expression.split('\n').map((line, i, arr) => { return new source_map_1.SourceNode(node.start.line + i, i == 0 ? node.start.column : 0, sourceUrl, line + ((i == arr.length - 1) ? '' : '\n')); }), new source_map_1.SourceNode(node.end.line, node.end.column, sourceUrl, ');\n'), ]; break; case 'evaluate': code = [ ...node.expression.split('\n').map((line, i, arr) => { return new source_map_1.SourceNode(node.start.line + i, i == 0 ? node.start.column : 0, sourceUrl, line + ((i == arr.length - 1) ? '' : '\n')); }), new source_map_1.SourceNode(node.end.line, node.end.column, sourceUrl, '\n'), ]; break; } return chunk.add(new source_map_1.SourceNode(node.start.line, node.start.column, sourceUrl, code)); }, preamble) .add(new source_map_1.SourceNode(end.line, end.column, sourceUrl, [ ' };\n', '\n', ' return __p;\n', '}\n', ])); const code = nodes.toStringWithSourceMap({ file: sourceUrl, sourceRoot: options && options.sourceRoot || '.', }); // Set the source content in the source map, otherwise the sourceUrl is not enough // to find the content. code.map.setSourceContent(sourceUrl, ast.content); return code.code + '\n//# sourceMappingURL=data:application/json;base64,' + Buffer.from(code.map.toString()).toString('base64'); } /** * An equivalent of EJS templates, which is based on John Resig's `tmpl` implementation * (http://ejohn.org/blog/javascript-micro-templating/) and Laura Doktorova's doT.js * (https://github.com/olado/doT). * * This version differs from lodash by removing support from ES6 quasi-literals, and making the * code slightly simpler to follow. It also does not depend on any third party, which is nice. * * Finally, it supports SourceMap, if you ever need to debug, which is super nice. * * @param content The template content. * @param options Optional Options. See TemplateOptions for more description. * @return {(input: T) => string} A function that accept an input object and returns the content * of the template with the input applied. */ function template(content, options) { const sourceUrl = options && options.sourceURL || 'ejs'; const ast = templateParser(content, sourceUrl); let source; // If there's no need for source map support, we revert back to the fast implementation. if (options && options.sourceMap) { source = templateWithSourceMap(ast, options); } else { source = templateFast(ast, options); } // We pass a dummy module in case the module option is passed. If `module: true` is passed, we // need to only use the source, not the function itself. Otherwise expect a module object to be // passed, and we use that one. const fn = Function('module', source); const module = options && options.module ? (options.module === true ? { exports: {} } : options.module) : null; const result = fn(module); // Provide the compiled function's source by its `toString` method or // the `source` property as a convenience for inlining compiled templates. result.source = source; return result; } exports.template = template; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUuanMiLCJzb3VyY2VSb290IjoiLi8iLCJzb3VyY2VzIjpbInBhY2thZ2VzL2FuZ3VsYXJfZGV2a2l0L2NvcmUvc3JjL3V0aWxzL3RlbXBsYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7OztHQU1HO0FBQ0gsMkNBQWtEO0FBRWxELGlGQUFpRjtBQUNqRixNQUFNLGNBQWMsR0FBRyxrQkFBa0IsQ0FBQztBQUMxQyxvRUFBb0U7QUFDcEUsTUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQUM7QUFFdEMscUNBQXFDO0FBQ3JDLHNDQUFzQztBQUN0Qyx1Q0FBdUM7QUFDdkMsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUM7QUFDckMsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUM7QUFFdEMsK0NBQStDO0FBQy9DLE1BQU0sWUFBWSxHQUE2QjtJQUM3QyxHQUFHLEVBQUUsT0FBTztJQUNaLEdBQUcsRUFBRSxNQUFNO0lBQ1gsR0FBRyxFQUFFLE1BQU07SUFDWCxHQUFHLEVBQUUsUUFBUTtJQUNiLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87Q0FDYixDQUFDO0FBRUYsbURBQW1EO0FBQ25ELE1BQU0sZUFBZSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQVluRixTQUFTLFlBQVksQ0FBQyxPQUFlLEVBQUUsTUFBYztJQUNuRCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7SUFDYixJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDZixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNuQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUU7WUFDdEIsSUFBSSxF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cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQgeyBQb3NpdGlvbiwgU291cmNlTm9kZSB9IGZyb20gJ3NvdXJjZS1tYXAnO1xuXG4vLyBNYXRjaGVzIDwlPSBleHByICU+LiBUaGlzIGRvZXMgbm90IHN1cHBvcnQgc3RydWN0dXJhbCBKYXZhU2NyaXB0IChmb3IvaWYvLi4uKS5cbmNvbnN0IGtJbnRlcnBvbGF0ZVJlID0gLzwlPShbXFxzXFxTXSs/KSU+L2c7XG4vLyBNYXRjaGVzIDwlIyB0ZXh0ICU+LiBJdCdzIGEgY29tbWVudCBhbmQgd2lsbCBiZSBlbnRpcmVseSBpZ25vcmVkLlxuY29uc3Qga0NvbW1lbnRSZSA9IC88JSMoW1xcc1xcU10rPyklPi9nO1xuXG4vLyBVc2VkIHRvIG1hdGNoIHRlbXBsYXRlIGRlbGltaXRlcnMuXG4vLyA8JS0gZXhwciAlPjogSFRNTCBlc2NhcGUgdGhlIHZhbHVlLlxuLy8gPCUgLi4uICU+OiBTdHJ1Y3R1cmFsIHRlbXBsYXRlIGNvZGUuXG5jb25zdCBrRXNjYXBlUmUgPSAvPCUtKFtcXHNcXFNdKz8pJT4vZztcbmNvbnN0IGtFdmFsdWF0ZVJlID0gLzwlKFtcXHNcXFNdKz8pJT4vZztcblxuLyoqIFVzZWQgdG8gbWFwIGNoYXJhY3RlcnMgdG8gSFRNTCBlbnRpdGllcy4gKi9cbmNvbnN0IGtIdG1sRXNjYXBlczoge1tjaGFyOiBzdHJpbmddOiBzdHJpbmd9ID0ge1xuICAnJic6ICcmYW1wOycsXG4gICc8JzogJyZsdDsnLFxuICAnPic6ICcmZ3Q7JyxcbiAgJ1wiJzogJyZxdW90OycsXG4gIFwiJ1wiOiAnJiMzOTsnLFxuICAnYCc6ICcmIzk2OycsXG59O1xuXG4vLyBVc2VkIHRvIG1hdGNoIEhUTUwgZW50aXRpZXMgYW5kIEhUTUwgY2hhcmFjdGVycy5cbmNvbnN0IHJlVW5lc2NhcGVkSHRtbCA9IG5ldyBSZWdFeHAoYFske09iamVjdC5rZXlzKGtIdG1sRXNjYXBlcykuam9pbignJyl9XWAsICdnJyk7XG5cbi8vIE9wdGlvbnMgdG8gcGFzcyB0byB0ZW1wbGF0ZS5cbmV4cG9ydCBpbnRlcmZhY2UgVGVtcGxhdGVPcHRpb25zIHtcbiAgc291cmNlVVJMPzogc3RyaW5nO1xuICBzb3VyY2VNYXA/OiBib29sZWFuO1xuICBtb2R1bGU/OiBib29sZWFuIHwgeyBleHBvcnRzOiB7fSB9O1xuICBzb3VyY2VSb290Pzogc3RyaW5nO1xuICBmaWxlTmFtZT86IHN0cmluZztcbn1cblxuXG5mdW5jdGlvbiBfcG9zaXRpb25Gb3IoY29udGVudDogc3RyaW5nLCBvZmZzZXQ6IG51bWJlcik6IFBvc2l0aW9uIHtcbiAgbGV0IGxpbmUgPSAxO1xuICBsZXQgY29sdW1uID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmZzZXQgLSAxOyBpKyspIHtcbiAgICBpZiAoY29udGVudFtpXSA9PSAnXFxuJykge1xuICAgICAgbGluZSsrO1xuICAgICAgY29sdW1uID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29sdW1uKys7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBsaW5lLFxuICAgIGNvbHVtbixcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHNpbXBsZSBBU1QgZm9yIHRlbXBsYXRlcy4gVGhlcmUncyBvbmx5IG9uZSBsZXZlbCBvZiBBU1Qgbm9kZXMsIGJ1dCBpdCdzIHN0aWxsIHVzZWZ1bFxuICogdG8gaGF2ZSB0aGUgaW5mb3JtYXRpb24geW91J3JlIGxvb2tpbmcgZm9yLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbXBsYXRlQXN0IHtcbiAgZmlsZU5hbWU6IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBjaGlsZHJlbjogVGVtcGxhdGVBc3ROb2RlW107XG59XG5cbi8qKlxuICogVGhlIGJhc2UsIHdoaWNoIGNvbnRhaW5zIHBvc2l0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZUFzdEJhc2Uge1xuICBzdGFydDogUG9zaXRpb247XG4gIGVuZDogUG9zaXRpb247XG59XG5cbi8qKlxuICogQSBzdGF0aWMgY29udGVudCBub2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbXBsYXRlQXN0Q29udGVudCBleHRlbmRzIFRlbXBsYXRlQXN0QmFzZSB7XG4gIGtpbmQ6ICdjb250ZW50JztcbiAgY29udGVudDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgY29tbWVudCBub2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbXBsYXRlQXN0Q29tbWVudCBleHRlbmRzIFRlbXBsYXRlQXN0QmFzZSB7XG4gIGtpbmQ6ICdjb21tZW50JztcbiAgdGV4dDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFuIGV2YWx1YXRlIG5vZGUsIHdoaWNoIGlzIHRoZSBjb2RlIGJldHdlZW4gYDwlIC4uLiAlPmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVtcGxhdGVBc3RFdmFsdWF0ZSBleHRlbmRzIFRlbXBsYXRlQXN0QmFzZSB7XG4gIGtpbmQ6ICdldmFsdWF0ZSc7XG4gIGV4cHJlc3Npb246IHN0cmluZztcbn1cblxuLyoqXG4gKiBBbiBlc2NhcGUgbm9kZSwgd2hpY2ggaXMgdGhlIGNvZGUgYmV0d2VlbiBgPCUtIC4uLiAlPmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVtcGxhdGVBc3RFc2NhcGUgZXh0ZW5kcyBUZW1wbGF0ZUFzdEJhc2Uge1xuICBraW5kOiAnZXNjYXBlJztcbiAgZXhwcmVzc2lvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFuIGludGVycG9sYXRpb24gbm9kZSwgd2hpY2ggaXMgdGhlIGNvZGUgYmV0d2VlbiBgPCU9IC4uLiAlPmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVtcGxhdGVBc3RJbnRlcnBvbGF0ZSBleHRlbmRzIFRlbXBsYXRlQXN0QmFzZSB7XG4gIGtpbmQ6ICdpbnRlcnBvbGF0ZSc7XG4gIGV4cHJlc3Npb246IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgVGVtcGxhdGVBc3ROb2RlID0gVGVtcGxhdGVBc3RDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUZW1wbGF0ZUFzdEV2YWx1YXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUZW1wbGF0ZUFzdENvbW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFRlbXBsYXRlQXN0RXNjYXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUZW1wbGF0ZUFzdEludGVycG9sYXRlO1xuXG4vKipcbiAqIEdpdmVuIGEgc291cmNlIHRleHQgKGFuZCBhIGZpbGVOYW1lKSwgcmV0dXJucyBhIFRlbXBsYXRlQXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGVtcGxhdGVQYXJzZXIoc291cmNlVGV4dDogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nKTogVGVtcGxhdGVBc3Qge1xuICBjb25zdCBjaGlsZHJlbiA9IFtdO1xuXG4gIC8vIENvbXBpbGUgdGhlIHJlZ2V4cCB0byBtYXRjaCBlYWNoIGRlbGltaXRlci5cbiAgY29uc3QgcmVFeHByZXNzaW9ucyA9IFtrRXNjYXBlUmUsIGtDb21tZW50UmUsIGtJbnRlcnBvbGF0ZVJlLCBrRXZhbHVhdGVSZV07XG4gIGNvbnN0IHJlRGVsaW1pdGVycyA9IFJlZ0V4cChyZUV4cHJlc3Npb25zLm1hcCh4ID0+IHguc291cmNlKS5qb2luKCd8JykgKyAnfCQnLCAnZycpO1xuXG4gIGNvbnN0IHBhcnNlZCA9IHNvdXJjZVRleHQuc3BsaXQocmVEZWxpbWl0ZXJzKTtcbiAgbGV0IG9mZnNldCA9IDA7XG4gIC8vIE9wdGltaXphdGlvbiB0aGF0IHVzZXMgdGhlIGZhY3QgdGhhdCB0aGUgZW5kIG9mIGEgbm9kZSBpcyBhbHdheXMgdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dFxuICAvLyBub2RlLCBzbyB3ZSBrZWVwIHRoZSBwb3NpdGlvbmluZyBvZiB0aGUgbm9kZXMgaW4gbWVtb3J5LlxuICBsZXQgc3RhcnQgPSBfcG9zaXRpb25Gb3Ioc291cmNlVGV4dCwgb2Zmc2V0KTtcbiAgbGV0IGVuZDogUG9zaXRpb24gfCBudWxsO1xuXG4gIGNvbnN0IGluY3JlbWVudCA9IHJlRXhwcmVzc2lvbnMubGVuZ3RoICsgMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpICs9IGluY3JlbWVudCkge1xuICAgIGNvbnN0IFtjb250ZW50LCBlc2NhcGUsIGNvbW1lbnQsIGludGVycG9sYXRlLCBldmFsdWF0ZV0gPSBwYXJzZWQuc2xpY2UoaSwgaSArIGluY3JlbWVudCk7XG4gICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgIGVuZCA9IF9wb3NpdGlvbkZvcihzb3VyY2VUZXh0LCBvZmZzZXQgKyBjb250ZW50Lmxlbmd0aCk7XG4gICAgICBvZmZzZXQgKz0gY29udGVudC5sZW5ndGg7XG4gICAgICBjaGlsZHJlbi5wdXNoKHsga2luZDogJ2NvbnRlbnQnLCBjb250ZW50LCBzdGFydCwgZW5kIH0gYXMgVGVtcGxhdGVBc3RDb250ZW50KTtcbiAgICAgIHN0YXJ0ID0gZW5kO1xuICAgIH1cbiAgICBpZiAoZXNjYXBlKSB7XG4gICAgICBlbmQgPSBfcG9zaXRpb25Gb3Ioc291cmNlVGV4dCwgb2Zmc2V0ICsgZXNjYXBlLmxlbmd0aCArIDUpO1xuICAgICAgb2Zmc2V0ICs9IGVzY2FwZS5sZW5ndGggKyA1O1xuICAgICAgY2hpbGRyZW4ucHVzaCh7IGtpbmQ6ICdlc2NhcGUnLCBleHByZXNzaW9uOiBlc2NhcGUsIHN0YXJ0LCBlbmQgfSBhcyBUZW1wbGF0ZUFzdEVzY2FwZSk7XG4gICAgICBzdGFydCA9IGVuZDtcbiAgICB9XG4gICAgaWYgKGNvbW1lbnQpIHtcbiAgICAgIGVuZCA9IF9wb3NpdGlvbkZvcihzb3VyY2VUZXh0LCBvZmZzZXQgKyBjb21tZW50Lmxlbmd0aCArIDUpO1xuICAgICAgb2Zmc2V0ICs9IGNvbW1lbnQubGVuZ3RoICsgNTtcbiAgICAgIGNoaWxkcmVuLnB1c2goeyBraW5kOiAnY29tbWVudCcsIHRleHQ6IGNvbW1lbnQsIHN0YXJ0LCBlbmQgfSBhcyBUZW1wbGF0ZUFzdENvbW1lbnQpO1xuICAgICAgc3RhcnQgPSBlbmQ7XG4gICAgfVxuICAgIGlmIChpbnRlcnBvbGF0ZSkge1xuICAgICAgZW5kID0gX3Bvc2l0aW9uRm9yKHNvdXJjZVRleHQsIG9mZnNldCArIGludGVycG9sYXRlLmxlbmd0aCArIDUpO1xuICAgICAgb2Zmc2V0ICs9IGludGVycG9sYXRlLmxlbmd0aCArIDU7XG4gICAgICBjaGlsZHJlbi5wdXNoKHtcbiAgICAgICAga2luZDogJ2ludGVycG9sYXRlJyxcbiAgICAgICAgZXhwcmVzc2lvbjogaW50ZXJwb2xhdGUsXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBlbmQsXG4gICAgICB9IGFzIFRlbXBsYXRlQXN0SW50ZXJwb2xhdGUpO1xuICAgICAgc3RhcnQgPSBlbmQ7XG4gICAgfVxuICAgIGlmIChldmFsdWF0ZSkge1xuICAgICAgZW5kID0gX3Bvc2l0aW9uRm9yKHNvdXJjZVRleHQsIG9mZnNldCArIGV2YWx1YXRlLmxlbmd0aCArIDUpO1xuICAgICAgb2Zmc2V0ICs9IGV2YWx1YXRlLmxlbmd0aCArIDU7XG4gICAgICBjaGlsZHJlbi5wdXNoKHsga2luZDogJ2V2YWx1YXRlJywgZXhwcmVzc2lvbjogZXZhbHVhdGUsIHN0YXJ0LCBlbmQgfSBhcyBUZW1wbGF0ZUFzdEV2YWx1YXRlKTtcbiAgICAgIHN0YXJ0ID0gZW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZmlsZU5hbWUsXG4gICAgY29udGVudDogc291cmNlVGV4dCxcbiAgICBjaGlsZHJlbixcbiAgfTtcbn1cblxuLyoqXG4gKiBGYXN0ZXN0IGltcGxlbWVudGF0aW9uIG9mIHRoZSB0ZW1wbGF0aW5nIGFsZ29yaXRobS4gSXQgb25seSBhZGQgc3RyaW5ncyBhbmQgZG9lcyBub3QgYm90aGVyXG4gKiB3aXRoIHNvdXJjZSBtYXBzLlxuICovXG5mdW5jdGlvbiB0ZW1wbGF0ZUZhc3QoYXN0OiBUZW1wbGF0ZUFzdCwgb3B0aW9ucz86IFRlbXBsYXRlT3B0aW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IG1vZHVsZSA9IG9wdGlvbnMgJiYgb3B0aW9ucy5tb2R1bGUgPyAnbW9kdWxlLmV4cG9ydHMuZGVmYXVsdCA9JyA6ICcnO1xuICBjb25zdCByZUh0bWxFc2NhcGUgPSByZVVuZXNjYXBlZEh0bWwuc291cmNlLnJlcGxhY2UoL1snXS9nLCAnXFxcXFxcXFxcXFxcXFwnJyk7XG5cbiAgcmV0dXJuIGBcbiAgICByZXR1cm4gJHttb2R1bGV9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgb2JqIHx8IChvYmogPSB7fSk7XG4gICAgICBsZXQgX190O1xuICAgICAgbGV0IF9fcCA9ICcnO1xuICAgICAgY29uc3QgX19lc2NhcGVzID0gJHtKU09OLnN0cmluZ2lmeShrSHRtbEVzY2FwZXMpfTtcbiAgICAgIGNvbnN0IF9fZXNjYXBlc3JlID0gbmV3IFJlZ0V4cCgnJHtyZUh0bWxFc2NhcGV9JywgJ2cnKTtcblxuICAgICAgY29uc3QgX19lID0gZnVuY3Rpb24ocykge1xuICAgICAgICByZXR1cm4gcyA/IHMucmVwbGFjZShfX2VzY2FwZXNyZSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiBfX2VzY2FwZXNba2V5XTsgfSkgOiAnJztcbiAgICAgIH07XG4gICAgICB3aXRoIChvYmopIHtcbiAgICAgICAgJHthc3QuY2hpbGRyZW4ubWFwKG5vZGUgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChub2RlLmtpbmQpIHtcbiAgICAgICAgICAgICAgY2FzZSAnY29udGVudCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBfX3AgKz0gJHtKU09OLnN0cmluZ2lmeShub2RlLmNvbnRlbnQpfTtgO1xuICAgICAgICAgICAgICBjYXNlICdpbnRlcnBvbGF0ZSc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBfX3AgKz0gKChfX3QgPSAoJHtub2RlLmV4cHJlc3Npb259KSkgPT0gbnVsbCkgPyAnJyA6IF9fdDtgO1xuICAgICAgICAgICAgICBjYXNlICdlc2NhcGUnOlxuICAgICAgICAgICAgICAgIHJldHVybiBgX19wICs9IF9fZSgke25vZGUuZXhwcmVzc2lvbn0pO2A7XG4gICAgICAgICAgICAgIGNhc2UgJ2V2YWx1YXRlJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5leHByZXNzaW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9fcDtcbiAgICB9O1xuICBgO1xufVxuXG4vKipcbiAqIFRlbXBsYXRpbmcgYWxnb3JpdGhtIHdpdGggc291cmNlIG1hcCBzdXBwb3J0LiBUaGUgbWFwIGlzIG91dHB1dHRlZCBhcyAvLyMgc291cmNlTWFwVXJsPS4uLlxuICovXG5mdW5jdGlvbiB0ZW1wbGF0ZVdpdGhTb3VyY2VNYXAoYXN0OiBUZW1wbGF0ZUFzdCwgb3B0aW9ucz86IFRlbXBsYXRlT3B0aW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IHNvdXJjZVVybCA9IGFzdC5maWxlTmFtZTtcbiAgY29uc3QgbW9kdWxlID0gb3B0aW9ucyAmJiBvcHRpb25zLm1vZHVsZSA/ICdtb2R1bGUuZXhwb3J0cy5kZWZhdWx0ID0nIDogJyc7XG4gIGNvbnN0IHJlSHRtbEVzY2FwZSA9IHJlVW5lc2NhcGVkSHRtbC5zb3VyY2UucmVwbGFjZSgvWyddL2csICdcXFxcXFxcXFxcXFxcXCcnKTtcblxuICBjb25zdCBwcmVhbWJsZSA9IChuZXcgU291cmNlTm9kZSgxLCAwLCBzb3VyY2VVcmwsICcnKSlcbiAgICAuYWRkKG5ldyBTb3VyY2VOb2RlKDEsIDAsIHNvdXJjZVVybCwgW1xuICAgICAgYHJldHVybiAke21vZHVsZX0gZnVuY3Rpb24ob2JqKSB7XFxuYCxcbiAgICAgICcgIG9iaiB8fCAob2JqID0ge30pO1xcbicsXG4gICAgICAnICBsZXQgX190O1xcbicsXG4gICAgICAnICBsZXQgX19wID0gXCJcIjtcXG4nLFxuICAgICAgYCAgY29uc3QgX19lc2NhcGVzID0gJHtKU09OLnN0cmluZ2lmeShrSHRtbEVzY2FwZXMpfTtcXG5gLFxuICAgICAgYCAgY29uc3QgX19lc2NhcGVzcmUgPSBuZXcgUmVnRXhwKCcke3JlSHRtbEVzY2FwZX0nLCAnZycpO1xcbmAsXG4gICAgICBgXFxuYCxcbiAgICAgIGAgIGNvbnN0IF9fZSA9IGZ1bmN0aW9uKHMpIHsgYCxcbiAgICAgIGAgICAgcmV0dXJuIHMgPyBzLnJlcGxhY2UoX19lc2NhcGVzcmUsIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gX19lc2NhcGVzW2tleV07IH0pIDogJyc7YCxcbiAgICAgIGAgIH07XFxuYCxcbiAgICAgIGAgIHdpdGggKG9iaikge1xcbmAsXG4gICAgXSkpO1xuXG4gIGNvbnN0IGVuZCA9IGFzdC5jaGlsZHJlbi5sZW5ndGhcbiAgICA/IGFzdC5jaGlsZHJlblthc3QuY2hpbGRyZW4ubGVuZ3RoIC0gMV0uZW5kXG4gICAgOiB7IGxpbmU6IDAsIGNvbHVtbjogMCB9O1xuICBjb25zdCBub2RlcyA9IGFzdC5jaGlsZHJlbi5yZWR1Y2UoKGNodW5rLCBub2RlKSA9PiB7XG4gICAgbGV0IGNvZGU6IHN0cmluZyB8IFNvdXJjZU5vZGUgfCAoU291cmNlTm9kZSB8IHN0cmluZylbXSA9ICcnO1xuICAgIHN3aXRjaCAobm9kZS5raW5kKSB7XG4gICAgICBjYXNlICdjb250ZW50JzpcbiAgICAgICAgY29kZSA9IFtcbiAgICAgICAgICBuZXcgU291cmNlTm9kZShub2RlLnN0YXJ0LmxpbmUsIG5vZGUuc3RhcnQuY29sdW1uLCBzb3VyY2VVcmwsICdfX3AgPSBfX3AnKSxcbiAgICAgICAgICAuLi5ub2RlLmNvbnRlbnQuc3BsaXQoJ1xcbicpLm1hcCgobGluZSwgaSwgYXJyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNvdXJjZU5vZGUoXG4gICAgICAgICAgICAgIG5vZGUuc3RhcnQubGluZSArIGksXG4gICAgICAgICAgICAgIGkgPT0gMCA/IG5vZGUuc3RhcnQuY29sdW1uIDogMCxcbiAgICAgICAgICAgICAgc291cmNlVXJsLFxuICAgICAgICAgICAgICAnXFxuICAgICsgJ1xuICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGxpbmUgKyAoaSA9PSBhcnIubGVuZ3RoIC0gMSA/ICcnIDogJ1xcbicpKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgbmV3IFNvdXJjZU5vZGUobm9kZS5lbmQubGluZSwgbm9kZS5lbmQuY29sdW1uLCBzb3VyY2VVcmwsICc7XFxuJyksXG4gICAgICAgIF07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW50ZXJwb2xhdGUnOlxuICAgICAgICBjb2RlID0gW1xuICAgICAgICAgIG5ldyBTb3VyY2VOb2RlKG5vZGUuc3RhcnQubGluZSwgbm9kZS5zdGFydC5jb2x1bW4sIHNvdXJjZVVybCwgJ19fcCArPSAoKF9fdCA9ICcpLFxuICAgICAgICAgIC4uLm5vZGUuZXhwcmVzc2lvbi5zcGxpdCgnXFxuJykubWFwKChsaW5lLCBpLCBhcnIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU291cmNlTm9kZShcbiAgICAgICAgICAgICAgbm9kZS5zdGFydC5saW5lICsgaSxcbiAgICAgICAgICAgICAgaSA9PSAwID8gbm9kZS5zdGFydC5jb2x1bW4gOiAwLFxuICAgICAgICAgICAgICBzb3VyY2VVcmwsXG4gICAgICAgICAgICAgIGxpbmUgKyAoKGkgPT0gYXJyLmxlbmd0aCAtIDEpID8gJycgOiAnXFxuJyksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIG5ldyBTb3VyY2VOb2RlKG5vZGUuZW5kLmxpbmUsIG5vZGUuZW5kLmNvbHVtbiwgc291cmNlVXJsLCAnKSA9PSBudWxsID8gXCJcIiA6IF9fdCk7XFxuJyksXG4gICAgICAgIF07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZXNjYXBlJzpcbiAgICAgICAgY29kZSA9IFtcbiAgICAgICAgICBuZXcgU291cmNlTm9kZShub2RlLnN0YXJ0LmxpbmUsIG5vZGUuc3RhcnQuY29sdW1uLCBzb3VyY2VVcmwsICdfX3AgKz0gX19lKCcpLFxuICAgICAgICAgIC4uLm5vZGUuZXhwcmVzc2lvbi5zcGxpdCgnXFxuJykubWFwKChsaW5lLCBpLCBhcnIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU291cmNlTm9kZShcbiAgICAgICAgICAgICAgbm9kZS5zdGFydC5saW5lICsgaSxcbiAgICAgICAgICAgICAgaSA9PSAwID8gbm9kZS5zdGFydC5jb2x1bW4gOiAwLFxuICAgICAgICAgICAgICBzb3VyY2VVcmwsXG4gICAgICAgICAgICAgIGxpbmUgKyAoKGkgPT0gYXJyLmxlbmd0aCAtIDEpID8gJycgOiAnXFxuJyksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIG5ldyBTb3VyY2VOb2RlKG5vZGUuZW5kLmxpbmUsIG5vZGUuZW5kLmNvbHVtbiwgc291cmNlVXJsLCAnKTtcXG4nKSxcbiAgICAgICAgXTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdldmFsdWF0ZSc6XG4gICAgICAgIGNvZGUgPSBbXG4gICAgICAgICAgLi4ubm9kZS5leHByZXNzaW9uLnNwbGl0KCdcXG4nKS5tYXAoKGxpbmUsIGksIGFycikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBTb3VyY2VOb2RlKFxuICAgICAgICAgICAgICBub2RlLnN0YXJ0LmxpbmUgKyBpLFxuICAgICAgICAgICAgICBpID09IDAgPyBub2RlLnN0YXJ0LmNvbHVtbiA6IDAsXG4gICAgICAgICAgICAgIHNvdXJjZVVybCxcbiAgICAgICAgICAgICAgbGluZSArICgoaSA9PSBhcnIubGVuZ3RoIC0gMSkgPyAnJyA6ICdcXG4nKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgbmV3IFNvdXJjZU5vZGUobm9kZS5lbmQubGluZSwgbm9kZS5lbmQuY29sdW1uLCBzb3VyY2VVcmwsICdcXG4nKSxcbiAgICAgICAgXTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNodW5rLmFkZChuZXcgU291cmNlTm9kZShub2RlLnN0YXJ0LmxpbmUsIG5vZGUuc3RhcnQuY29sdW1uLCBzb3VyY2VVcmwsIGNvZGUpKTtcbiAgfSwgcHJlYW1ibGUpXG4gIC5hZGQobmV3IFNvdXJjZU5vZGUoZW5kLmxpbmUsIGVuZC5jb2x1bW4sIHNvdXJjZVVybCwgW1xuICAgICcgIH07XFxuJyxcbiAgICAnXFxuJyxcbiAgICAnICByZXR1cm4gX19wO1xcbicsXG4gICAgJ31cXG4nLFxuICBdKSk7XG5cbiAgY29uc3QgY29kZSA9IG5vZGVzLnRvU3RyaW5nV2l0aFNvdXJjZU1hcCh7XG4gICAgZmlsZTogc291cmNlVXJsLFxuICAgIHNvdXJjZVJvb3Q6IG9wdGlvbnMgJiYgb3B0aW9ucy5zb3VyY2VSb290IHx8ICcuJyxcbiAgfSk7XG5cbiAgLy8gU2V0IHRoZSBzb3VyY2UgY29udGVudCBpbiB0aGUgc291cmNlIG1hcCwgb3RoZXJ3aXNlIHRoZSBzb3VyY2VVcmwgaXMgbm90IGVub3VnaFxuICAvLyB0byBmaW5kIHRoZSBjb250ZW50LlxuICBjb2RlLm1hcC5zZXRTb3VyY2VDb250ZW50KHNvdXJjZVVybCwgYXN0LmNvbnRlbnQpO1xuXG4gIHJldHVybiBjb2RlLmNvZGVcbiAgICAgICArICdcXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247YmFzZTY0LCdcbiAgICAgICArIEJ1ZmZlci5mcm9tKGNvZGUubWFwLnRvU3RyaW5nKCkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbn1cblxuXG4vKipcbiAqIEFuIGVxdWl2YWxlbnQgb2YgRUpTIHRlbXBsYXRlcywgd2hpY2ggaXMgYmFzZWQgb24gSm9obiBSZXNpZydzIGB0bXBsYCBpbXBsZW1lbnRhdGlvblxuICogKGh0dHA6Ly9lam9obi5vcmcvYmxvZy9qYXZhc2NyaXB0LW1pY3JvLXRlbXBsYXRpbmcvKSBhbmQgTGF1cmEgRG9rdG9yb3ZhJ3MgZG9ULmpzXG4gKiAoaHR0cHM6Ly9naXRodWIuY29tL29sYWRvL2RvVCkuXG4gKlxuICogVGhpcyB2ZXJzaW9uIGRpZmZlcnMgZnJvbSBsb2Rhc2ggYnkgcmVtb3Zpbmcgc3VwcG9ydCBmcm9tIEVTNiBxdWFzaS1saXRlcmFscywgYW5kIG1ha2luZyB0aGVcbiAqIGNvZGUgc2xpZ2h0bHkgc2ltcGxlciB0byBmb2xsb3cuIEl0IGFsc28gZG9lcyBub3QgZGVwZW5kIG9uIGFueSB0aGlyZCBwYXJ0eSwgd2hpY2ggaXMgbmljZS5cbiAqXG4gKiBGaW5hbGx5LCBpdCBzdXBwb3J0cyBTb3VyY2VNYXAsIGlmIHlvdSBldmVyIG5lZWQgdG8gZGVidWcsIHdoaWNoIGlzIHN1cGVyIG5pY2UuXG4gKlxuICogQHBhcmFtIGNvbnRlbnQgVGhlIHRlbXBsYXRlIGNvbnRlbnQuXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBPcHRpb25zLiBTZWUgVGVtcGxhdGVPcHRpb25zIGZvciBtb3JlIGRlc2NyaXB0aW9uLlxuICogQHJldHVybiB7KGlucHV0OiBUKSA9PiBzdHJpbmd9IEEgZnVuY3Rpb24gdGhhdCBhY2NlcHQgYW4gaW5wdXQgb2JqZWN0IGFuZCByZXR1cm5zIHRoZSBjb250ZW50XG4gKiAgICAgICAgIG9mIHRoZSB0ZW1wbGF0ZSB3aXRoIHRoZSBpbnB1dCBhcHBsaWVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGVtcGxhdGU8VD4oY29udGVudDogc3RyaW5nLCBvcHRpb25zPzogVGVtcGxhdGVPcHRpb25zKTogKGlucHV0OiBUKSA9PiBzdHJpbmcge1xuICBjb25zdCBzb3VyY2VVcmwgPSBvcHRpb25zICYmIG9wdGlvbnMuc291cmNlVVJMIHx8ICdlanMnO1xuICBjb25zdCBhc3QgPSB0ZW1wbGF0ZVBhcnNlcihjb250ZW50LCBzb3VyY2VVcmwpO1xuXG4gIGxldCBzb3VyY2U6IHN0cmluZztcbiAgLy8gSWYgdGhlcmUncyBubyBuZWVkIGZvciBzb3VyY2UgbWFwIHN1cHBvcnQsIHdlIHJldmVydCBiYWNrIHRvIHRoZSBmYXN0IGltcGxlbWVudGF0aW9uLlxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnNvdXJjZU1hcCkge1xuICAgIHNvdXJjZSA9IHRlbXBsYXRlV2l0aFNvdXJjZU1hcChhc3QsIG9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHNvdXJjZSA9IHRlbXBsYXRlRmFzdChhc3QsIG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gV2UgcGFzcyBhIGR1bW15IG1vZHVsZSBpbiBjYXNlIHRoZSBtb2R1bGUgb3B0aW9uIGlzIHBhc3NlZC4gSWYgYG1vZHVsZTogdHJ1ZWAgaXMgcGFzc2VkLCB3ZVxuICAvLyBuZWVkIHRvIG9ubHkgdXNlIHRoZSBzb3VyY2UsIG5vdCB0aGUgZnVuY3Rpb24gaXRzZWxmLiBPdGhlcndpc2UgZXhwZWN0IGEgbW9kdWxlIG9iamVjdCB0byBiZVxuICAvLyBwYXNzZWQsIGFuZCB3ZSB1c2UgdGhhdCBvbmUuXG4gIGNvbnN0IGZuID0gRnVuY3Rpb24oJ21vZHVsZScsIHNvdXJjZSk7XG4gIGNvbnN0IG1vZHVsZSA9IG9wdGlvbnMgJiYgb3B0aW9ucy5tb2R1bGVcbiAgICAgICAgICAgICAgID8gKG9wdGlvbnMubW9kdWxlID09PSB0cnVlID8geyBleHBvcnRzOiB7fSB9IDogb3B0aW9ucy5tb2R1bGUpXG4gICAgICAgICAgICAgICA6IG51bGw7XG4gIGNvbnN0IHJlc3VsdCA9IGZuKG1vZHVsZSk7XG5cbiAgLy8gUHJvdmlkZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24ncyBzb3VyY2UgYnkgaXRzIGB0b1N0cmluZ2AgbWV0aG9kIG9yXG4gIC8vIHRoZSBgc291cmNlYCBwcm9wZXJ0eSBhcyBhIGNvbnZlbmllbmNlIGZvciBpbmxpbmluZyBjb21waWxlZCB0ZW1wbGF0ZXMuXG4gIHJlc3VsdC5zb3VyY2UgPSBzb3VyY2U7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdfQ==