UNPKG

@glimmer/application-test-helpers

Version:

Test helpers for developing @glimmer/component and @glimmer/application

311 lines (267 loc) 32.7 kB
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _defaults(subClass, superClass); } import Resolver, { BasicModuleRegistry } from '@glimmer/resolver'; import defaultResolverConfiguration from './default-resolver-configuration'; import { precompile } from './compiler'; import Application, { BytecodeLoader, DOMBuilder, RuntimeCompilerLoader, SyncRenderer, INTERNAL_DYNAMIC_SCOPE } from '@glimmer/application'; import { assert } from '@glimmer/util'; import { BundleCompiler } from '@glimmer/bundle-compiler'; import { buildAction, mainTemplate } from '@glimmer/application'; import { compilable } from '@glimmer/opcode-compiler'; import { SSRApplication } from '@glimmer/ssr'; import didRender from './did-render'; export var TestApplication = /*#__PURE__*/ function (_Application) { _inheritsLoose(TestApplication, _Application); function TestApplication() { return _Application.apply(this, arguments) || this; } return TestApplication; }(Application); function locatorFor(module, name) { return { kind: 'template', module: module, name: name, meta: { module: module, name: name } }; } export var AppBuilder = /*#__PURE__*/ function () { function AppBuilder(name, options) { this.modules = {}; this.templates = {}; this.rootName = name; this.options = options; this.template('Main', '<div />'); this.helper('action', buildAction, true); } var _proto = AppBuilder.prototype; _proto.template = function template(name, _template) { assert(name.charAt(0) === name.charAt(0).toUpperCase(), 'template names must start with a capital letter'); var specifier = "template:/" + this.rootName + "/components/" + name; this.modules[specifier] = precompile(_template, { meta: { specifier: specifier } }); this.templates[specifier] = _template; return this; }; _proto.component = function component(name, componentFactory) { var specifier = "component:/" + this.rootName + "/components/" + name; this.modules[specifier] = componentFactory; return this; }; _proto.helper = function helper(name, helperFunc, isFactory) { if (isFactory === void 0) { isFactory = false; } var specifier = "helper:/" + this.rootName + "/components/" + name; helperFunc.isFactory = isFactory; this.modules[specifier] = helperFunc; return this; }; _proto.buildResolver = function buildResolver() { var resolverConfiguration = this.options.resolverConfiguration || defaultResolverConfiguration; resolverConfiguration.app = resolverConfiguration.app || { name: this.rootName, rootName: this.rootName }; var registry = new BasicModuleRegistry(this.modules); return new Resolver(resolverConfiguration, registry); }; _proto.buildRuntimeCompilerLoader = function buildRuntimeCompilerLoader() { return new RuntimeCompilerLoader(); }; _proto.buildBytecodeLoader = function buildBytecodeLoader(resolver) { var _this = this; var delegate = new CompilerDelegate(resolver); var compiler = new BundleCompiler(delegate); var mainLocator = locatorFor('template:mainTemplate', 'default'); mainLocator.meta.module = 'template:mainTemplate'; var block = JSON.parse(mainTemplate.block); var compilableTemplate = compilable({ block: block, referrer: mainLocator.meta }); compiler.addCompilableTemplate(mainLocator, compilableTemplate); for (var module in this.templates) { compiler.addTemplateSource(locatorFor(module, 'default'), this.templates[module]); } var _compiler$compile = compiler.compile(), heap = _compiler$compile.heap, pool = _compiler$compile.pool, table = _compiler$compile.table; var resolverTable = []; var meta = {}; table.vmHandleByModuleLocator.forEach(function (vmHandle, locator) { var handle = table.byModuleLocator.get(locator); var template = compiler.getTemplate(locator); meta[locator.module] = { v: vmHandle, h: handle, sT: template.symbolTable }; }); table.byHandle.forEach(function (locator, handle) { var module = locator.module.replace('template:/', 'component:/'); if (_this.modules[module]) { if (module.indexOf('helper:') === 0) { var moduleType = _this.modules[module].isFactory ? 0 /* HELPER_FACTORY */ : 1 /* HELPER */ ; resolverTable[handle] = [moduleType, _this.modules[module]]; } else { resolverTable[handle] = _this.modules[module]; } } }); var bytecode = heap.buffer; var data = { prefix: '', mainEntry: table.vmHandleByModuleLocator.get(mainLocator), pool: pool, table: resolverTable, meta: meta, heap: { table: heap.table, handle: heap.handle } }; return new BytecodeLoader({ bytecode: bytecode, data: data }); }; _proto.buildLoader = function buildLoader(resolver) { switch (this.options.loader) { case 'runtime-compiler': return this.buildRuntimeCompilerLoader(); case 'bytecode': return this.buildBytecodeLoader(resolver); default: throw new Error("Unrecognized loader " + this.options.loader); } }; _proto.renderToString = function renderToString(componentName, data, options) { var resolver = this.buildResolver(); var loader = this.buildLoader(resolver); return SSRApplication.renderToString(componentName, data, Object.assign({ rootName: this.rootName, resolver: resolver, loader: loader, renderer: new SyncRenderer() }, options)); }; _proto.boot = /*#__PURE__*/ function () { var _boot = _asyncToGenerator(function* () { var resolver = this.buildResolver(); var loader = this.buildLoader(resolver); var doc = this.options.document || document; var element = doc.body; var builder = new DOMBuilder({ element: element }); var renderer = new SyncRenderer(); var app = new this.options.ApplicationClass({ resolver: resolver, builder: builder, loader: loader, renderer: renderer, rootName: this.rootName, document: this.options.document }); var rootElement = doc.createElement('div'); app.rootElement = rootElement; app.renderComponent('Main', rootElement); app.boot(); yield didRender(app); return app; }); function boot() { return _boot.apply(this, arguments); } return boot; }(); return AppBuilder; }(); var CAPABILITIES = { createInstance: true, dynamicLayout: false, dynamicTag: false, wrapped: false, prepareArgs: false, createArgs: true, attributeHook: false, elementHook: false, updateHook: true, createCaller: false, dynamicScope: true }; var CompilerDelegate = /*#__PURE__*/ function () { function CompilerDelegate(resolver) { this.resolver = resolver; } var _proto2 = CompilerDelegate.prototype; _proto2.hasComponentInScope = function hasComponentInScope(name, referrer) { return !!this.resolver.identify("template:" + name, referrer.module); }; _proto2.resolveComponent = function resolveComponent(name, referrer) { var resolved = this.resolver.identify("template:" + name, referrer.module); return { module: resolved, name: 'default' }; }; _proto2.getComponentCapabilities = function getComponentCapabilities() { return CAPABILITIES; }; _proto2.hasHelperInScope = function hasHelperInScope(helperName, referrer) { return !!this.resolver.identify("helper:" + helperName, referrer.module); }; _proto2.resolveHelper = function resolveHelper(helperName, referrer) { var resolved = this.resolver.identify("helper:" + helperName, referrer.module); return { module: resolved, name: 'default' }; }; _proto2.hasPartialInScope = function hasPartialInScope(partialName, referrer) { throw new Error('Method not implemented.'); }; _proto2.resolvePartial = function resolvePartial(partialName, referrer) { throw new Error('Method not implemented.'); }; _proto2.hasModifierInScope = function hasModifierInScope(modifierName, referrer) { throw new Error('Method not implemented.'); }; _proto2.resolveModifier = function resolveModifier(modifierName, referrer) { throw new Error('Method not implemented.'); }; return CompilerDelegate; }(); function buildApp(options) { if (options === void 0) { options = {}; } options.appName = options.appName || 'test-app'; options.loader = options.loader || 'runtime-compiler'; options.ApplicationClass = options.ApplicationClass || TestApplication; return new AppBuilder(options.appName, options); } export { buildApp }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL2FwcGxpY2F0aW9uLXRlc3QtaGVscGVycy9zcmMvYXBwLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQSxPQUFPLFFBQVAsSUFBbUIsbUJBQW5CLFFBQXFFLG1CQUFyRTtBQUVBLE9BQU8sNEJBQVAsTUFBeUMsa0NBQXpDO0FBQ0EsU0FBUyxVQUFULFFBQTJCLFlBQTNCO0FBQ0EsT0FBTyxXQUFQLElBRUUsY0FGRixFQUdFLFVBSEYsRUFLRSxxQkFMRixFQU1FLFlBTkYsRUFRRSxzQkFSRixRQVNPLHNCQVRQO0FBVUEsU0FBUyxNQUFULFFBQXVCLGVBQXZCO0FBQ0EsU0FBUyxjQUFULFFBQXNFLDBCQUF0RTtBQUNBLFNBQVMsV0FBVCxFQUFzQixZQUF0QixRQUFzRSxzQkFBdEU7QUFDQSxTQUFTLFVBQVQsUUFBMkIsMEJBQTNCO0FBR0EsU0FBUyxjQUFULFFBQStCLGNBQS9CO0FBRUEsT0FBTyxTQUFQLE1BQXNCLGNBQXRCO0FBYUEsV0FBYSxlQUFiO0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQUFBLEVBQXFDLFdBQXJDOztBQXFCQSxTQUFTLFVBQVQsQ0FBb0IsTUFBcEIsRUFBb0MsSUFBcEMsRUFBZ0Q7QUFDOUMsU0FBTztBQUNMLElBQUEsSUFBSSxFQUFFLFVBREQ7QUFFTCxJQUFBLE1BQU0sRUFBTixNQUZLO0FBR0wsSUFBQSxJQUFJLEVBQUosSUFISztBQUlMLElBQUEsSUFBSSxFQUFFO0FBQ0osTUFBQSxNQUFNLEVBQU4sTUFESTtBQUVKLE1BQUEsSUFBSSxFQUFKO0FBRkk7QUFKRCxHQUFQO0FBU0Q7O0FBRUQsV0FBYSxVQUFiO0FBQUE7QUFBQTtBQU1FLHNCQUFZLElBQVosRUFBMEIsT0FBMUIsRUFBdUQ7QUFKdkQsU0FBQSxPQUFBLEdBQXlCLEVBQXpCO0FBQ0EsU0FBQSxTQUFBLEdBQTBCLEVBQTFCO0FBSUUsU0FBSyxRQUFM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SUFBSSxLQUFKLENBQVUseUJBQVYsQ0FBTjtBQUNELEc7Ozs7O0FBR0gsU0FBUyxRQUFULENBQTZDLE9BQTdDLEVBQStFO0FBQUEsTUFBbEMsT0FBa0M7QUFBbEMsSUFBQSxPQUFrQyxHQUFGLEVBQUU7QUFBQTs7QUFDN0UsRUFBQSxPQUFPLENBQUMsT0FBUixHQUFrQixPQUFPLENBQUMsT0FBUixJQUFtQixVQUFyQztBQUNBLEVBQUEsT0FBTyxDQUFDLE1BQVIsR0FBaUIsT0FBTyxDQUFDLE1BQVIsSUFBa0Isa0JBQW5DO0FBQ0EsRUFBQSxPQUFPLENBQUMsZ0JBQVIsR0FDRSxPQUFPLENBQUMsZ0JBQVIsSUFBNkIsZUFEL0I7QUFHQSxTQUFPLElBQUksVUFBSixDQUFlLE9BQU8sQ0FBQyxPQUF2QixFQUFnQyxPQUFoQyxDQUFQO0FBQ0Q7O0FBRUQsU0FBUyxRQUFUIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlc29sdmVyLCB7IEJhc2ljTW9kdWxlUmVnaXN0cnksIFJlc29sdmVyQ29uZmlndXJhdGlvbiB9IGZyb20gJ0BnbGltbWVyL3Jlc29sdmVyJztcbmltcG9ydCB7IERpY3QsIE1vZHVsZUxvY2F0b3IsIFRlbXBsYXRlTG9jYXRvciwgQ29tcG9uZW50Q2FwYWJpbGl0aWVzIH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgZGVmYXVsdFJlc29sdmVyQ29uZmlndXJhdGlvbiBmcm9tICcuL2RlZmF1bHQtcmVzb2x2ZXItY29uZmlndXJhdGlvbic7XG5pbXBvcnQgeyBwcmVjb21waWxlIH0gZnJvbSAnLi9jb21waWxlcic7XG5pbXBvcnQgQXBwbGljYXRpb24sIHtcbiAgQXBwbGljYXRpb25Db25zdHJ1Y3RvcixcbiAgQnl0ZWNvZGVMb2FkZXIsXG4gIERPTUJ1aWxkZXIsXG4gIExvYWRlcixcbiAgUnVudGltZUNvbXBpbGVyTG9hZGVyLFxuICBTeW5jUmVuZGVyZXIsXG4gIE1vZHVsZVR5cGVzLFxuICBJTlRFUk5BTF9EWU5BTUlDX1NDT1BFXG59IGZyb20gJ0BnbGltbWVyL2FwcGxpY2F0aW9uJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgQnVuZGxlQ29tcGlsZXIsIENvbXBpbGVyRGVsZWdhdGUgYXMgSUNvbXBpbGVyRGVsZWdhdGUgfSBmcm9tICdAZ2xpbW1lci9idW5kbGUtY29tcGlsZXInO1xuaW1wb3J0IHsgYnVpbGRBY3Rpb24sIG1haW5UZW1wbGF0ZSwgUmVuZGVyZXIsIEJ5dGVjb2RlTWV0YWRhdGEgfSBmcm9tICdAZ2xpbW1lci9hcHBsaWNhdGlvbic7XG5pbXBvcnQgeyBjb21waWxhYmxlIH0gZnJvbSAnQGdsaW1tZXIvb3Bjb2RlLWNvbXBpbGVyJztcbmltcG9ydCB7IFNpbXBsZURvY3VtZW50IH0gZnJvbSAnQHNpbXBsZS1kb20vaW50ZXJmYWNlJztcbmltcG9ydCBIVE1MU2VyaWFsaXplciBmcm9tICdAc2ltcGxlLWRvbS9zZXJpYWxpemVyJztcbmltcG9ydCB7IFNTUkFwcGxpY2F0aW9uIH0gZnJvbSAnQGdsaW1tZXIvc3NyJztcblxuaW1wb3J0IGRpZFJlbmRlciBmcm9tICcuL2RpZC1yZW5kZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFwcEJ1aWxkZXJPcHRpb25zPFQ+IHtcbiAgYXBwTmFtZT86IHN0cmluZztcbiAgbG9hZGVyPzogc3RyaW5nO1xuICBBcHBsaWNhdGlvbkNsYXNzPzogQXBwbGljYXRpb25Db25zdHJ1Y3RvcjxUPjtcbiAgQ29tcG9uZW50TWFuYWdlcj86IGFueTsgLy8gVE9ETyAtIHR5cGluZ1xuICByZXNvbHZlckNvbmZpZ3VyYXRpb24/OiBSZXNvbHZlckNvbmZpZ3VyYXRpb247XG4gIGRvY3VtZW50PzogU2ltcGxlRG9jdW1lbnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50RmFjdG9yeSB7fVxuXG5leHBvcnQgY2xhc3MgVGVzdEFwcGxpY2F0aW9uIGV4dGVuZHMgQXBwbGljYXRpb24ge1xuICByb290RWxlbWVudDogRWxlbWVudDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBcHBCdWlsZGVyVGVtcGxhdGVNZXRhIHtcbiAgc3BlY2lmaWVyOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBIZWxwZXJGdW5jdGlvbiBleHRlbmRzIEZ1bmN0aW9uIHtcbiAgaXNGYWN0b3J5PzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIFRlc3RTU1JBcHBsaWNhdGlvbk9wdGlvbnMge1xuICByb290TmFtZT86IHN0cmluZztcbiAgcmVzb2x2ZXI/OiBSZXNvbHZlcjtcbiAgbG9hZGVyPzogTG9hZGVyO1xuICByZW5kZXJlcj86IFJlbmRlcmVyO1xuICBzZXJpYWxpemVyPzogSFRNTFNlcmlhbGl6ZXI7XG4gIFtJTlRFUk5BTF9EWU5BTUlDX1NDT1BFXT86IERpY3Q8dW5rbm93bj47XG59XG5cbmZ1bmN0aW9uIGxvY2F0b3JGb3IobW9kdWxlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFRlbXBsYXRlTG9jYXRvcjxNb2R1bGVMb2NhdG9yPiB7XG4gIHJldHVybiB7XG4gICAga2luZDogJ3RlbXBsYXRlJyxcbiAgICBtb2R1bGUsXG4gICAgbmFtZSxcbiAgICBtZXRhOiB7XG4gICAgICBtb2R1bGUsXG4gICAgICBuYW1lLFxuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBjbGFzcyBBcHBCdWlsZGVyPFQgZXh0ZW5kcyBUZXN0QXBwbGljYXRpb24+IHtcbiAgcm9vdE5hbWU6IHN0cmluZztcbiAgbW9kdWxlczogRGljdDx1bmtub3duPiA9IHt9O1xuICB0ZW1wbGF0ZXM6IERpY3Q8c3RyaW5nPiA9IHt9O1xuICBvcHRpb25zOiBBcHBCdWlsZGVyT3B0aW9uczxUPjtcblxuICBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIG9wdGlvbnM6IEFwcEJ1aWxkZXJPcHRpb25zPFQ+KSB7XG4gICAgdGhpcy5yb290TmFtZSA9IG5hbWU7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnRlbXBsYXRlKCdNYWluJywgJzxkaXYgLz4nKTtcbiAgICB0aGlzLmhlbHBlcignYWN0aW9uJywgYnVpbGRBY3Rpb24sIHRydWUpO1xuICB9XG5cbiAgdGVtcGxhdGUobmFtZTogc3RyaW5nLCB0ZW1wbGF0ZTogc3RyaW5nKSB7XG4gICAgYXNzZXJ0KFxuICAgICAgbmFtZS5jaGFyQXQoMCkgPT09IG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCksXG4gICAgICAndGVtcGxhdGUgbmFtZXMgbXVzdCBzdGFydCB3aXRoIGEgY2FwaXRhbCBsZXR0ZXInXG4gICAgKTtcblxuICAgIGxldCBzcGVjaWZpZXIgPSBgdGVtcGxhdGU6LyR7dGhpcy5yb290TmFtZX0vY29tcG9uZW50cy8ke25hbWV9YDtcbiAgICB0aGlzLm1vZHVsZXNbc3BlY2lmaWVyXSA9IHByZWNvbXBpbGUodGVtcGxhdGUsIHsgbWV0YTogeyBzcGVjaWZpZXIgfSB9KTtcbiAgICB0aGlzLnRlbXBsYXRlc1tzcGVjaWZpZXJdID0gdGVtcGxhdGU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBjb21wb25lbnQobmFtZTogc3RyaW5nLCBjb21wb25lbnRGYWN0b3J5OiBDb21wb25lbnRGYWN0b3J5KSB7XG4gICAgbGV0IHNwZWNpZmllciA9IGBjb21wb25lbnQ6LyR7dGhpcy5yb290TmFtZX0vY29tcG9uZW50cy8ke25hbWV9YDtcbiAgICB0aGlzLm1vZHVsZXNbc3BlY2lmaWVyXSA9IGNvbXBvbmVudEZhY3Rvcnk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBoZWxwZXIobmFtZTogc3RyaW5nLCBoZWxwZXJGdW5jOiBIZWxwZXJGdW5jdGlvbiwgaXNGYWN0b3J5ID0gZmFsc2UpIHtcbiAgICBsZXQgc3BlY2lmaWVyID0gYGhlbHBlcjovJHt0aGlzLnJvb3ROYW1lfS9jb21wb25lbnRzLyR7bmFtZX1gO1xuICAgIGhlbHBlckZ1bmMuaXNGYWN0b3J5ID0gaXNGYWN0b3J5O1xuICAgIHRoaXMubW9kdWxlc1tzcGVjaWZpZXJdID0gaGVscGVyRnVuYztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZFJlc29sdmVyKCk6IFJlc29sdmVyIHtcbiAgICBsZXQgcmVzb2x2ZXJDb25maWd1cmF0aW9uID0gdGhpcy5vcHRpb25zLnJlc29sdmVyQ29uZmlndXJhdGlvbiB8fCBkZWZhdWx0UmVzb2x2ZXJDb25maWd1cmF0aW9uO1xuICAgIHJlc29sdmVyQ29uZmlndXJhdGlvbi5hcHAgPSByZXNvbHZlckNvbmZpZ3VyYXRpb24uYXBwIHx8IHtcbiAgICAgIG5hbWU6IHRoaXMucm9vdE5hbWUsXG4gICAgICByb290TmFtZTogdGhpcy5yb290TmFtZSxcbiAgICB9O1xuXG4gICAgbGV0IHJlZ2lzdHJ5ID0gbmV3IEJhc2ljTW9kdWxlUmVnaXN0cnkodGhpcy5tb2R1bGVzKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVyKHJlc29sdmVyQ29uZmlndXJhdGlvbiwgcmVnaXN0cnkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGJ1aWxkUnVudGltZUNvbXBpbGVyTG9hZGVyKCk6IExvYWRlciB7XG4gICAgcmV0dXJuIG5ldyBSdW50aW1lQ29tcGlsZXJMb2FkZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZEJ5dGVjb2RlTG9hZGVyKHJlc29sdmVyOiBSZXNvbHZlcikge1xuICAgIGxldCBkZWxlZ2F0ZSA9IG5ldyBDb21waWxlckRlbGVnYXRlKHJlc29sdmVyKTtcbiAgICBsZXQgY29tcGlsZXIgPSBuZXcgQnVuZGxlQ29tcGlsZXIoZGVsZWdhdGUpO1xuXG4gICAgbGV0IG1haW5Mb2NhdG9yID0gbG9jYXRvckZvcigndGVtcGxhdGU6bWFpblRlbXBsYXRlJywgJ2RlZmF1bHQnKTtcbiAgICBtYWluTG9jYXRvci5tZXRhLm1vZHVsZSA9ICd0ZW1wbGF0ZTptYWluVGVtcGxhdGUnO1xuXG4gICAgbGV0IGJsb2NrID0gSlNPTi5wYXJzZShtYWluVGVtcGxhdGUuYmxvY2spO1xuICAgIGxldCBjb21waWxhYmxlVGVtcGxhdGUgPSBjb21waWxhYmxlKHtcbiAgICAgIGJsb2NrLFxuICAgICAgcmVmZXJyZXI6IG1haW5Mb2NhdG9yLm1ldGEsXG4gICAgfSk7XG5cbiAgICBjb21waWxlci5hZGRDb21waWxhYmxlVGVtcGxhdGUobWFpbkxvY2F0b3IsIGNvbXBpbGFibGVUZW1wbGF0ZSk7XG5cbiAgICBmb3IgKGxldCBtb2R1bGUgaW4gdGhpcy50ZW1wbGF0ZXMpIHtcbiAgICAgIGNvbXBpbGVyLmFkZFRlbXBsYXRlU291cmNlKGxvY2F0b3JGb3IobW9kdWxlLCAnZGVmYXVsdCcpLCB0aGlzLnRlbXBsYXRlc1ttb2R1bGVdKTtcbiAgICB9XG5cbiAgICBsZXQgeyBoZWFwLCBwb29sLCB0YWJsZSB9ID0gY29tcGlsZXIuY29tcGlsZSgpO1xuXG4gICAgbGV0IHJlc29sdmVyVGFibGU6IHVua25vd25bXSA9IFtdO1xuXG4gICAgbGV0IG1ldGE6IERpY3Q8Qnl0ZWNvZGVNZXRhZGF0YT4gPSB7fTtcblxuICAgIHRhYmxlLnZtSGFuZGxlQnlNb2R1bGVMb2NhdG9yLmZvckVhY2goKHZtSGFuZGxlLCBsb2NhdG9yKSA9PiB7XG4gICAgICBsZXQgaGFuZGxlID0gdGFibGUuYnlNb2R1bGVMb2NhdG9yLmdldChsb2NhdG9yKTtcbiAgICAgIGxldCB0ZW1wbGF0ZSA9IGNvbXBpbGVyLmdldFRlbXBsYXRlKGxvY2F0b3IpO1xuXG4gICAgICBtZXRhW2xvY2F0b3IubW9kdWxlXSA9IHtcbiAgICAgICAgdjogdm1IYW5kbGUsXG4gICAgICAgIGg6IGhhbmRsZSxcbiAgICAgICAgc1Q6IHRlbXBsYXRlLnN5bWJvbFRhYmxlLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHRhYmxlLmJ5SGFuZGxlLmZvckVhY2goKGxvY2F0b3IsIGhhbmRsZSkgPT4ge1xuICAgICAgbGV0IG1vZHVsZSA9IGxvY2F0b3IubW9kdWxlLnJlcGxhY2UoJ3RlbXBsYXRlOi8nLCAnY29tcG9uZW50Oi8nKTtcbiAgICAgIGlmICh0aGlzLm1vZHVsZXNbbW9kdWxlXSkge1xuICAgICAgICBpZiAobW9kdWxlLmluZGV4T2YoJ2hlbHBlcjonKSA9PT0gMCkge1xuICAgICAgICAgIGNvbnN0IG1vZHVsZVR5cGUgPSAodGhpcy5tb2R1bGVzW21vZHVsZV0gYXMgSGVscGVyRnVuY3Rpb24pLmlzRmFjdG9yeSA/IE1vZHVsZVR5cGVzLkhFTFBFUl9GQUNUT1JZIDogTW9kdWxlVHlwZXMuSEVMUEVSO1xuICAgICAgICAgIHJlc29sdmVyVGFibGVbaGFuZGxlXSA9IFttb2R1bGVUeXBlLCB0aGlzLm1vZHVsZXNbbW9kdWxlXV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZXJUYWJsZVtoYW5kbGVdID0gdGhpcy5tb2R1bGVzW21vZHVsZV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCBieXRlY29kZSA9IGhlYXAuYnVmZmVyO1xuICAgIGxldCBkYXRhID0ge1xuICAgICAgcHJlZml4OiAnJyxcbiAgICAgIG1haW5FbnRyeTogdGFibGUudm1IYW5kbGVCeU1vZHVsZUxvY2F0b3IuZ2V0KG1haW5Mb2NhdG9yKSxcbiAgICAgIHBvb2wsXG4gICAgICB0YWJsZTogcmVzb2x2ZXJUYWJsZSxcbiAgICAgIG1ldGEsXG4gICAgICBoZWFwOiB7XG4gICAgICAgIHRhYmxlOiBoZWFwLnRhYmxlLFxuICAgICAgICBoYW5kbGU6IGhlYXAuaGFuZGxlLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIG5ldyBCeXRlY29kZUxvYWRlcih7IGJ5dGVjb2RlLCBkYXRhIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGJ1aWxkTG9hZGVyKHJlc29sdmVyKTogTG9hZGVyIHtcbiAgICBzd2l0Y2ggKHRoaXMub3B0aW9ucy5sb2FkZXIpIHtcbiAgICAgIGNhc2UgJ3J1bnRpbWUtY29tcGlsZXInOlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZFJ1bnRpbWVDb21waWxlckxvYWRlcigpO1xuICAgICAgY2FzZSAnYnl0ZWNvZGUnOlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEJ5dGVjb2RlTG9hZGVyKHJlc29sdmVyKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pemVkIGxvYWRlciAke3RoaXMub3B0aW9ucy5sb2FkZXJ9YCk7XG4gICAgfVxuICB9XG5cbiAgcmVuZGVyVG9TdHJpbmcoY29tcG9uZW50TmFtZTogc3RyaW5nLCBkYXRhOiBEaWN0PHVua25vd24+LCBvcHRpb25zPzogVGVzdFNTUkFwcGxpY2F0aW9uT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgcmVzb2x2ZXIgPSB0aGlzLmJ1aWxkUmVzb2x2ZXIoKTtcbiAgICBsZXQgbG9hZGVyID0gdGhpcy5idWlsZExvYWRlcihyZXNvbHZlcik7XG5cbiAgICByZXR1cm4gU1NSQXBwbGljYXRpb24ucmVuZGVyVG9TdHJpbmcoY29tcG9uZW50TmFtZSwgZGF0YSwge1xuICAgICAgcm9vdE5hbWU6IHRoaXMucm9vdE5hbWUsXG4gICAgICByZXNvbHZlcixcbiAgICAgIGxvYWRlcixcbiAgICAgIHJlbmRlcmVyOiBuZXcgU3luY1JlbmRlcmVyKCksXG4gICAgICAuLi5vcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBib290KCk6IFByb21pc2U8VD4ge1xuICAgIGxldCByZXNvbHZlciA9IHRoaXMuYnVpbGRSZXNvbHZlcigpO1xuICAgIGxldCBsb2FkZXI6IExvYWRlciA9IHRoaXMuYnVpbGRMb2FkZXIocmVzb2x2ZXIpO1xuXG4gICAgbGV0IGRvYzogRG9jdW1lbnQgPSAodGhpcy5vcHRpb25zLmRvY3VtZW50IGFzIERvY3VtZW50KSB8fCBkb2N1bWVudDtcbiAgICBsZXQgZWxlbWVudCA9IGRvYy5ib2R5O1xuICAgIGxldCBidWlsZGVyID0gbmV3IERPTUJ1aWxkZXIoeyBlbGVtZW50IH0pO1xuICAgIGxldCByZW5kZXJlciA9IG5ldyBTeW5jUmVuZGVyZXIoKTtcblxuICAgIGxldCBhcHAgPSBuZXcgdGhpcy5vcHRpb25zLkFwcGxpY2F0aW9uQ2xhc3Moe1xuICAgICAgcmVzb2x2ZXIsXG4gICAgICBidWlsZGVyLFxuICAgICAgbG9hZGVyLFxuICAgICAgcmVuZGVyZXIsXG4gICAgICByb290TmFtZTogdGhpcy5yb290TmFtZSxcbiAgICAgIGRvY3VtZW50OiB0aGlzLm9wdGlvbnMuZG9jdW1lbnQsXG4gICAgfSk7XG5cbiAgICBsZXQgcm9vdEVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgYXBwLnJvb3RFbGVtZW50ID0gcm9vdEVsZW1lbnQ7XG4gICAgYXBwLnJlbmRlckNvbXBvbmVudCgnTWFpbicsIHJvb3RFbGVtZW50KTtcbiAgICBhcHAuYm9vdCgpO1xuXG4gICAgYXdhaXQgZGlkUmVuZGVyKGFwcCk7XG5cbiAgICByZXR1cm4gYXBwO1xuICB9XG59XG5cbmNvbnN0IENBUEFCSUxJVElFUzogQ29tcG9uZW50Q2FwYWJpbGl0aWVzID0ge1xuICBjcmVhdGVJbnN0YW5jZTogdHJ1ZSxcbiAgZHluYW1pY0xheW91dDogZmFsc2UsXG4gIGR5bmFtaWNUYWc6IGZhbHNlLFxuICB3cmFwcGVkOiBmYWxzZSxcbiAgcHJlcGFyZUFyZ3M6IGZhbHNlLFxuICBjcmVhdGVBcmdzOiB0cnVlLFxuICBhdHRyaWJ1dGVIb29rOiBmYWxzZSxcbiAgZWxlbWVudEhvb2s6IGZhbHNlLFxuICB1cGRhdGVIb29rOiB0cnVlLFxuICBjcmVhdGVDYWxsZXI6IGZhbHNlLFxuICBkeW5hbWljU2NvcGU6IHRydWUsXG59O1xuXG5jbGFzcyBDb21waWxlckRlbGVnYXRlIGltcGxlbWVudHMgSUNvbXBpbGVyRGVsZWdhdGU8TW9kdWxlTG9jYXRvcj4ge1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVzb2x2ZXI6IFJlc29sdmVyKSB7fVxuXG4gIGhhc0NvbXBvbmVudEluU2NvcGUobmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMucmVzb2x2ZXIuaWRlbnRpZnkoYHRlbXBsYXRlOiR7bmFtZX1gLCByZWZlcnJlci5tb2R1bGUpO1xuICB9XG5cbiAgcmVzb2x2ZUNvbXBvbmVudChuYW1lOiBzdHJpbmcsIHJlZmVycmVyOiBNb2R1bGVMb2NhdG9yKTogTW9kdWxlTG9jYXRvciB7XG4gICAgbGV0IHJlc29sdmVkID0gdGhpcy5yZXNvbHZlci5pZGVudGlmeShgdGVtcGxhdGU6JHtuYW1lfWAsIHJlZmVycmVyLm1vZHVsZSk7XG4gICAgcmV0dXJuIHsgbW9kdWxlOiByZXNvbHZlZCwgbmFtZTogJ2RlZmF1bHQnIH07XG4gIH1cblxuICBnZXRDb21wb25lbnRDYXBhYmlsaXRpZXMoKSB7XG4gICAgcmV0dXJuIENBUEFCSUxJVElFUztcbiAgfVxuXG4gIGhhc0hlbHBlckluU2NvcGUoaGVscGVyTmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMucmVzb2x2ZXIuaWRlbnRpZnkoYGhlbHBlcjoke2hlbHBlck5hbWV9YCwgcmVmZXJyZXIubW9kdWxlKTtcbiAgfVxuXG4gIHJlc29sdmVIZWxwZXIoaGVscGVyTmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IE1vZHVsZUxvY2F0b3Ige1xuICAgIGxldCByZXNvbHZlZCA9IHRoaXMucmVzb2x2ZXIuaWRlbnRpZnkoYGhlbHBlcjoke2hlbHBlck5hbWV9YCwgcmVmZXJyZXIubW9kdWxlKTtcbiAgICByZXR1cm4geyBtb2R1bGU6IHJlc29sdmVkLCBuYW1lOiAnZGVmYXVsdCcgfTtcbiAgfVxuXG4gIGhhc1BhcnRpYWxJblNjb3BlKHBhcnRpYWxOYW1lOiBzdHJpbmcsIHJlZmVycmVyOiBNb2R1bGVMb2NhdG9yKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgcmVzb2x2ZVBhcnRpYWwocGFydGlhbE5hbWU6IHN0cmluZywgcmVmZXJyZXI6IE1vZHVsZUxvY2F0b3IpOiBNb2R1bGVMb2NhdG9yIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cblxuICBoYXNNb2RpZmllckluU2NvcGUobW9kaWZpZXJOYW1lOiBzdHJpbmcsIHJlZmVycmVyOiBNb2R1bGVMb2NhdG9yKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgcmVzb2x2ZU1vZGlmaWVyKG1vZGlmaWVyTmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IE1vZHVsZUxvY2F0b3Ige1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBidWlsZEFwcDxUIGV4dGVuZHMgVGVzdEFwcGxpY2F0aW9uPihvcHRpb25zOiBBcHBCdWlsZGVyT3B0aW9uczxUPiA9IHt9KTogQXBwQnVpbGRlcjxUPiB7XG4gIG9wdGlvbnMuYXBwTmFtZSA9IG9wdGlvbnMuYXBwTmFtZSB8fCAndGVzdC1hcHAnO1xuICBvcHRpb25zLmxvYWRlciA9IG9wdGlvbnMubG9hZGVyIHx8ICdydW50aW1lLWNvbXBpbGVyJztcbiAgb3B0aW9ucy5BcHBsaWNhdGlvbkNsYXNzID1cbiAgICBvcHRpb25zLkFwcGxpY2F0aW9uQ2xhc3MgfHwgKFRlc3RBcHBsaWNhdGlvbiBhcyBBcHBsaWNhdGlvbkNvbnN0cnVjdG9yPFQ+KTtcblxuICByZXR1cm4gbmV3IEFwcEJ1aWxkZXIob3B0aW9ucy5hcHBOYW1lLCBvcHRpb25zKTtcbn1cblxuZXhwb3J0IHsgYnVpbGRBcHAgfTtcbiJdLCJzb3VyY2VSb290IjoiIn0=