babel-plugin-ember-template-compilation
Version:
Babel implementation of Ember's low-level template-compilation API
196 lines • 23.3 kB
JavaScript
/*
This class exists because:
- before template compilation starts, we need to pass a `locals` array to
ember-template-compiler
- the JSUtils API can mutate the scope during template compilation
- those scope mutations need to update both the original `locals` array and
our own name mapping, keeping them in sync.
*/
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _ScopeLocals_instances, _ScopeLocals_mapping, _ScopeLocals_locals, _ScopeLocals_params, _ScopeLocals_isInJsScope;
import { astNodeHasBinding } from './hbs-utils.js';
import { readOnlyArray } from './read-only-array.js';
/**
* RFC: https://github.com/emberjs/rfcs/pull/1070
*
* Criteria for inclusion in this list:
*
* Any of:
* - begins with an uppercase letter
* - guaranteed to never be added to glimmer as a keyword (e.g.: globalThis)
*
* And:
* - must not need new to invoke
* - must not require lifetime management (e.g.: setTimeout)
* - must not be a single-word lower-case API, because of potential collision with future new HTML elements
* - if the API is a function, the return value should not be a promise
* - must be one one of these lists:
* - https://tc39.es/ecma262/#sec-global-object
* - https://tc39.es/ecma262/#sec-function-properties-of-the-global-object
* - https://html.spec.whatwg.org/multipage/nav-history-apis.html#window
* - https://html.spec.whatwg.org/multipage/indices.html#all-interfaces
* - https://html.spec.whatwg.org/multipage/webappapis.html
*/
export const ALLOWED_GLOBALS = new Set([
// ////////////////
// namespaces
// ////////////////
// TC39
'globalThis',
'Atomics',
'JSON',
'Math',
'Reflect',
// WHATWG
'localStorage',
'sessionStorage',
'URL',
// ////////////////
// functions / utilities
// ////////////////
// TC39
'isNaN',
'isFinite',
'parseInt',
'parseFloat',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
// WHATWG
'postMessage',
'structuredClone',
// ////////////////
// new-less Constructors (still functions)
// ////////////////
// TC39
'Array', // different behavior from (array)
'BigInt',
'Boolean',
'Date',
'Number',
'Object', // different behavior from (hash)
'String',
// ////////////////
// Values
// ////////////////
// TC39
'Infinity',
'NaN',
// WHATWG
'isSecureContext',
]);
export class ScopeLocals {
constructor(params) {
_ScopeLocals_instances.add(this);
_ScopeLocals_mapping.set(this, {});
_ScopeLocals_locals.set(this, []);
_ScopeLocals_params.set(this, void 0);
__classPrivateFieldSet(this, _ScopeLocals_params, params, "f");
}
get locals() {
return readOnlyArray(__classPrivateFieldGet(this, _ScopeLocals_locals, "f"), 'The only supported way to manipulate locals is via the jsutils API\nhttps://github.com/emberjs/babel-plugin-ember-template-compilation#jsutils-manipulating-javascript-from-within-ast-transforms');
}
has(key) {
return key in __classPrivateFieldGet(this, _ScopeLocals_mapping, "f");
}
get(key) {
return __classPrivateFieldGet(this, _ScopeLocals_mapping, "f")[key];
}
isEmpty() {
return __classPrivateFieldGet(this, _ScopeLocals_locals, "f").length === 0;
}
entries() {
return Object.entries(__classPrivateFieldGet(this, _ScopeLocals_mapping, "f"));
}
add(hbsName, jsName) {
__classPrivateFieldGet(this, _ScopeLocals_mapping, "f")[hbsName] = jsName ?? hbsName;
if (!__classPrivateFieldGet(this, _ScopeLocals_locals, "f").includes(hbsName)) {
__classPrivateFieldGet(this, _ScopeLocals_locals, "f").push(hbsName);
}
}
// this AST transform discovers all possible upvars in HBS that refer to valid
// bindings in JS, and then depending on the mode adjusts our actual scope bag
// contents.
crawl() {
return (_env) => {
let seen;
return {
name: 'scope-locals-crawl',
visitor: {
Template: {
enter: () => {
seen = new Set();
},
exit: (_node, _path) => {
if (__classPrivateFieldGet(this, _ScopeLocals_params, "f").mode === 'implicit') {
// all hbs upvars that have matching JS bindings go into the
// scope
for (let name of seen) {
if (name === 'this') {
if (__classPrivateFieldGet(this, _ScopeLocals_params, "f").mayUseLexicalThis) {
this.add(name);
}
}
else if (__classPrivateFieldGet(this, _ScopeLocals_instances, "m", _ScopeLocals_isInJsScope).call(this, name, __classPrivateFieldGet(this, _ScopeLocals_params, "f").jsPath)) {
this.add(name);
}
}
}
else {
// in explicit form, we might prune back the preexising scope in
// the case where another AST transform has eliminated the use
// of the original binding. But we don't add anything new. The
// only way for new bindings to be introduced into scope is for
// another AST transform to explicitly call the jsutils, which
// calls our `add`.
for (let name of Object.keys(__classPrivateFieldGet(this, _ScopeLocals_mapping, "f"))) {
if (!seen.has(name)) {
__classPrivateFieldGet(this, _ScopeLocals_locals, "f").splice(__classPrivateFieldGet(this, _ScopeLocals_locals, "f").indexOf(name), 1);
delete __classPrivateFieldGet(this, _ScopeLocals_mapping, "f")[name];
}
}
}
},
},
PathExpression: (node, path) => {
switch (node.head.type) {
case 'ThisHead':
if (!astNodeHasBinding(path, 'this')) {
seen.add('this');
}
break;
case 'VarHead': {
const name = node.head.name;
if (!astNodeHasBinding(path, name)) {
seen.add(name);
}
}
}
},
ElementNode: (node, path) => {
const name = node.tag.split('.')[0];
if (!astNodeHasBinding(path, name)) {
seen.add(name);
}
},
},
};
};
}
}
_ScopeLocals_mapping = new WeakMap(), _ScopeLocals_locals = new WeakMap(), _ScopeLocals_params = new WeakMap(), _ScopeLocals_instances = new WeakSet(), _ScopeLocals_isInJsScope = function _ScopeLocals_isInJsScope(hbsName, jsPath) {
let jsName = __classPrivateFieldGet(this, _ScopeLocals_mapping, "f")[hbsName] ?? hbsName;
return ALLOWED_GLOBALS.has(jsName) || jsPath.scope.getBinding(jsName);
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NvcGUtbG9jYWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Njb3BlLWxvY2Fscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztFQU9FOzs7Ozs7Ozs7Ozs7O0FBSUYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXJEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNyQyxtQkFBbUI7SUFDbkIsYUFBYTtJQUNiLG1CQUFtQjtJQUNuQixTQUFTO0lBQ1QsWUFBWTtJQUNaLFNBQVM7SUFDVCxNQUFNO0lBQ04sTUFBTTtJQUNOLFNBQVM7SUFDVCxXQUFXO0lBQ1gsY0FBYztJQUNkLGdCQUFnQjtJQUNoQixLQUFLO0lBQ0wsbUJBQW1CO0lBQ25CLHdCQUF3QjtJQUN4QixtQkFBbUI7SUFDbkIsU0FBUztJQUNULE9BQU87SUFDUCxVQUFVO0lBQ1YsVUFBVTtJQUNWLFlBQVk7SUFDWixXQUFXO0lBQ1gsb0JBQW9CO0lBQ3BCLFdBQVc7SUFDWCxvQkFBb0I7SUFDcEIsV0FBVztJQUNYLGFBQWE7SUFDYixpQkFBaUI7SUFDakIsbUJBQW1CO0lBQ25CLDBDQUEwQztJQUMxQyxtQkFBbUI7SUFDbkIsU0FBUztJQUNULE9BQU8sRUFBRSxrQ0FBa0M7SUFDM0MsUUFBUTtJQUNSLFNBQVM7SUFDVCxNQUFNO0lBQ04sUUFBUTtJQUNSLFFBQVEsRUFBRSxpQ0FBaUM7SUFDM0MsUUFBUTtJQUNSLG1CQUFtQjtJQUNuQixTQUFTO0lBQ1QsbUJBQW1CO0lBQ25CLFNBQVM7SUFDVCxVQUFVO0lBQ1YsS0FBSztJQUNMLFdBQVc7SUFDWCxpQkFBaUI7Q0FDbEIsQ0FBQyxDQUFDO0FBc0JILE1BQU0sT0FBTyxXQUFXO0lBQ3RCLFlBQVksTUFB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R0FBRyx1QkFBQSxJQUFJLDRCQUFTLENBQUMsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDO0lBQy9DLE9BQU8sZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN4RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgVGhpcyBjbGFzcyBleGlzdHMgYmVjYXVzZTpcbiAgIC0gYmVmb3JlIHRlbXBsYXRlIGNvbXBpbGF0aW9uIHN0YXJ0cywgd2UgbmVlZCB0byBwYXNzIGEgYGxvY2Fsc2AgYXJyYXkgdG9cbiAgICAgZW1iZXItdGVtcGxhdGUtY29tcGlsZXJcbiAgIC0gdGhlIEpTVXRpbHMgQVBJIGNhbiBtdXRhdGUgdGhlIHNjb3BlIGR1cmluZyB0ZW1wbGF0ZSBjb21waWxhdGlvblxuICAgLSB0aG9zZSBzY29wZSBtdXRhdGlvbnMgbmVlZCB0byB1cGRhdGUgYm90aCB0aGUgb3JpZ2luYWwgYGxvY2Fsc2AgYXJyYXkgYW5kXG4gICAgIG91ciBvd24gbmFtZSBtYXBwaW5nLCBrZWVwaW5nIHRoZW0gaW4gc3luYy5cbiovXG5cbmltcG9ydCB0eXBlIHsgTm9kZVBhdGggfSBmcm9tICdAYmFiZWwvdHJhdmVyc2UnO1xuaW1wb3J0IHR5cGUgeyBBU1RQbHVnaW5FbnZpcm9ubWVudCwgTm9kZVZpc2l0b3IgfSBmcm9tICdAZ2xpbW1lci9zeW50YXgnO1xuaW1wb3J0IHsgYXN0Tm9kZUhhc0JpbmRpbmcgfSBmcm9tICcuL2hicy11dGlscy5qcyc7XG5pbXBvcnQgeyByZWFkT25seUFycmF5IH0gZnJvbSAnLi9yZWFkLW9ubHktYXJyYXkuanMnO1xuXG4vKipcbiAqIFJGQzogaHR0cHM6Ly9naXRodWIuY29tL2VtYmVyanMvcmZjcy9wdWxsLzEwNzBcbiAqXG4gKiBDcml0ZXJpYSBmb3IgaW5jbHVzaW9uIGluIHRoaXMgbGlzdDpcbiAqXG4gKiAgIEFueSBvZjpcbiAqICAgICAtIGJlZ2lucyB3aXRoIGFuIHVwcGVyY2FzZSBsZXR0ZXJcbiAqICAgICAtIGd1YXJhbnRlZWQgdG8gbmV2ZXIgYmUgYWRkZWQgdG8gZ2xpbW1lciBhcyBhIGtleXdvcmQgKGUuZy46IGdsb2JhbFRoaXMpXG4gKlxuICogICBBbmQ6XG4gKiAgICAgLSBtdXN0IG5vdCBuZWVkIG5ldyB0byBpbnZva2VcbiAqICAgICAtIG11c3Qgbm90IHJlcXVpcmUgbGlmZXRpbWUgbWFuYWdlbWVudCAoZS5nLjogc2V0VGltZW91dClcbiAqICAgICAtIG11c3Qgbm90IGJlIGEgc2luZ2xlLXdvcmQgbG93ZXItY2FzZSBBUEksIGJlY2F1c2Ugb2YgcG90ZW50aWFsIGNvbGxpc2lvbiB3aXRoIGZ1dHVyZSBuZXcgSFRNTCBlbGVtZW50c1xuICogICAgIC0gaWYgdGhlIEFQSSBpcyBhIGZ1bmN0aW9uLCB0aGUgcmV0dXJuIHZhbHVlIHNob3VsZCBub3QgYmUgYSBwcm9taXNlXG4gKiAgICAgLSBtdXN0IGJlIG9uZSBvbmUgb2YgdGhlc2UgbGlzdHM6XG4gKiAgICAgICAgLSBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWdsb2JhbC1vYmplY3RcbiAqICAgICAgICAtIGh0dHBzOi8vdGMzOS5lcy9lY21hMjYyLyNzZWMtZnVuY3Rpb24tcHJvcGVydGllcy1vZi10aGUtZ2xvYmFsLW9iamVjdFxuICogICAgICAgIC0gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvbmF2LWhpc3RvcnktYXBpcy5odG1sI3dpbmRvd1xuICogICAgICAgIC0gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvaW5kaWNlcy5odG1sI2FsbC1pbnRlcmZhY2VzXG4gKiAgICAgICAgLSBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWxcbiAqL1xuZXhwb3J0IGNvbnN0IEFMTE9XRURfR0xPQkFMUyA9IG5ldyBTZXQoW1xuICAvLyAvLy8vLy8vLy8vLy8vLy8vXG4gIC8vIG5hbWVzcGFjZXNcbiAgLy8gLy8vLy8vLy8vLy8vLy8vL1xuICAvLyAgIFRDMzlcbiAgJ2dsb2JhbFRoaXMnLFxuICAnQXRvbWljcycsXG4gICdKU09OJyxcbiAgJ01hdGgnLFxuICAnUmVmbGVjdCcsXG4gIC8vICAgV0hBVFdHXG4gICdsb2NhbFN0b3JhZ2UnLFxuICAnc2Vzc2lvblN0b3JhZ2UnLFxuICAnVVJMJyxcbiAgLy8gLy8vLy8vLy8vLy8vLy8vL1xuICAvLyBmdW5jdGlvbnMgLyB1dGlsaXRpZXNcbiAgLy8gLy8vLy8vLy8vLy8vLy8vL1xuICAvLyAgIFRDMzlcbiAgJ2lzTmFOJyxcbiAgJ2lzRmluaXRlJyxcbiAgJ3BhcnNlSW50JyxcbiAgJ3BhcnNlRmxvYXQnLFxuICAnZGVjb2RlVVJJJyxcbiAgJ2RlY29kZVVSSUNvbXBvbmVudCcsXG4gICdlbmNvZGVVUkknLFxuICAnZW5jb2RlVVJJQ29tcG9uZW50JyxcbiAgLy8gICBXSEFUV0dcbiAgJ3Bvc3RNZXNzYWdlJyxcbiAgJ3N0cnVjdHVyZWRDbG9uZScsXG4gIC8vIC8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gbmV3LWxlc3MgQ29uc3RydWN0b3JzIChzdGlsbCBmdW5jdGlvbnMpXG4gIC8vIC8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gICBUQzM5XG4gICdBcnJheScsIC8vIGRpZmZlcmVudCBiZWhhdmlvciBmcm9tIChhcnJheSlcbiAgJ0JpZ0ludCcsXG4gICdCb29sZWFuJyxcbiAgJ0RhdGUnLFxuICAnTnVtYmVyJyxcbiAgJ09iamVjdCcsIC8vIGRpZmZlcmVudCBiZWhhdmlvciBmcm9tIChoYXNoKVxuICAnU3RyaW5nJyxcbiAgLy8gLy8vLy8vLy8vLy8vLy8vL1xuICAvLyBWYWx1ZXNcbiAgLy8gLy8vLy8vLy8vLy8vLy8vL1xuICAvLyAgIFRDMzlcbiAgJ0luZmluaXR5JyxcbiAgJ05hTicsXG4gIC8vICAgV0hBVFdHXG4gICdpc1NlY3VyZUNvbnRleHQnLFxuXSk7XG5cbi8qXG4gICAgYG1vZGVgIHJlZmVycyB0byB0aGUgaW1wbGljaXQgYW5kIGV4cGxpY2l0IGZvcm1hdHMgZGVmaW5lZCBoZXJlOlxuXG4gICAgICBodHRwczovL2dpdGh1Yi5jb20vZW1iZXJqcy9yZmNzL2Jsb2IvOWZkNmNlYWMyNTU5YmVlMWMzM2FjZjBkNzgzNGU2NzUxMjVhNGYxNi90ZXh0LzA5MzEtdGVtcGxhdGUtY29tcGlsZXItYXBpLm1kI2V4cGxpY2l0LWZvcm1cbiAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9lbWJlcmpzL3JmY3MvYmxvYi85ZmQ2Y2VhYzI1NTliZWUxYzMzYWNmMGQ3ODM0ZTY3NTEyNWE0ZjE2L3RleHQvMDkzMS10ZW1wbGF0ZS1jb21waWxlci1hcGkubWQjaW1wbGljaXQtZm9ybVxuXG4gICAgVGhpcyBjbGFzcyBuZWVkcyB0byBrbm93IHRoZSBkaWZmZXJlbmNlIGJlY2F1c2UgaW4gaW1wbGljaXQgZm9ybWF0LCB1cHZhcnNcbiAgICBpbiBoYnMgYXJlIGF1dG9tYWdpY2FsbHkgY29ubmVjdGVkIHdpdGggb3V0ZXIgSmF2YXNjcmlwdCBiaW5kaW5ncywgYW5kIGluXG4gICAgZXhwbGljaXQgZm9ybSB0aGV5IGFyZSBub3QuXG4qL1xudHlwZSBQYXJhbXMgPVxuICB8IHtcbiAgICAgIG1vZGU6ICdleHBsaWNpdCc7XG4gICAgfVxuICB8IHtcbiAgICAgIG1vZGU6ICdpbXBsaWNpdCc7XG4gICAgICBqc1BhdGg6IE5vZGVQYXRoO1xuICAgICAgbWF5VXNlTGV4aWNhbFRoaXM6IGJvb2xlYW47XG4gICAgfTtcblxuZXhwb3J0IGNsYXNzIFNjb3BlTG9jYWxzIHtcbiAgY29uc3RydWN0b3IocGFyYW1zOiBQYXJhbXMpIHtcbiAgICB0aGlzLiNwYXJhbXMgPSBwYXJhbXM7XG4gIH1cblxuICAjbWFwcGluZzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAjbG9jYWxzOiBzdHJpbmdbXSA9IFtdO1xuICAjcGFyYW1zOiBQYXJhbXM7XG5cbiAgZ2V0IGxvY2FscygpIHtcbiAgICByZXR1cm4gcmVhZE9ubHlBcnJheShcbiAgICAgIHRoaXMuI2xvY2FscyxcbiAgICAgICdUaGUgb25seSBzdXBwb3J0ZWQgd2F5IHRvIG1hbmlwdWxhdGUgbG9jYWxzIGlzIHZpYSB0aGUganN1dGlscyBBUElcXG5odHRwczovL2dpdGh1Yi5jb20vZW1iZXJqcy9iYWJlbC1wbHVnaW4tZW1iZXItdGVtcGxhdGUtY29tcGlsYXRpb24janN1dGlscy1tYW5pcHVsYXRpbmctamF2YXNjcmlwdC1mcm9tLXdpdGhpbi1hc3QtdHJhbnNmb3JtcydcbiAgICApO1xuICB9XG5cbiAgaGFzKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGtleSBpbiB0aGlzLiNtYXBwaW5nO1xuICB9XG5cbiAgZ2V0KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy4jbWFwcGluZ1trZXldO1xuICB9XG5cbiAgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy4jbG9jYWxzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIGVudHJpZXMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRoaXMuI21hcHBpbmcpO1xuICB9XG5cbiAgYWRkKGhic05hbWU6IHN0cmluZywganNOYW1lPzogc3RyaW5nKSB7XG4gICAgdGhpcy4jbWFwcGluZ1toYnNOYW1lXSA9IGpzTmFtZSA/PyBoYnNOYW1lO1xuICAgIGlmICghdGhpcy4jbG9jYWxzLmluY2x1ZGVzKGhic05hbWUpKSB7XG4gICAgICB0aGlzLiNsb2NhbHMucHVzaChoYnNOYW1lKTtcbiAgICB9XG4gIH1cblxuICAjaXNJbkpzU2NvcGUoaGJzTmFtZTogc3RyaW5nLCBqc1BhdGg6IE5vZGVQYXRoKSB7XG4gICAgbGV0IGpzTmFtZSA9IHRoaXMuI21hcHBpbmdbaGJzTmFtZV0gPz8gaGJzTmFtZTtcbiAgICByZXR1cm4gQUxMT1dFRF9HTE9CQUxTLmhhcyhqc05hbWUpIHx8IGpzUGF0aC5zY29wZS5nZXRCaW5kaW5nKGpzTmFtZSk7XG4gIH1cblxuICAvLyB0aGlzIEFTVCB0cmFuc2Zvcm0gZGlzY292ZXJzIGFsbCBwb3NzaWJsZSB1cHZhcnMgaW4gSEJTIHRoYXQgcmVmZXIgdG8gdmFsaWRcbiAgLy8gYmluZGluZ3MgaW4gSlMsIGFuZCB0aGVuIGRlcGVuZGluZyBvbiB0aGUgbW9kZSBhZGp1c3RzIG91ciBhY3R1YWwgc2NvcGUgYmFnXG4gIC8vIGNvbnRlbnRzLlxuICBjcmF3bCgpIHtcbiAgICByZXR1cm4gKF9lbnY6IEFTVFBsdWdpbkVudmlyb25tZW50KTogeyBuYW1lOiBzdHJpbmc7IHZpc2l0b3I6IE5vZGVWaXNpdG9yIH0gPT4ge1xuICAgICAgbGV0IHNlZW46IFNldDxzdHJpbmc+O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogJ3Njb3BlLWxvY2Fscy1jcmF3bCcsXG4gICAgICAgIHZpc2l0b3I6IHtcbiAgICAgICAgICBUZW1wbGF0ZToge1xuICAgICAgICAgICAgZW50ZXI6ICgpID0+IHtcbiAgICAgICAgICAgICAgc2VlbiA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBleGl0OiAoX25vZGUsIF9wYXRoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLiNwYXJhbXMubW9kZSA9PT0gJ2ltcGxpY2l0Jykge1xuICAgICAgICAgICAgICAgIC8vIGFsbCBoYnMgdXB2YXJzIHRoYXQgaGF2ZSBtYXRjaGluZyBKUyBiaW5kaW5ncyBnbyBpbnRvIHRoZVxuICAgICAgICAgICAgICAgIC8vIHNjb3BlXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgbmFtZSBvZiBzZWVuKSB7XG4gICAgICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gJ3RoaXMnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLiNwYXJhbXMubWF5VXNlTGV4aWNhbFRoaXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZChuYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLiNpc0luSnNTY29wZShuYW1lLCB0aGlzLiNwYXJhbXMuanNQYXRoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZChuYW1lKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gaW4gZXhwbGljaXQgZm9ybSwgd2UgbWlnaHQgcHJ1bmUgYmFjayB0aGUgcHJlZXhpc2luZyBzY29wZSBpblxuICAgICAgICAgICAgICAgIC8vIHRoZSBjYXNlIHdoZXJlIGFub3RoZXIgQVNUIHRyYW5zZm9ybSBoYXMgZWxpbWluYXRlZCB0aGUgdXNlXG4gICAgICAgICAgICAgICAgLy8gb2YgdGhlIG9yaWdpbmFsIGJpbmRpbmcuIEJ1dCB3ZSBkb24ndCBhZGQgYW55dGhpbmcgbmV3LiBUaGVcbiAgICAgICAgICAgICAgICAvLyBvbmx5IHdheSBmb3IgbmV3IGJpbmRpbmdzIHRvIGJlIGludHJvZHVjZWQgaW50byBzY29wZSBpcyBmb3JcbiAgICAgICAgICAgICAgICAvLyBhbm90aGVyIEFTVCB0cmFuc2Zvcm0gdG8gZXhwbGljaXRseSBjYWxsIHRoZSBqc3V0aWxzLCB3aGljaFxuICAgICAgICAgICAgICAgIC8vIGNhbGxzIG91ciBgYWRkYC5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBuYW1lIG9mIE9iamVjdC5rZXlzKHRoaXMuI21hcHBpbmcpKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoIXNlZW4uaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuI2xvY2Fscy5zcGxpY2UodGhpcy4jbG9jYWxzLmluZGV4T2YobmFtZSksIDEpO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy4jbWFwcGluZ1tuYW1lXTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBQYXRoRXhwcmVzc2lvbjogKG5vZGUsIHBhdGgpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAobm9kZS5oZWFkLnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAnVGhpc0hlYWQnOlxuICAgICAgICAgICAgICAgIGlmICghYXN0Tm9kZUhhc0JpbmRpbmcocGF0aCwgJ3RoaXMnKSkge1xuICAgICAgICAgICAgICAgICAgc2Vlbi5hZGQoJ3RoaXMnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ1ZhckhlYWQnOiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IG5vZGUuaGVhZC5uYW1lO1xuICAgICAgICAgICAgICAgIGlmICghYXN0Tm9kZUhhc0JpbmRpbmcocGF0aCwgbmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgIHNlZW4uYWRkKG5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgRWxlbWVudE5vZGU6IChub2RlLCBwYXRoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gbm9kZS50YWcuc3BsaXQoJy4nKVswXTtcbiAgICAgICAgICAgIGlmICghYXN0Tm9kZUhhc0JpbmRpbmcocGF0aCwgbmFtZSkpIHtcbiAgICAgICAgICAgICAgc2Vlbi5hZGQobmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfTtcbiAgfVxufVxuIl19