UNPKG

babel-plugin-ember-template-compilation

Version:
466 lines 80 kB
import { ImportUtil } from 'babel-import-util'; import { ExpressionParser } from './expression-parser.js'; import { JSUtils } from './js-utils.js'; import { ScopeLocals } from './scope-locals.js'; import { preprocess, print } from '@glimmer/syntax'; export * from './public-types.js'; const INLINE_PRECOMPILE_MODULES = [ { moduleName: 'ember-cli-htmlbars', export: 'hbs', allowTemplateLiteral: true, }, { moduleName: 'ember-cli-htmlbars-inline-precompile', export: 'default', allowTemplateLiteral: true, }, { moduleName: 'htmlbars-inline-precompile', export: 'default', allowTemplateLiteral: true, }, { moduleName: '@ember/template-compilation', export: 'precompileTemplate', enableScope: true, }, { moduleName: '@ember/template-compiler', export: 'template', enableScope: true, rfc931Support: 'polyfilled', }, ]; function normalizeOpts(options) { if ((options.targetFormat ?? 'wire') === 'wire') { let { compiler } = options; if (!compiler) { throw new Error(`when targetFormat==="wire" you must provide the ember template compiler`); } return { outputModuleOverrides: {}, enableLegacyModules: [], transforms: [], ...options, targetFormat: 'wire', compiler, }; } else { return { outputModuleOverrides: {}, enableLegacyModules: [], transforms: [], ...options, targetFormat: 'hbs', }; } } export function makePlugin(loadOptions) { return async function htmlbarsInlinePrecompile(babel, opts) { let t = babel.types; let normalizedOpts = normalizeOpts(await loadOptions(opts)); const plugin = { visitor: { Program: { enter(path, state) { state.templateFactory = templateFactoryConfig(normalizedOpts); state.util = new ImportUtil(babel, path); state.program = path; state.recursionGuard = new Set(); }, exit(_path, state) { if (normalizedOpts.targetFormat === 'wire') { for (let { moduleName, export: exportName } of configuredModules(normalizedOpts)) { state.util.removeImport(moduleName, exportName); } } }, }, TaggedTemplateExpression(path, state) { let tagPath = path.get('tag'); if (!tagPath.isIdentifier()) { return; } let config = referencesInlineCompiler(tagPath, normalizedOpts); if (!config) { return; } if (!config.allowTemplateLiteral) { throw path.buildCodeFrameError(`Attempted to use \`${tagPath.node.name}\` as a template tag, but it can only be called as a function with a string passed to it: ${tagPath.node.name}('content here')`); } if (path.node.quasi.expressions.length) { throw path.buildCodeFrameError('placeholders inside a tagged template string are not supported'); } let template = path.node.quasi.quasis.map((quasi) => quasi.value.cooked).join(''); if (normalizedOpts.targetFormat === 'wire') { insertCompiledTemplate(babel, state, normalizedOpts, template, path, {}, config, undefined); } else { insertTransformedTemplate(babel, state, normalizedOpts, template, path, {}, config, undefined); } }, CallExpression(path, state) { let calleePath = path.get('callee'); if (!calleePath.isIdentifier()) { return; } let config = referencesInlineCompiler(calleePath, normalizedOpts); if (!config) { return; } if (state.recursionGuard.has(path.node)) { return; } if (path.get('arguments').length > 2) { throw path.buildCodeFrameError(`${calleePath.node.name} can only be invoked with 2 arguments: the template string and any static options`); } let [firstArg, secondArg] = path.get('arguments'); let template; switch (firstArg?.node.type) { case 'StringLiteral': template = firstArg.node.value; break; case 'TemplateLiteral': if (firstArg.node.expressions.length) { throw path.buildCodeFrameError('placeholders inside a template string are not supported'); } else { template = firstArg.node.quasis.map((quasi) => quasi.value.cooked).join(''); } break; case 'TaggedTemplateExpression': throw path.buildCodeFrameError(`tagged template strings inside ${calleePath.node.name} are not supported`); default: throw path.buildCodeFrameError(`${calleePath.node.name} should be invoked with at least a single argument (the template string)`); } let userTypedOptions; let backingClass; if (!secondArg) { userTypedOptions = {}; } else { if (!secondArg.isObjectExpression()) { throw path.buildCodeFrameError(`${calleePath.node.name} can only be invoked with 2 arguments: the template string, and any static options`); } userTypedOptions = new ExpressionParser(babel).parseObjectExpression(calleePath.node.name, secondArg, config.enableScope, Boolean(config.rfc931Support)); if (config.rfc931Support && userTypedOptions.component) { backingClass = userTypedOptions.component; } } if (normalizedOpts.targetFormat === 'wire') { insertCompiledTemplate(babel, state, normalizedOpts, template, path, userTypedOptions, config, backingClass); } else { insertTransformedTemplate(babel, state, normalizedOpts, template, path, userTypedOptions, config, backingClass); } }, }, }; return { pre(file) { // run our processing in pre so that imports for gts // are kept for other plugins. babel.traverse(file.ast, plugin.visitor, file.scope, this); }, visitor: {}, }; }; } function* configuredModules(normalizedOpts) { for (let moduleConfig of INLINE_PRECOMPILE_MODULES) { if (moduleConfig.moduleName !== '@ember/template-compilation' && moduleConfig.moduleName !== '@ember/template-compiler' && !normalizedOpts.enableLegacyModules.includes(moduleConfig.moduleName)) { continue; } yield moduleConfig; } } function referencesInlineCompiler(path, normalizedOpts) { for (let moduleConfig of configuredModules(normalizedOpts)) { if (path.referencesImport(moduleConfig.moduleName, moduleConfig.export)) { return moduleConfig; } } return undefined; } function runtimeErrorIIFE(babel, replacements) { let statement = babel.template(`(function() {\n throw new Error('ERROR_MESSAGE');\n})();`)(replacements); return statement.expression; } function buildScopeLocals(userTypedOptions, formatOptions, target, mayUseLexicalThis) { if (formatOptions.rfc931Support && userTypedOptions.eval) { return new ScopeLocals({ mode: 'implicit', jsPath: target, mayUseLexicalThis }); } else if (userTypedOptions.scope) { return userTypedOptions.scope; } else { return new ScopeLocals({ mode: 'explicit' }); } } function buildPrecompileOptions(babel, target, state, normalizedOpts, template, userTypedOptions, config, scope) { let jsutils = new JSUtils(babel, state, target, scope.add.bind(scope), state.util); let meta = Object.assign({ jsutils }, userTypedOptions?.meta); let output = { contents: template, // we've extended meta to add jsutils, but the types in @glimmer/syntax // don't account for extension meta: meta, // This is here so it's *always* the real filename. filename: state.filename, plugins: { // the cast is needed here only because our meta is extended. That is, // these plugins can access meta.jsutils. ast: [...normalizedOpts.transforms, scope.crawl()], }, }; for (let [key, value] of Object.entries(userTypedOptions)) { if (key !== 'scope') { // `scope` in the user-facing API becomes `locals` in the low-level // ember-template-compiler API output[key] = value; } } output.locals = scope.locals; if (config.rfc931Support) { output.strictMode = true; } return output; } function remapAndBindIdentifiers(target, babel, scopeLocals) { target.traverse({ Identifier(path) { if (scopeLocals.has(path.node.name) && path.node.name !== scopeLocals.get(path.node.name)) { // this identifier has different names in hbs vs js, so we need to // replace the hbs name in the template compiler output with the js // name path.replaceWith(babel.types.identifier(scopeLocals.get(path.node.name))); } // this is where we tell babel's scope system about the new reference we // just introduced. @babel/plugin-transform-typescript in particular // cares a lot about those references being present. path.scope.getBinding(path.node.name)?.reference(path); }, }); } function insertCompiledTemplate(babel, state, opts, template, target, userTypedOptions, config, backingClass) { let t = babel.types; let scopeLocals = buildScopeLocals(userTypedOptions, config, target, !backingClass); let options = buildPrecompileOptions(babel, target, state, opts, template, userTypedOptions, config, scopeLocals); let precompileResultString; // insertRuntimeErrors is legacy and not supported by the newer rfc931 form if (options.insertRuntimeErrors && !config.rfc931Support) { try { precompileResultString = opts.compiler.precompile(template, options); } catch (error) { target.replaceWith(runtimeErrorIIFE(babel, { ERROR_MESSAGE: error.message })); return; } } else { precompileResultString = opts.compiler.precompile(template, options); } let templateExpression = babel.template.expression.ast(precompileResultString); t.addComment(templateExpression, 'leading', `\n ${template.replace(/\*\//g, '*\\/')}\n`, /* line comment? */ false); state.util.replaceWith(target, (i) => { let templateFactoryIdentifier = i.import(state.templateFactory.moduleName, state.templateFactory.exportName); let expression = t.callExpression(templateFactoryIdentifier, [templateExpression]); if (config.rfc931Support) { expression = t.callExpression(i.import('@ember/component', 'setComponentTemplate'), [ expression, backingClass?.node ?? t.callExpression(i.import('@ember/component/template-only', 'default', 'templateOnly'), []), ]); } return expression; }); remapAndBindIdentifiers(target, babel, scopeLocals); } function insertTransformedTemplate(babel, state, normalizedOpts, template, target, userTypedOptions, formatOptions, backingClass) { let t = babel.types; let scopeLocals = buildScopeLocals(userTypedOptions, formatOptions, target, !backingClass); let options = buildPrecompileOptions(babel, target, state, normalizedOpts, template, userTypedOptions, formatOptions, scopeLocals); let ast = preprocess(template, { ...options, mode: 'codemod' }); let transformed = print(ast, { entityEncoding: 'raw' }); if (target.isCallExpression()) { updateCallForm(target, transformed, formatOptions, scopeLocals, state, babel, backingClass); } else { updateBacktickForm(scopeLocals, state, target, t, transformed, babel); } } function updateBacktickForm(scopeLocals, state, target, t, transformed, babel) { if (scopeLocals.isEmpty()) { // simple case: just replace the string literal part with the transformed // template contents target.get('quasi').get('quasis.0').replaceWith(t.templateElement({ raw: transformed })); return; } // need to add scope, so need to replace the backticks form with a call // expression to precompileTemplate maybePruneImport(state.util, target.get('tag')); let newCall = state.util.replaceWith(target, (i) => t.callExpression(precompileTemplate(i), [t.stringLiteral(transformed)])); updateScope(babel, newCall, scopeLocals); } function updateCallForm(target, transformed, formatOptions, scopeLocals, state, babel, backingClass) { // first the simple part: replacing the string literal with the actual body of // the rewritten template target.get('arguments.0').replaceWith(babel.types.stringLiteral(transformed)); if (!formatOptions.enableScope && !scopeLocals.isEmpty()) { // an AST transform added lexically scoped values to a template that // wasn't already in a form that supports them, so convert form. maybePruneImport(state.util, target.get('callee')); state.util.replaceWith(target.get('callee'), (i) => precompileTemplate(i)); } if (formatOptions.rfc931Support === 'polyfilled') { maybePruneImport(state.util, target.get('callee')); state.util.replaceWith(target.get('callee'), (i) => precompileTemplate(i)); convertStrictMode(babel, target); removeEvalAndScope(target); target.node.arguments = target.node.arguments.slice(0, 2); state.recursionGuard.add(target.node); state.util.replaceWith(target, (i) => babel.types.callExpression(i.import('@ember/component', 'setComponentTemplate'), [ target.node, backingClass?.node ?? babel.types.callExpression(i.import('@ember/component/template-only', 'default', 'templateOnly'), []), ])); // we just wrapped the target callExpression in the call to // setComponentTemplate. Adjust `target` back to point at the // precompileTemplate call for the final updateScope below. // target = target.get('arguments.0'); } // We deliberately do updateScope at the end so that when it updates // references, those references will point to the accurate paths in the // final AST. updateScope(babel, target, scopeLocals); } function templateFactoryConfig(opts) { let moduleName = '@ember/template-factory'; let exportName = 'createTemplateFactory'; let overrides = opts.outputModuleOverrides[moduleName]?.[exportName]; return overrides ? { exportName: overrides[0], moduleName: overrides[1] } : { exportName, moduleName }; } function buildScope(babel, locals) { let t = babel.types; return t.arrowFunctionExpression([], t.objectExpression(locals .entries() .map(([name, identifier]) => t.objectProperty(t.identifier(name), t.identifier(identifier), false, name !== 'this')))); } // this is responsible both for adjusting the AST for our scope argument *and* // ensuring that babel's scope system will see that these new identifiers // reference their bindings. @babel/plugin-transform-typescript in particular // cares an awful lot about whether an import has valid non-type references, so // these newly introducd references need to be valid. function updateScope(babel, target, locals) { let t = babel.types; let secondArg = target.get('arguments.1'); if (secondArg) { let scope = secondArg.get('properties').find((p) => { let key = p.get('key'); return key.isIdentifier() && key.node.name === 'scope'; }); if (scope) { if (locals.isEmpty()) { scope.remove(); } else { scope.set('value', buildScope(babel, locals)); // funny-looking naming here, but it actually makes sense because we're // connecting the glimmer scope system with the babel scope system. scope.scope.crawl(); } } else if (!locals.isEmpty()) { secondArg.pushContainer('properties', t.objectProperty(t.identifier('scope'), buildScope(babel, locals))); secondArg.get(`properties.${secondArg.node.properties.length - 1}`).scope.crawl(); } } else if (!locals.isEmpty()) { target.pushContainer('arguments', t.objectExpression([t.objectProperty(t.identifier('scope'), buildScope(babel, locals))])); target.get('arguments.1').scope.crawl(); } } function removeEvalAndScope(target) { let secondArg = target.get('arguments.1'); if (secondArg) { let evalProp = secondArg.get('properties').find((p) => { let key = p.get('key'); return key.isIdentifier() && key.node.name === 'eval'; }); if (evalProp) { evalProp.remove(); } let componentProp = secondArg.get('properties').find((p) => { let key = p.get('key'); return key.isIdentifier() && key.node.name === 'component'; }); if (componentProp) { componentProp.remove(); } } } // Given a call to template(), convert its "strict" argument into // precompileTemplate's "strictMode" argument. They differ in name and default // value. function convertStrictMode(babel, target) { let t = babel.types; let secondArg = target.get('arguments.1'); if (secondArg) { let strict = secondArg.get('properties').find((p) => { let key = p.get('key'); return key.isIdentifier() && key.node.name === 'strict'; }); if (strict) { strict.set('key', t.identifier('strictMode')); } else { secondArg.pushContainer('properties', t.objectProperty(t.identifier('strictMode'), t.booleanLiteral(true))); } } else { target.pushContainer('arguments', t.objectExpression([t.objectProperty(t.identifier('strictMode'), t.booleanLiteral(true))])); } } function maybePruneImport(util, identifier) { if (!identifier.isIdentifier()) { return; } let binding = identifier.scope.getBinding(identifier.node.name); if (!binding) { return; } let found = binding.referencePaths.find((path) => path.node === identifier.node); if (!found) { return; } binding.referencePaths.splice(binding.referencePaths.indexOf(found), 1); binding.references--; if (binding.references === 0) { let specifier = binding.path; if (specifier.isImportSpecifier()) { let declaration = specifier.parentPath; util.removeImport(declaration.node.source.value, name(specifier.node.imported)); } } } function precompileTemplate(i) { return i.import('@ember/template-compilation', 'precompileTemplate'); } function name(node) { if (node.type === 'StringLiteral') { return node.value; } else { return node.name; } } export default makePlugin(async (options) => options); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFpQixNQUFNLG1CQUFtQixDQUFDO0FBQzlELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzFELE9BQU8sRUFBRSxPQUFPLEVBQXlCLE1BQU0sZUFBZSxDQUFDO0FBRy9ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNoRCxPQUFPLEVBQXlCLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUzRSxjQUFjLG1CQUFtQixDQUFDO0FBWWxDLE1BQU0seUJBQXlCLEdBQW1CO0lBQ2hEO1FBQ0UsVUFBVSxFQUFFLG9CQUFvQjtRQUNoQyxNQUFNLEVBQUUsS0FBSztRQUNiLG9CQUFvQixFQUFFLElBQUk7S0FDM0I7SUFDRDtRQUNFLFVBQVUsRUFBRSxzQ0FBc0M7UUFDbEQsTUFBTSxFQUFFLFNBQVM7UUFDakIsb0JBQW9CLEVBQUUsSUFBSTtLQUMzQjtJQUNEO1FBQ0UsVUFBVSxFQUFFLDRCQUE0QjtRQUN4QyxNQUFNLEVBQUUsU0FBUztRQUNqQixvQkFBb0IsRUFBRSxJQUFJO0tBQzNCO0lBQ0Q7UUFDRSxVQUFVLEVBQUUsNkJBQTZCO1FBQ3pDLE1BQU0sRUFBRSxvQkFBb0I7UUFDNUIsV0FBVyxFQUFFLElBQUk7S0FDbEI7SUFDRDtRQUNFLFVBQVUsRUFBRSwwQkFBMEI7UUFDdEMsTUFBTSxFQUFFLFVBQVU7UUFDbEIsV0FBVyxFQUFFLElBQUk7UUFDakIsYUFBYSxFQUFFLFlBQVk7S0FDNUI7Q0FDRixDQUFDO0FBK0RGLFNBQVMsYUFBYSxDQUFDLE9BQWdCO0lBQ3JDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLE1BQU0sQ0FBQyxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQ2hELElBQUksRUFB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Q0FBQztJQUVyQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDN0IsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUM3QixJQUFJLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUM7WUFDbEMsSUFBSSxXQUFXLEdBQUcsU0FBUyxDQUFDLFVBQTJDLENBQUM7WUFDeEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNsRixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLENBQVc7SUFDckMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLDZCQUE2QixFQUFFLG9CQUFvQixDQUFDLENBQUM7QUFDdkUsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFDLElBQW9DO0lBQ2hELElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxlQUFlLEVBQUUsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUM7QUFFRCxlQUFlLFVBQVUsQ0FBVSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTm9kZVBhdGggfSBmcm9tICdAYmFiZWwvdHJhdmVyc2UnO1xuaW1wb3J0IHR5cGUgKiBhcyBCYWJlbCBmcm9tICdAYmFiZWwvY29yZSc7XG5pbXBvcnQgdHlwZSB7IHR5cGVzIGFzIHQgfSBmcm9tICdAYmFiZWwvY29yZSc7XG5pbXBvcnQgeyBJbXBvcnRVdGlsLCB0eXBlIEltcG9ydGVyIH0gZnJvbSAnYmFiZWwtaW1wb3J0LXV0aWwnO1xuaW1wb3J0IHsgRXhwcmVzc2lvblBhcnNlciB9IGZyb20gJy4vZXhwcmVzc2lvbi1wYXJzZXIuanMnO1xuaW1wb3J0IHsgSlNVdGlscywgRXh0ZW5kZWRQbHVnaW5CdWlsZGVyIH0gZnJvbSAnLi9qcy11dGlscy5qcyc7XG5pbXBvcnQgdHlwZSB7IEVtYmVyVGVtcGxhdGVDb21waWxlciwgUHJlcHJvY2Vzc09wdGlvbnMgfSBmcm9tICcuL2VtYmVyLXRlbXBsYXRlLWNvbXBpbGVyLmpzJztcbmltcG9ydCB7IExlZ2FjeU1vZHVsZU5hbWUgfSBmcm9tICcuL3B1YmxpYy10eXBlcy5qcyc7XG5pbXBvcnQgeyBTY29wZUxvY2FscyB9IGZyb20gJy4vc2NvcGUtbG9jYWxzLmpzJztcbmltcG9ydCB7IHR5cGUgQVNUUGx1Z2luQnVpbGRlciwgcHJlcHJvY2VzcywgcHJpbnQgfSBmcm9tICdAZ2xpbW1lci9zeW50YXgnO1xuXG5leHBvcnQgKiBmcm9tICcuL3B1YmxpYy10eXBlcy5qcyc7XG5cbnR5cGUgTW9kdWxlTmFtZSA9IExlZ2FjeU1vZHVsZU5hbWUgfCAnQGVtYmVyL3RlbXBsYXRlLWNvbXBpbGF0aW9uJyB8ICdAZW1iZXIvdGVtcGxhdGUtY29tcGlsZXInO1xuXG5pbnRlcmZhY2UgTW9kdWxlQ29uZmlnIHtcbiAgbW9kdWxlTmFtZTogTW9kdWxlTmFtZTtcbiAgZXhwb3J0OiBzdHJpbmc7XG4gIGFsbG93VGVtcGxhdGVMaXRlcmFsPzogdHJ1ZTtcbiAgZW5hYmxlU2NvcGU/OiB0cnVlO1xuICByZmM5MzFTdXBwb3J0PzogJ3BvbHlmaWxsZWQnO1xufVxuXG5jb25zdCBJTkxJTkVfUFJFQ09NUElMRV9NT0RVTEVTOiBNb2R1bGVDb25maWdbXSA9IFtcbiAge1xuICAgIG1vZHVsZU5hbWU6ICdlbWJlci1jbGktaHRtbGJhcnMnLFxuICAgIGV4cG9ydDogJ2hicycsXG4gICAgYWxsb3dUZW1wbGF0ZUxpdGVyYWw6IHRydWUsXG4gIH0sXG4gIHtcbiAgICBtb2R1bGVOYW1lOiAnZW1iZXItY2xpLWh0bWxiYXJzLWlubGluZS1wcmVjb21waWxlJyxcbiAgICBleHBvcnQ6ICdkZWZhdWx0JyxcbiAgICBhbGxvd1RlbXBsYXRlTGl0ZXJhbDogdHJ1ZSxcbiAgfSxcbiAge1xuICAgIG1vZHVsZU5hbWU6ICdodG1sYmFycy1pbmxpbmUtcHJlY29tcGlsZScsXG4gICAgZXhwb3J0OiAnZGVmYXVsdCcsXG4gICAgYWxsb3dUZW1wbGF0ZUxpdGVyYWw6IHRydWUsXG4gIH0sXG4gIHtcbiAgICBtb2R1bGVOYW1lOiAnQGVtYmVyL3RlbXBsYXRlLWNvbXBpbGF0aW9uJyxcbiAgICBleHBvcnQ6ICdwcmVjb21waWxlVGVtcGxhdGUnLFxuICAgIGVuYWJsZVNjb3BlOiB0cnVlLFxuICB9LFxuICB7XG4gICAgbW9kdWxlTmFtZTogJ0BlbWJlci90ZW1wbGF0ZS1jb21waWxlcicsXG4gICAgZXhwb3J0OiAndGVtcGxhdGUnLFxuICAgIGVuYWJsZVNjb3BlOiB0cnVlLFxuICAgIHJmYzkzMVN1cHBvcnQ6ICdwb2x5ZmlsbGVkJyxcbiAgfSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9ucyB7XG4gIC8vIFRoZSBlbWJlci10ZW1wbGF0ZS1jb21waWxlci5qcyBtb2R1bGUgdGhhdCBzaGlwcyB3aXRoaW4geW91ciBlbWJlci1zb3VyY2VcbiAgLy8gdmVyc2lvbi4gTWFuZGF0b3J5IHdoZW4gdXNpbmcgdGFyZ2V0Rm9ybWF0OiAnd2lyZScuXG4gIGNvbXBpbGVyPzogRW1iZXJUZW1wbGF0ZUNvbXBpbGVyO1xuXG4gIC8vIEFsbG93cyB5b3UgdG8gcmVtYXAgd2hhdCBpbXBvcnRzIHdpbGwgYmUgZW1pdHRlZCBpbiBvdXIgY29tcGlsZWQgb3V0cHV0LiBCeVxuICAvLyBleGFtcGxlOlxuICAvL1xuICAvLyAgIG91dHB1dE1vZHVsZU92ZXJyaWRlczoge1xuICAvLyAgICAgJ0BlbWJlci90ZW1wbGF0ZS1mYWN0b3J5Jzoge1xuICAvLyAgICAgICBjcmVhdGVUZW1wbGF0ZUZhY3Rvcnk6IFsnY3JlYXRlVGVtcGxhdGVGYWN0b3J5JywgJ0BnbGltbWVyL2NvcmUnXSxcbiAgLy8gICAgIH1cbiAgLy8gICB9XG4gIC8vXG4gIC8vIE5vcm1hbCBFbWJlciBhcHBzIHNob3VsZG4ndCBuZWVkIHRoaXMsIGl0IGV4aXN0cyB0byBzdXBwb3J0IG90aGVyXG4gIC8vIGVudmlyb25tZW50cyBsaWtlIHN0YW5kYWxvbmUgR2xpbW1lckpTXG4gIG91dHB1dE1vZHVsZU92ZXJyaWRlcz86IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIFtzdHJpbmcsIHN0cmluZ10+PjtcblxuICAvLyBCeSBkZWZhdWx0LCB0aGlzIHBsdWdpbiBpbXBsZW1lbnRzIG9ubHkgRW1iZXIncyBzdGFibGUgcHVibGljIEFQSSBmb3JcbiAgLy8gdGVtcGxhdGUgY29tcGlsYXRpb24sIHdoaWNoIGlzOlxuICAvL1xuICAvLyAgICBpbXBvcnQgeyBwcmVjb21waWxlVGVtcGxhdGUgfSBmcm9tICdAZW1iZXIvdGVtcGxhdGUtY29tcGlsYXRpb24nO1xuICAvL1xuICAvLyBCdXQgaGlzdG9yaWNhbGx5IHRoZXJlIGFyZSBzZXZlcmFsIG90aGVyIGltcG9ydGFibGUgc3ludGF4ZXMgaW4gd2lkZXNwcmVhZFxuICAvLyB1c2UsIGFuZCB3ZSBjYW4gZW5hYmxlIHRob3NlIHRvbyBieSBpbmNsdWRpbmcgdGhlaXIgbW9kdWxlIG5hbWVzIGluIHRoaXNcbiAgLy8gbGlzdC5cbiAgZW5hYmxlTGVnYWN5TW9kdWxlcz86IExlZ2FjeU1vZHVsZU5hbWVbXTtcblxuICAvLyBDb250cm9scyB0aGUgb3V0cHV0IGZvcm1hdC5cbiAgLy9cbiAgLy8gIFwid2lyZVwiOiBUaGUgZGVmYXVsdC4gSW4gdGhlIG91dHB1dCwgeW91ciB0ZW1wbGF0ZXMgYXJlIHJlYWR5IHRvIGV4ZWN1dGUgaW5cbiAgLy8gIHRoZSBtb3N0IHBlcmZvcm1hbnQgd2F5LlxuICAvL1xuICAvLyAgXCJoYnNcIjogSW4gdGhlIG91dHB1dCwgeW91ciB0ZW1wbGF0ZXMgd2lsbCBzdGlsbCBiZSBpbiBIQlMgZm9ybWF0LlxuICAvLyAgR2VuZXJhbGx5IHRoaXMgbWVhbnMgdGhleSB3aWxsIHN0aWxsIG5lZWQgZnVydGhlciBwcm9jZXNzaW5nIGJlZm9yZVxuICAvLyAgdGhleSdyZSByZWFkeSB0byBleGVjdXRlLiBUaGUgcHVycG9zZSBvZiB0aGlzIG1vZGUgaXMgdG8gc3VwcG9ydCB0aGluZ3NcbiAgLy8gIGxpa2UgY29kZW1vZHMgYW5kIHByZS1wdWJsaWNhdGlvbiB0cmFuc2Zvcm1hdGlvbnMgaW4gbGlicmFyaWVzLlxuICB0YXJnZXRGb3JtYXQ/OiAnd2lyZScgfCAnaGJzJztcblxuICAvLyBPcHRpb25hbCBsaXN0IG9mIGN1c3RvbSB0cmFuc2Zvcm1zIHRvIGFwcGx5IHRvIHRoZSBoYW5kbGViYXJzIEFTVCBiZWZvcmVcbiAgLy8gY29tcGlsYXRpb24uXG4gIHRyYW5zZm9ybXM/OiBFeHRlbmRlZFBsdWdpbkJ1aWxkZXJbXTtcbn1cblxuaW50ZXJmYWNlIFdpcmVPcHRzIHtcbiAgdGFyZ2V0Rm9ybWF0OiAnd2lyZSc7XG4gIGNvbXBpbGVyOiBFbWJlclRlbXBsYXRlQ29tcGlsZXI7XG4gIG91dHB1dE1vZHVsZU92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgW3N0cmluZywgc3RyaW5nXT4+O1xuICBlbmFibGVMZWdhY3lNb2R1bGVzOiBMZWdhY3lNb2R1bGVOYW1lW107XG4gIHRyYW5zZm9ybXM6IEV4dGVuZGVkUGx1Z2luQnVpbGRlcltdO1xufVxuXG5pbnRlcmZhY2UgSGJzT3B0cyB7XG4gIHRhcmdldEZvcm1hdDogJ2hicyc7XG4gIG91dHB1dE1vZHVsZU92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgW3N0cmluZywgc3RyaW5nXT4+O1xuICBlbmFibGVMZWdhY3lNb2R1bGVzOiBMZWdhY3lNb2R1bGVOYW1lW107XG4gIHRyYW5zZm9ybXM6IEV4dGVuZGVkUGx1Z2luQnVpbGRlcltdO1xufVxuXG50eXBlIE5vcm1hbGl6ZWRPcHRzID0gV2lyZU9wdHMgfCBIYnNPcHRzO1xuXG5mdW5jdGlvbiBub3JtYWxpemVPcHRzKG9wdGlvbnM6IE9wdGlvbnMpOiBOb3JtYWxpemVkT3B0cyB7XG4gIGlmICgob3B0aW9ucy50YXJnZXRGb3JtYXQgPz8gJ3dpcmUnKSA9PT0gJ3dpcmUnKSB7XG4gICAgbGV0IHsgY29tcGlsZXIgfSA9IG9wdGlvbnM7XG4gICAgaWYgKCFjb21waWxlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB3aGVuIHRhcmdldEZvcm1hdD09PVwid2lyZVwiIHlvdSBtdXN0IHByb3ZpZGUgdGhlIGVtYmVyIHRlbXBsYXRlIGNvbXBpbGVyYCk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBvdXRwdXRNb2R1bGVPdmVycmlkZXM6IHt9LFxuICAgICAgZW5hYmx