UNPKG

babel-plugin-ember-template-compilation

Version:
184 lines 30.4 kB
import { ScopeLocals } from './scope-locals.js'; export class ExpressionParser { constructor(babel) { this.babel = babel; } parseExpression(invokedName, path) { switch (path.node.type) { case 'ObjectExpression': return this.parseObjectExpression(invokedName, path); case 'ArrayExpression': { return this.parseArrayExpression(invokedName, path); } case 'StringLiteral': case 'BooleanLiteral': case 'NumericLiteral': return path.node.value; default: throw path.buildCodeFrameError(`${invokedName} can only accept static options but you passed ${JSON.stringify(path.node)}`); } } parseArrayExpression(invokedName, path) { return path.get('elements').map((element) => { if (element.isSpreadElement()) { throw element.buildCodeFrameError(`spread element is not allowed here`); } else if (element.isExpression()) { return this.parseExpression(invokedName, element); } return null; }); } parseScope(invokedName, path) { let body = undefined; if (path.node.type === 'ObjectMethod') { body = path.node.body; } else { let { value } = path.node; if (this.t.isObjectExpression(value)) { throw path.buildCodeFrameError(`Passing an object as the \`scope\` property to inline templates is no longer supported. Please pass a function that returns an object expression instead.`); } if (this.t.isFunctionExpression(value) || this.t.isArrowFunctionExpression(value)) { body = value.body; } } let objExpression = undefined; if (body?.type === 'ObjectExpression') { objExpression = body; } else if (body?.type === 'BlockStatement') { // SAFETY: We know that the body is a ReturnStatement because we're checking inside let returnStatements = body.body.filter((statement) => statement.type === 'ReturnStatement'); if (returnStatements.length !== 1) { throw new Error('Scope functions must have a single return statement which returns an object expression containing references to in-scope values'); } objExpression = returnStatements[0].argument; } if (objExpression?.type !== 'ObjectExpression') { throw path.buildCodeFrameError(`Scope objects for \`${invokedName}\` must be an object expression containing only references to in-scope values, or a function that returns an object expression containing only references to in-scope values`); } return objExpression.properties.reduce((res, prop) => { if (this.t.isSpreadElement(prop)) { throw path.buildCodeFrameError(`Scope objects for \`${invokedName}\` may not contain spread elements`); } if (this.t.isObjectMethod(prop)) { throw path.buildCodeFrameError(`Scope objects for \`${invokedName}\` may not contain methods`); } let { key, value } = prop; if (!this.t.isStringLiteral(key) && !this.t.isIdentifier(key)) { throw path.buildCodeFrameError(`Scope objects for \`${invokedName}\` may only contain static property names`); } let propName = name(key); switch (value.type) { case 'Identifier': res.add(propName, value.name); break; case 'ThisExpression': res.add(propName, 'this'); break; default: throw path.buildCodeFrameError(`Scope objects for \`${invokedName}\` may only contain direct references to in-scope values, e.g. { ${propName} } or { ${propName}: ${propName} }. Found ${value.type}`); } return res; }, new ScopeLocals({ mode: 'explicit' })); } parseEval(invokedName, path) { let body; if (path.isObjectMethod()) { body = path.get('body'); } else if (path.isObjectProperty()) { let value = path.get('value'); if (value.isFunctionExpression()) { body = value.get('body'); } else { throw path.buildCodeFrameError(`unsupported syntax for \`eval\` parameter to \`${invokedName}\`. It must be an object method or a function.`); } } else { throw path.buildCodeFrameError(`unsupported syntax for \`eval\` parameter to \`${invokedName}\`. It must be an object method or a function.`); } let returnStatements = body .get('body') .filter((statement) => statement.isReturnStatement()); if (returnStatements.length !== 1) { throw body.buildCodeFrameError('eval function must have a single return statement'); } let returnExpression = returnStatements[0].get('argument'); if (!returnExpression.isCallExpression()) { throw returnStatements[0].buildCodeFrameError('eval function must return `eval(arguments[0])`. Found non-CallExpression.'); } let callee = returnExpression.get('callee'); if (!callee.isIdentifier() || callee.node.name !== 'eval') { throw returnExpression.buildCodeFrameError('eval function must return `eval(arguments[0])`. Found callee is not eval.'); } let args = returnExpression.get('arguments'); if (args.length !== 1) { throw returnExpression.buildCodeFrameError('eval function must return `eval(arguments[0])`. Found incorrect number of arguments.'); } let arg = args[0]; if (!arg.isMemberExpression()) { throw arg.buildCodeFrameError('eval function must return `eval(arguments[0])`. Found argument is non-MemberExpression.'); } let obj = arg.get('object'); if (!obj.isIdentifier() || obj.node.name !== 'arguments') { throw obj.buildCodeFrameError('eval function must return `eval(arguments[0])`. Found wrong argument to eval.'); } let prop = arg.get('property'); if (!prop.isNumericLiteral() || prop.node.value !== 0) { throw prop.buildCodeFrameError('eval function must return `eval(arguments[0])`. Found wrong property.'); } return { isEval: true }; } parseObjectExpression(invokedName, path, shouldParseScope = false, shouldSupportRFC931 = false) { let result = {}; path.get('properties').forEach((property) => { let { node } = property; if (this.t.isSpreadElement(node)) { throw property.buildCodeFrameError(`${invokedName} does not allow spread element`); } if (node.computed) { throw property.buildCodeFrameError(`${invokedName} can only accept static property names`); } let { key } = node; if (!this.t.isIdentifier(key) && !this.t.isStringLiteral(key)) { throw property.buildCodeFrameError(`${invokedName} can only accept static property names`); } let propertyName = name(key); if (shouldParseScope && propertyName === 'scope') { result.scope = this.parseScope(invokedName, property); } else if (shouldSupportRFC931 && propertyName === 'eval') { result.eval = this.parseEval(invokedName, property); } else if (shouldSupportRFC931 && propertyName === 'component') { result.component = property.get('value'); } else { if (this.t.isObjectMethod(node)) { throw property.buildCodeFrameError(`${invokedName} does not accept a method for ${propertyName}`); } let valuePath = property.get('value'); if (!valuePath.isExpression()) { throw valuePath.buildCodeFrameError(`must be an expression`); } result[propertyName] = this.parseExpression(invokedName, valuePath); } }); return result; } get t() { return this.babel.types; } } function name(node) { if (node.type === 'StringLiteral') { return node.value; } else { return node.name; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvbi1wYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXhwcmVzc2lvbi1wYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWhELE1BQU0sT0FBTyxnQkFBZ0I7SUFDM0IsWUFBb0IsS0FBbUI7UUFBbkIsVUFBSyxHQUFMLEtBQUssQ0FBYztJQUFHLENBQUM7SUFFM0MsZUFBZSxDQUFDLFdBQW1CLEVBQUUsSUFBNEI7UUFDL0QsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3ZCLEtBQUssa0JBQWtCO2dCQUNyQixPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLEVBQUUsSUFBb0MsQ0FBQyxDQUFDO1lBQ3ZGLEtBQUssaUJBQWlCLENBQUMsQ0FBQyxDQUFDO2dCQUN2QixPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsSUFBbUMsQ0FBQyxDQUFDO1lBQ3JGLENBQUM7WUFDRCxLQUFLLGVBQWUsQ0FBQztZQUNyQixLQUFLLGdCQUFnQixDQUFDO1lBQ3RCLEtBQUssZ0JBQWdCO2dCQUNuQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ3pCO2dCQUNFLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUM1QixHQUFHLFdBQVcsa0RBQWtELElBQUksQ0FBQyxTQUFTLENBQzVFLElBQUksQ0FBQyxJQUFJLENBQ1YsRUFBRSxDQUNKLENBQUM7UUFDTixDQUFDO0lBQ0gsQ0FBQztJQUVELG9CQUFvQixDQUFDLFdBQW1CLEVBQUUsSUFBaUM7UUFDekUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzFDLElBQUksT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7Z0JBQzlC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QUUsQ0FBQztnQkFDL0QsTUFBTSxDQUFDLFNBQVMsR0FBSSxRQUFrQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0RSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNoQyxNQUFNLFFBQVEsQ0FBQyxtQkFBbUIsQ0FDaEMsR0FBRyxXQUFXLGlDQUFpQyxZQUFZLEVBQUUsQ0FDOUQsQ0FBQztnQkFDSixDQUFDO2dCQUNELElBQUksU0FBUyxHQUFJLFFBQWtDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNqRSxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUM7b0JBQzlCLE1BQU0sU0FBUyxDQUFDLG1CQUFtQixDQUFDLHVCQUF1QixDQUFDLENBQUM7Z0JBQy9ELENBQUM7Z0JBQ0QsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxJQUFZLENBQUM7UUFDWCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0lBQzFCLENBQUM7Q0FDRjtBQUVELFNBQVMsSUFBSSxDQUFDLElBQW9DO0lBQ2hELElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxlQUFlLEVBQUUsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IE5vZGVQYXRoIH0gZnJvbSAnQGJhYmVsL3RyYXZlcnNlJztcbmltcG9ydCB0eXBlICogYXMgQmFiZWwgZnJvbSAnQGJhYmVsL2NvcmUnO1xuaW1wb3J0IHR5cGUgeyB0eXBlcyBhcyB0IH0gZnJvbSAnQGJhYmVsL2NvcmUnO1xuaW1wb3J0IHsgU2NvcGVMb2NhbHMgfSBmcm9tICcuL3Njb3BlLWxvY2Fscy5qcyc7XG5cbmV4cG9ydCBjbGFzcyBFeHByZXNzaW9uUGFyc2VyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBiYWJlbDogdHlwZW9mIEJhYmVsKSB7fVxuXG4gIHBhcnNlRXhwcmVzc2lvbihpbnZva2VkTmFtZTogc3RyaW5nLCBwYXRoOiBOb2RlUGF0aDx0LkV4cHJlc3Npb24+KTogdW5rbm93biB7XG4gICAgc3dpdGNoIChwYXRoLm5vZGUudHlwZSkge1xuICAgICAgY2FzZSAnT2JqZWN0RXhwcmVzc2lvbic6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlT2JqZWN0RXhwcmVzc2lvbihpbnZva2VkTmFtZSwgcGF0aCBhcyBOb2RlUGF0aDx0Lk9iamVjdEV4cHJlc3Npb24+KTtcbiAgICAgIGNhc2UgJ0FycmF5RXhwcmVzc2lvbic6IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VBcnJheUV4cHJlc3Npb24oaW52b2tlZE5hbWUsIHBhdGggYXMgTm9kZVBhdGg8dC5BcnJheUV4cHJlc3Npb24+KTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ1N0cmluZ0xpdGVyYWwnOlxuICAgICAgY2FzZSAnQm9vbGVhbkxpdGVyYWwnOlxuICAgICAgY2FzZSAnTnVtZXJpY0xpdGVyYWwnOlxuICAgICAgICByZXR1cm4gcGF0aC5ub2RlLnZhbHVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgcGF0aC5idWlsZENvZGVGcmFtZUVycm9yKFxuICAgICAgICAgIGAke2ludm9rZWROYW1lfSBjYW4gb25seSBhY2NlcHQgc3RhdGljIG9wdGlvbnMgYnV0IHlvdSBwYXNzZWQgJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIHBhdGgubm9kZVxuICAgICAgICAgICl9YFxuICAgICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlQXJyYXlFeHByZXNzaW9uKGludm9rZWROYW1lOiBzdHJpbmcsIHBhdGg6IE5vZGVQYXRoPHQuQXJyYXlFeHByZXNzaW9uPikge1xuICAgIHJldHVybiBwYXRoLmdldCgnZWxlbWVudHMnKS5tYXAoKGVsZW1lbnQpID0+IHtcbiAgICAgIGlmIChlbGVtZW50LmlzU3ByZWFkRWxlbWVudCgpKSB7XG4gICAgICAgIHRocm93IGVsZW1lbnQuYnVpbGRDb2RlRnJhbWVFcnJvcihgc3ByZWFkIGVsZW1lbnQgaXMgbm90IGFsbG93ZWQgaGVyZWApO1xuICAgICAgfSBlbHNlIGlmIChlbGVtZW50LmlzRXhwcmVzc2lvbigpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlRXhwcmVzc2lvbihpbnZva2VkTmFtZSwgZWxlbWVudCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9KTtcbiAgfVxuXG4gIHBhcnNlU2NvcGUoaW52b2tlZE5hbWU6IHN0cmluZywgcGF0aDogTm9kZVBhdGg8dC5PYmplY3RQcm9wZXJ0eSB8IHQuT2JqZWN0TWV0aG9kPik6IFNjb3BlTG9jYWxzIHtcbiAgICBsZXQgYm9keTogdC5CbG9ja1N0YXRlbWVudCB8IHQuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAgIGlmIChwYXRoLm5vZGUudHlwZSA9PT0gJ09iamVjdE1ldGhvZCcpIHtcbiAgICAgIGJvZHkgPSBwYXRoLm5vZGUuYm9keTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHsgdmFsdWUgfSA9IHBhdGgubm9kZTtcbiAgICAgIGlmICh0aGlzLnQuaXNPYmplY3RFeHByZXNzaW9uKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBwYXRoLmJ1aWxkQ29kZUZyYW1lRXJyb3IoXG4gICAgICAgICAgYFBhc3NpbmcgYW4gb2JqZWN0IGFzIHRoZSBcXGBzY29wZVxcYCBwcm9wZXJ0eSB0byBpbmxpbmUgdGVtcGxhdGVzIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuIFBsZWFzZSBwYXNzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGFuIG9iamVjdCBleHByZXNzaW9uIGluc3RlYWQuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudC5pc0Z1bmN0aW9uRXhwcmVzc2lvbih2YWx1ZSkgfHwgdGhpcy50LmlzQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24odmFsdWUpKSB7XG4gICAgICAgIGJvZHkgPSB2YWx1ZS5ib2R5O1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBvYmpFeHByZXNzaW9uOiB0LkV4cHJlc3Npb24gfCB1bmRlZmluZWQgfCBudWxsID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGJvZHk/LnR5cGUgPT09ICdPYmplY3RFeHByZXNzaW9uJykge1xuICAgICAgb2JqRXhwcmVzc2lvbiA9IGJvZHk7XG4gICAgfSBlbHNlIGlmIChib2R5Py50eXBlID09PSAnQmxvY2tTdGF0ZW1lbnQnKSB7XG4gICAgICAvLyBTQUZFVFk6IFdlIGtub3cgdGhhdCB0aGUgYm9keSBpcyBhIFJldHVyblN0YXRlbWVudCBiZWNhdXNlIHdlJ3JlIGNoZWNraW5nIGluc2lkZVxuICAgICAgbGV0IHJldHVyblN0YXRlbWVudHMgPSBib2R5LmJvZHkuZmlsdGVyKFxuICAgICAgICAoc3RhdGVtZW50KSA9PiBzdGF0ZW1lbnQudHlwZSA9PT0gJ1JldHVyblN0YXRlbWVudCdcbiAgICAgICkgYXMgQmFiZWwudHlwZXMuUmV0dXJuU3RhdGVtZW50W107XG5cbiAgICAgIGlmIChyZXR1cm5TdGF0ZW1lbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1Njb3BlIGZ1bmN0aW9ucyBtdXN0IGhhdmUgYSBzaW5nbGUgcmV0dXJuIHN0YXRlbWVudCB3aGljaCByZXR1cm5zIGFuIG9iamVjdCBleHByZXNzaW9uIGNvbnRhaW5pbmcgcmVmZXJlbmNlcyB0byBpbi1zY29wZSB2YWx1ZXMnXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIG9iakV4cHJlc3Npb24gPSByZXR1cm5TdGF0ZW1lbnRzWzBdLmFyZ3VtZW50O1xuICAgIH1cblxuICAgIGlmIChvYmpFeHByZXNzaW9uPy50eXBlICE9PSAnT2JqZWN0RXhwcmVzc2lvbicpIHtcbiAgICAgIHRocm93IHBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgYFNjb3BlIG9iamVjdHMgZm9yIFxcYCR7aW52b2tlZE5hbWV9XFxgIG11c3QgYmUgYW4gb2JqZWN0IGV4cHJlc3Npb24gY29udGFpbmluZyBvbmx5IHJlZmVyZW5jZXMgdG8gaW4tc2NvcGUgdmFsdWVzLCBvciBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhbiBvYmplY3QgZXhwcmVzc2lvbiBjb250YWluaW5nIG9ubHkgcmVmZXJlbmNlcyB0byBpbi1zY29wZSB2YWx1ZXNgXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBvYmpFeHByZXNzaW9uLnByb3BlcnRpZXMucmVkdWNlKFxuICAgICAgKHJlcywgcHJvcCkgPT4ge1xuICAgICAgICBpZiAodGhpcy50LmlzU3ByZWFkRWxlbWVudChwcm9wKSkge1xuICAgICAgICAgIHRocm93IHBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgICAgIGBTY29wZSBvYmplY3RzIGZvciBcXGAke2ludm9rZWROYW1lfVxcYCBtYXkgbm90IGNvbnRhaW4gc3ByZWFkIGVsZW1lbnRzYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudC5pc09iamVjdE1ldGhvZChwcm9wKSkge1xuICAgICAgICAgIHRocm93IHBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgICAgIGBTY29wZSBvYmplY3RzIGZvciBcXGAke2ludm9rZWROYW1lfVxcYCBtYXkgbm90IGNvbnRhaW4gbWV0aG9kc2BcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHsga2V5LCB2YWx1ZSB9ID0gcHJvcDtcbiAgICAgICAgaWYgKCF0aGlzLnQuaXNTdHJpbmdMaXRlcmFsKGtleSkgJiYgIXRoaXMudC5pc0lkZW50aWZpZXIoa2V5KSkge1xuICAgICAgICAgIHRocm93IHBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgICAgIGBTY29wZSBvYmplY3RzIGZvciBcXGAke2ludm9rZWROYW1lfVxcYCBtYXkgb25seSBjb250YWluIHN0YXRpYyBwcm9wZXJ0eSBuYW1lc2BcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHByb3BOYW1lID0gbmFtZShrZXkpO1xuXG4gICAgICAgIHN3aXRjaCAodmFsdWUudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ0lkZW50aWZpZXInOlxuICAgICAgICAgICAgcmVzLmFkZChwcm9wTmFtZSwgdmFsdWUubmFtZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdUaGlzRXhwcmVzc2lvbic6XG4gICAgICAgICAgICByZXMuYWRkKHByb3BOYW1lLCAndGhpcycpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IHBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgICAgICAgYFNjb3BlIG9iamVjdHMgZm9yIFxcYCR7aW52b2tlZE5hbWV9XFxgIG1heSBvbmx5IGNvbnRhaW4gZGlyZWN0IHJlZmVyZW5jZXMgdG8gaW4tc2NvcGUgdmFsdWVzLCBlLmcuIHsgJHtwcm9wTmFtZX0gfSBvciB7ICR7cHJvcE5hbWV9OiAke3Byb3BOYW1lfSB9LiBGb3VuZCAke3ZhbHVlLnR5cGV9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgfSxcbiAgICAgIG5ldyBTY29wZUxvY2Fscyh7IG1vZGU6ICdleHBsaWNpdCcgfSlcbiAgICApO1xuICB9XG5cbiAgcGFyc2VFdmFsKFxuICAgIGludm9rZWROYW1lOiBzdHJpbmcsXG4gICAgcGF0aDogTm9kZVBhdGg8dC5PYmplY3RQcm9wZXJ0eSB8IHQuT2JqZWN0TWV0aG9kPlxuICApOiB7IGlzRXZhbDogdHJ1ZSB9IHtcbiAgICBsZXQgYm9keTogTm9kZVBhdGg8dC5CbG9ja1N0YXRlbWVudD47XG5cbiAgICBpZiAocGF0aC5pc09iamVjdE1ldGhvZCgpKSB7XG4gICAgICBib2R5ID0gcGF0aC5nZXQoJ2JvZHknKTtcbiAgICB9IGVsc2UgaWYgKHBhdGguaXNPYmplY3RQcm9wZXJ0eSgpKSB7XG4gICAgICBsZXQgdmFsdWUgPSBwYXRoLmdldCgndmFsdWUnKTtcbiAgICAgIGlmICh2YWx1ZS5pc0Z1bmN0aW9uRXhwcmVzc2lvbigpKSB7XG4gICAgICAgIGJvZHkgPSB2YWx1ZS5nZXQoJ2JvZHknKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IHBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgICBgdW5zdXBwb3J0ZWQgc3ludGF4IGZvciBcXGBldmFsXFxgIHBhcmFtZXRlciB0byBcXGAke2ludm9rZWROYW1lfVxcYC4gSXQgbXVzdCBiZSBhbiBvYmplY3QgbWV0aG9kIG9yIGEgZnVuY3Rpb24uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBwYXRoLmJ1aWxkQ29kZUZyYW1lRXJyb3IoXG4gICAgICAgIGB1bnN1cHBvcnRlZCBzeW50YXggZm9yIFxcYGV2YWxcXGAgcGFyYW1ldGVyIHRvIFxcYCR7aW52b2tlZE5hbWV9XFxgLiBJdCBtdXN0IGJlIGFuIG9iamVjdCBtZXRob2Qgb3IgYSBmdW5jdGlvbi5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCByZXR1cm5TdGF0ZW1lbnRzID0gYm9keVxuICAgICAgLmdldCgnYm9keScpXG4gICAgICAuZmlsdGVyKChzdGF0ZW1lbnQpID0+IHN0YXRlbWVudC5pc1JldHVyblN0YXRlbWVudCgpKSBhcyBOb2RlUGF0aDx0LlJldHVyblN0YXRlbWVudD5bXTtcblxuICAgIGlmIChyZXR1cm5TdGF0ZW1lbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgYm9keS5idWlsZENvZGVGcmFtZUVycm9yKCdldmFsIGZ1bmN0aW9uIG11c3QgaGF2ZSBhIHNpbmdsZSByZXR1cm4gc3RhdGVtZW50Jyk7XG4gICAgfVxuXG4gICAgbGV0IHJldHVybkV4cHJlc3Npb24gPSByZXR1cm5TdGF0ZW1lbnRzWzBdLmdldCgnYXJndW1lbnQnKTtcblxuICAgIGlmICghcmV0dXJuRXhwcmVzc2lvbi5pc0NhbGxFeHByZXNzaW9uKCkpIHtcbiAgICAgIHRocm93IHJldHVyblN0YXRlbWVudHNbMF0uYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgJ2V2YWwgZnVuY3Rpb24gbXVzdCByZXR1cm4gYGV2YWwoYXJndW1lbnRzWzBdKWAuIEZvdW5kIG5vbi1DYWxsRXhwcmVzc2lvbi4nXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBjYWxsZWUgPSByZXR1cm5FeHByZXNzaW9uLmdldCgnY2FsbGVlJyk7XG4gICAgaWYgKCFjYWxsZWUuaXNJZGVudGlmaWVyKCkgfHwgY2FsbGVlLm5vZGUubmFtZSAhPT0gJ2V2YWwnKSB7XG4gICAgICB0aHJvdyByZXR1cm5FeHByZXNzaW9uLmJ1aWxkQ29kZUZyYW1lRXJyb3IoXG4gICAgICAgICdldmFsIGZ1bmN0aW9uIG11c3QgcmV0dXJuIGBldmFsKGFyZ3VtZW50c1swXSlgLiBGb3VuZCBjYWxsZWUgaXMgbm90IGV2YWwuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgYXJncyA9IHJldHVybkV4cHJlc3Npb24uZ2V0KCdhcmd1bWVudHMnKTtcbiAgICBpZiAoYXJncy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IHJldHVybkV4cHJlc3Npb24uYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgJ2V2YWwgZnVuY3Rpb24gbXVzdCByZXR1cm4gYGV2YWwoYXJndW1lbnRzWzBdKWAuIEZvdW5kIGluY29ycmVjdCBudW1iZXIgb2YgYXJndW1lbnRzLidcbiAgICAgICk7XG4gICAgfVxuICAgIGxldCBhcmcgPSBhcmdzWzBdO1xuICAgIGlmICghYXJnLmlzTWVtYmVyRXhwcmVzc2lvbigpKSB7XG4gICAgICB0aHJvdyBhcmcuYnVpbGRDb2RlRnJhbWVFcnJvcihcbiAgICAgICAgJ2V2YWwgZnVuY3Rpb24gbXVzdCByZXR1cm4gYGV2YWwoYXJndW1lbnRzWzBdKWAuIEZvdW5kIGFyZ3VtZW50IGlzIG5vbi1NZW1iZXJFeHByZXNzaW9uLidcbiAgICAgICk7XG4gICAgfVxuICAgIGxldCBvYmogPSBhcmcuZ2V0KCdvYmplY3QnKTtcbiAgICBpZiAoIW9iai5pc0lkZW50aWZpZXIoKSB8fCBvYmoubm9kZS5uYW1lICE9PSAnYXJndW1lbnRzJykge1xuICAgICAgdGhyb3cgb2JqLmJ1aWxkQ29kZUZyYW1lRXJyb3IoXG4gICAgICAgICdldmFsIGZ1bmN0aW9uIG11c3QgcmV0dXJuIGBldmFsKGFyZ3VtZW50c1swXSlgLiBGb3VuZCB3cm9uZyBhcmd1bWVudCB0byBldmFsLidcbiAgICAgICk7XG4gICAgfVxuICAgIGxldCBwcm9wID0gYXJnLmdldCgncHJvcGVydHknKTtcbiAgICBpZiAoIXByb3AuaXNOdW1lcmljTGl0ZXJhbCgpIHx8IHByb3Aubm9kZS52YWx1ZSAhPT0gMCkge1xuICAgICAgdGhyb3cgcHJvcC5idWlsZENvZGVGcmFtZUVycm9yKFxuICAgICAgICAnZXZhbCBmdW5jdGlvbiBtdXN0IHJldHVybiBgZXZhbChhcmd1bWVudHNbMF0pYC4gRm91bmQgd3JvbmcgcHJvcGVydHkuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgaXNFdmFsOiB0cnVlIH07XG4gIH1cblxuICBwYXJzZU9iamVjdEV4cHJlc3Npb24oXG4gICAgaW52b2tlZE5hbWU6IHN0cmluZyxcbiAgICBwYXRoOiBOb2RlUGF0aDx0Lk9iamVjdEV4cHJlc3Npb24+LFxuICAgIHNob3VsZFBhcnNlU2NvcGUgPSBmYWxzZSxcbiAgICBzaG91bGRTdXBwb3J0UkZDOTMxID0gZmFsc2VcbiAgKSB7XG4gICAgbGV0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIHBhdGguZ2V0KCdwcm9wZXJ0aWVzJykuZm9yRWFjaCgocHJvcGVydHkpID0+IHtcbiAgICAgIGxldCB7IG5vZGUgfSA9IHByb3BlcnR5O1xuICAgICAgaWYgKHRoaXMudC5pc1NwcmVhZEVsZW1lbnQobm9kZSkpIHtcbiAgICAgICAgdGhyb3cgcHJvcGVydHkuYnVpbGRDb2RlRnJhbWVFcnJvcihgJHtpbnZva2VkTmFtZX0gZG9lcyBub3QgYWxsb3cgc3ByZWFkIGVsZW1lbnRgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUuY29tcHV0ZWQpIHtcbiAgICAgICAgdGhyb3cgcHJvcGVydHkuYnVpbGRDb2RlRnJhbWVFcnJvcihgJHtpbnZva2VkTmFtZX0gY2FuIG9ubHkgYWNjZXB0IHN0YXRpYyBwcm9wZXJ0eSBuYW1lc2ApO1xuICAgICAgfVxuXG4gICAgICBsZXQgeyBrZXkgfSA9IG5vZGU7XG4gICAgICBpZiAoIXRoaXMudC5pc0lkZW50aWZpZXIoa2V5KSAmJiAhdGhpcy50LmlzU3RyaW5nTGl0ZXJhbChrZXkpKSB7XG4gICAgICAgIHRocm93IHByb3BlcnR5LmJ1aWxkQ29kZUZyYW1lRXJyb3IoYCR7aW52b2tlZE5hbWV9IGNhbiBvbmx5IGFjY2VwdCBzdGF0aWMgcHJvcGVydHkgbmFtZXNgKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHByb3BlcnR5TmFtZSA9IG5hbWUoa2V5KTtcblxuICAgICAgaWYgKHNob3VsZFBhcnNlU2NvcGUgJiYgcHJvcGVydHlOYW1lID09PSAnc2NvcGUnKSB7XG4gICAgICAgIHJlc3VsdC5zY29wZSA9IHRoaXMucGFyc2VTY29wZShpbnZva2VkTmFtZSwgcHJvcGVydHkgYXMgTm9kZVBhdGg8dHlwZW9mIG5vZGU+KTtcbiAgICAgIH0gZWxzZSBpZiAoc2hvdWxkU3VwcG9ydFJGQzkzMSAmJiBwcm9wZXJ0eU5hbWUgPT09ICdldmFsJykge1xuICAgICAgICByZXN1bHQuZXZhbCA9IHRoaXMucGFyc2VFdmFsKGludm9rZWROYW1lLCBwcm9wZXJ0eSBhcyBOb2RlUGF0aDx0eXBlb2Ygbm9kZT4pO1xuICAgICAgfSBlbHNlIGlmIChzaG91bGRTdXBwb3J0UkZDOTMxICYmIHByb3BlcnR5TmFtZSA9PT0gJ2NvbXBvbmVudCcpIHtcbiAgICAgICAgcmVzdWx0LmNvbXBvbmVudCA9IChwcm9wZXJ0eSBhcyBOb2RlUGF0aDx0eXBlb2Ygbm9kZT4pLmdldCgndmFsdWUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnQuaXNPYmplY3RNZXRob2Qobm9kZSkpIHtcbiAgICAgICAgICB0aHJvdyBwcm9wZXJ0eS5idWlsZENvZGVGcmFtZUVycm9yKFxuICAgICAgICAgICAgYCR7aW52b2tlZE5hbWV9IGRvZXMgbm90IGFjY2VwdCBhIG1ldGhvZCBmb3IgJHtwcm9wZXJ0eU5hbWV9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHZhbHVlUGF0aCA9IChwcm9wZXJ0eSBhcyBOb2RlUGF0aDx0eXBlb2Ygbm9kZT4pLmdldCgndmFsdWUnKTtcbiAgICAgICAgaWYgKCF2YWx1ZVBhdGguaXNFeHByZXNzaW9uKCkpIHtcbiAgICAgICAgICB0aHJvdyB2YWx1ZVBhdGguYnVpbGRDb2RlRnJhbWVFcnJvcihgbXVzdCBiZSBhbiBleHByZXNzaW9uYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0W3Byb3BlcnR5TmFtZV0gPSB0aGlzLnBhcnNlRXhwcmVzc2lvbihpbnZva2VkTmFtZSwgdmFsdWVQYXRoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGdldCB0KCkge1xuICAgIHJldHVybiB0aGlzLmJhYmVsLnR5cGVzO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5hbWUobm9kZTogdC5TdHJpbmdMaXRlcmFsIHwgdC5JZGVudGlmaWVyKTogc3RyaW5nIHtcbiAgaWYgKG5vZGUudHlwZSA9PT0gJ1N0cmluZ0xpdGVyYWwnKSB7XG4gICAgcmV0dXJuIG5vZGUudmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5vZGUubmFtZTtcbiAgfVxufVxuIl19