From 97546debe25a874b6e1127653b1df6ade65eb853 Mon Sep 17 00:00:00 2001 From: Aleksandr Kanunnikov Date: Wed, 25 Aug 2021 19:24:37 +0300 Subject: [PATCH] ember selector engine --- docs/src/selectors.md | 47 +- src/server/injected/emberSelectorEngine.ts | 217 + src/server/injected/injectedScript.ts | 2 + src/server/selectors.ts | 4 +- .../ember-3-dist/assets/reading-list.js | 306 + .../ember-3-dist/assets/vendor.js | 95418 ++++++++++++++++ tests/assets/reading-list/ember3.html | 129 + tests/css-parser.spec.ts | 2 +- tests/page/selectors-ember.spec.ts | 118 + 9 files changed, 96239 insertions(+), 4 deletions(-) create mode 100644 src/server/injected/emberSelectorEngine.ts create mode 100644 tests/assets/reading-list/ember-3-dist/assets/reading-list.js create mode 100644 tests/assets/reading-list/ember-3-dist/assets/vendor.js create mode 100644 tests/assets/reading-list/ember3.html create mode 100644 tests/page/selectors-ember.spec.ts diff --git a/docs/src/selectors.md b/docs/src/selectors.md index c76f13d54401db..55e33ea50ada47 100644 --- a/docs/src/selectors.md +++ b/docs/src/selectors.md @@ -213,7 +213,23 @@ methods accept [`param: selector`] as their first argument. await page.ClickAsync("_vue=list-item[text *= 'milk' i]"); ``` Learn more about [Vue selectors][vue]. - +- Ember selector (experimental) + ```js + await page.click('_ember=LinkTo[text *= "milk" i]'); + ``` + ```java + page.click("_ember=LinkTo[text *= 'milk' i]"); + ``` + ```python async + await page.click("_ember=LinkTo[text *= "milk" i]") + ``` + ```python sync + page.click("_ember=LinkTo[text *= 'milk' i]") + ``` + ```csharp + await page.ClickAsync("_ember=LinkTo[text *= 'milk' i]"); + ``` + Learn more about [Ember selectors][ember]. ## Text selector @@ -781,6 +797,34 @@ Vue selectors, as well as [Vue DevTools](https://chrome.google.com/webstore/deta ::: +## Ember selectors + +:::note +Ember selectors are experimental and prefixed with `_`. The functionality might change in future. +::: + +Ember selectors allow selecting elements by its component name and property values. The syntax is very similar to [attribute selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) and supports all attribute selector operators. + +In ember selectors, component names are transcribed with **CamelCase**. + +Selector examples: + +- match by **component**: `_ember=LinkTo` +- match by component and **exact property value**, case-sensetive: `_ember=LinkTo[author = "Steven King"]` +- match by property value only, **case-insensetive**: `_ember=[author = "steven king" i]` +- match by component and **truthy property value**: `_ember=MyButton[enabled]` +- match by component and **boolean value**: `_ember=MyButton[enabled = false]` +- match by property **value substring**: `_ember=[author *= "King"]` +- match by component and **multiple properties**: `_ember=BookItem[author *= "king" i][year = 1990]` +- match by **nested** property value: `_ember=[some.nested.value = 12]` +- match by component and property value **prefix**: `_ember=BookItem[author ^= "Steven"]` +- match by component and property value **suffix**: `_ember=BookItem[author $= "Steven"]` + + + +To find Ember element names in a tree use [Ember Inspector](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi?hl=en). + + ## id, data-testid, data-test-id, data-test selectors Playwright supports a shorthand for selecting elements using certain attributes. Currently, only @@ -1124,4 +1168,5 @@ await page.ClickAsync("//*[@id='tsf']/div[2]/div[1]/div[1]/div/div[2]/input"); [xpath]: #xpath-selectors [react]: #react-selectors [vue]: #vue-selectors +[ember]: #ember-selectors [id]: #id-data-testid-data-test-id-data-test-selectors diff --git a/src/server/injected/emberSelectorEngine.ts b/src/server/injected/emberSelectorEngine.ts new file mode 100644 index 00000000000000..2dee1d65efbfec --- /dev/null +++ b/src/server/injected/emberSelectorEngine.ts @@ -0,0 +1,217 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SelectorEngine, SelectorRoot } from './selectorEngine'; +import { checkComponentAttribute, parseComponentSelector } from '../common/componentUtils'; + +interface IEmberAppInstance { + __container__: unknown; + _debugContainerKey?: string; +} + +interface IInteralEmberComponent { + children: IInteralEmberComponent[]; + args: { + named: Record + }, + bounds: { + firstNode: HTMLElement, + lastNode: HTMLElement, + parentElement: HTMLElement, + } + type: string; + name: string; +} + +interface IEmberComponent { + name: string; + args?: Record; + rootElements: HTMLElement[]; + components: IEmberComponent[]; + isComponent?: boolean; +} + +function normalizeToAngleBracketComponent(name: string) { + const SIMPLE_DASHERIZE_REGEXP = /[a-z]|\/|-/g; + const ALPHA = /[A-Za-z0-9]/; + + if (name.includes('.')) + return name; + + + return name.replace(SIMPLE_DASHERIZE_REGEXP, (char, index) => { + if (char === '/') + return '::'; + + + if (index === 0 || !ALPHA.test(name[index - 1])) + return char.toUpperCase(); + + + // Remove all occurrences of '-'s from the name that aren't starting with `-` + return char === '-' ? '' : char.toLowerCase(); + }); +} + +function getEmber() { + let EmberCore; + const w = window as any; + + try { + EmberCore = w.requireModule('ember')['default']; + } catch { + EmberCore = w.Ember; + } + + return EmberCore; +} + +function findEmberRoots(): IEmberAppInstance[] { + + const EmberCore = getEmber(); + + if (!EmberCore) + return []; + + + const isEmberApp = (el: any) => el._debugContainerKey === 'application:main'; + + const app: IEmberAppInstance | null = Object.values(EmberCore.Application.NAMESPACES).find(isEmberApp) as IEmberAppInstance | null; + + if (!app) + return []; + + + return [app]; +} + +function normalizeExtractedComponents(node: IEmberComponent) { + function cleanComponent(el: IEmberComponent) { + if (el.isComponent) { + delete el.isComponent; + if (!Object.keys(el.args || {}).length) + delete el.args; + + } + } + + const result = []; + if (node.isComponent) { + cleanComponent(node); + node.components.forEach((el: IEmberComponent) => { + cleanComponent(el); + }); + result.push(node); + } else { + node.components.forEach((el: IEmberComponent) => { + const results = normalizeExtractedComponents(el); + result.push(...results); + }); + } + + return result; +} + +function buildComponentsTree(appRoot: IEmberAppInstance): IEmberComponent[] { + const tree = getEmber()._captureRenderTree(appRoot.__container__); + const components = extractComponents(tree[0]); + const normalizedComponents = normalizeExtractedComponents(components[0]); + return normalizedComponents; +} + + +function findRoots(bounds: { firstNode: HTMLElement, lastNode: HTMLElement, parentElement: HTMLElement }) { + const { firstNode, lastNode, parentElement } = bounds; + const roots: ChildNode[] = []; + const closest = parentElement.childNodes; + if (firstNode === lastNode) + return [firstNode]; + + let start = null; + let end = null; + for (let i = 0; i < closest.length; i++) { + if (closest.item(i) === firstNode) + start = i; + else if (closest.item(i) === lastNode) + end = i; + } + + if (start === null || end === null) + return []; + + + for (let i = start; i <= end; i++) + roots.push(closest.item(i)); + + + return roots.filter((el: ChildNode) => { + if (el.nodeType === 3) { + if (el.nodeValue && el.nodeValue.trim() === '') + return false; + + } + return el; + }) as HTMLElement[]; +} + +function extractComponents(node: IInteralEmberComponent) { + const components: IEmberComponent[] = node.children.map((el: IInteralEmberComponent) => { + const instance: IEmberComponent = { + isComponent: el.type === 'component', + name: normalizeToAngleBracketComponent(el.name), + args: el.args.named, + rootElements: findRoots(el.bounds), + components: extractComponents(el) + }; + return instance; + }); + return components; +} + +function filterComponentsTree(treeNode: IEmberComponent, searchFn: (node: IEmberComponent) => boolean, result: IEmberComponent[] = []) { + if (searchFn(treeNode)) + result.push(treeNode); + for (const child of treeNode.components) + filterComponentsTree(child, searchFn, result); + return result; +} + +export const EmberEngine: SelectorEngine = { + queryAll(scope: SelectorRoot, selector: string): Element[] { + const { name, attributes } = parseComponentSelector(selector); + + const emberRoots = findEmberRoots(); + + const trees = emberRoots.map(emberRoot => buildComponentsTree(emberRoot)[0]); + const treeNodes = trees.map(tree => filterComponentsTree(tree, treeNode => { + if (name && treeNode.name !== name) + return false; + if (treeNode.rootElements.some(domNode => !scope.contains(domNode))) + return false; + for (const attr of attributes) { + if (!checkComponentAttribute(treeNode.args || {}, attr)) + return false; + } + return true; + })).flat(); + const allRootElements: Set = new Set(); + for (const treeNode of treeNodes) { + for (const domNode of treeNode.rootElements) + allRootElements.add(domNode); + } + return [...allRootElements]; + } +}; diff --git a/src/server/injected/injectedScript.ts b/src/server/injected/injectedScript.ts index 74549e975bc9ab..1c120d9eb76ce2 100644 --- a/src/server/injected/injectedScript.ts +++ b/src/server/injected/injectedScript.ts @@ -18,6 +18,7 @@ import { SelectorEngine, SelectorRoot } from './selectorEngine'; import { XPathEngine } from './xpathSelectorEngine'; import { ReactEngine } from './reactSelectorEngine'; import { VueEngine } from './vueSelectorEngine'; +import { EmberEngine } from './emberSelectorEngine'; import { ParsedSelector, ParsedSelectorPart, parseSelector } from '../common/selectorParser'; import { FatalDOMError } from '../common/domErrors'; import { SelectorEvaluatorImpl, isVisible, parentElementOrShadowHost, elementMatchesText, TextMatcher, createRegexTextMatcher, createStrictTextMatcher, createLaxTextMatcher } from './selectorEvaluator'; @@ -66,6 +67,7 @@ export class InjectedScript { this._engines.set('xpath:light', XPathEngine); this._engines.set('_react', ReactEngine); this._engines.set('_vue', VueEngine); + this._engines.set('_ember', EmberEngine); this._engines.set('text', this._createTextEngine(true)); this._engines.set('text:light', this._createTextEngine(false)); this._engines.set('id', this._createAttributeEngine('id', true)); diff --git a/src/server/selectors.ts b/src/server/selectors.ts index e6989c88dd3901..11b7da22899658 100644 --- a/src/server/selectors.ts +++ b/src/server/selectors.ts @@ -39,7 +39,7 @@ export class Selectors { this._builtinEngines = new Set([ 'css', 'css:light', 'xpath', 'xpath:light', - '_react', '_vue', + '_react', '_vue', '_ember', 'text', 'text:light', 'id', 'id:light', 'data-testid', 'data-testid:light', @@ -48,7 +48,7 @@ export class Selectors { 'nth', 'visible' ]); this._builtinEnginesInMainWorld = new Set([ - '_react', '_vue', + '_react', '_vue', '_ember', ]); this._engines = new Map(); } diff --git a/tests/assets/reading-list/ember-3-dist/assets/reading-list.js b/tests/assets/reading-list/ember-3-dist/assets/reading-list.js new file mode 100644 index 00000000000000..4d5f6d82f45d3f --- /dev/null +++ b/tests/assets/reading-list/ember-3-dist/assets/reading-list.js @@ -0,0 +1,306 @@ +'use strict'; + + + +;define("reading-list/app", ["exports", "@ember/application", "ember-resolver", "ember-load-initializers", "reading-list/config/environment"], function (_exports, _application, _emberResolver, _emberLoadInitializers, _environment) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + class App extends _application.default { + constructor(...args) { + super(...args); + + _defineProperty(this, "modulePrefix", _environment.default.modulePrefix); + + _defineProperty(this, "podModulePrefix", _environment.default.podModulePrefix); + + _defineProperty(this, "Resolver", _emberResolver.default); + } + + } + + _exports.default = App; + (0, _emberLoadInitializers.default)(App, _environment.default.modulePrefix); +}); +;define("reading-list/component-managers/glimmer", ["exports", "@glimmer/component/-private/ember-component-manager"], function (_exports, _emberComponentManager) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "default", { + enumerable: true, + get: function () { + return _emberComponentManager.default; + } + }); +}); +;define("reading-list/components/main/index", ["exports", "@glimmer/component", "ember-template-compiler", "@glimmer/manager", "@ember/application", "@ember/component/template-only", "@glimmer/tracking"], function (_exports, _component, _emberTemplateCompiler, _manager, _application, _templateOnly, _tracking) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + + var _class, _descriptor; + + function _initializerDefineProperty(target, property, descriptor, context) { if (!descriptor) return; Object.defineProperty(target, property, { enumerable: descriptor.enumerable, configurable: descriptor.configurable, writable: descriptor.writable, value: descriptor.initializer ? descriptor.initializer.call(context) : void 0 }); } + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } + + function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'proposal-class-properties is enabled and runs after the decorators transform.'); } + + let ReactiveComponent = (_class = class ReactiveComponent extends _component.default { + constructor(...args) { + super(...args); + + _initializerDefineProperty(this, "data", _descriptor, this); + } + + }, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "data", [_tracking.tracked], { + configurable: true, + enumerable: true, + writable: true, + initializer: null + })), _class); + + class MainComponent extends _component.default { + constructor() { + super(...arguments); + const owner = (0, _application.getOwner)(this); + const ctx = { + GlimmerComponent: ReactiveComponent, + templateOnlyComponent: _templateOnly.default, + RegisterComponent: (name, klass, template) => { + if (name.toLowerCase() === 'main') { + this._trueMain = (0, _manager.setComponentTemplate)(_emberTemplateCompiler.default.compile(template), klass); + } else { + owner.application.register(`component:${name}`, (0, _manager.setComponentTemplate)(_emberTemplateCompiler.default.compile(template), klass)); + } + } + }; + + if (typeof window.EmberAppSetup === 'function') { + window.EmberAppSetup(ctx); + } + } + + get TrueMain() { + return this._trueMain; + } + + } + + (0, _manager.setComponentTemplate)(_emberTemplateCompiler.default.compile(''), MainComponent); + var _default = MainComponent; + _exports.default = _default; +}); +;define("reading-list/helpers/app-version", ["exports", "@ember/component/helper", "reading-list/config/environment", "ember-cli-app-version/utils/regexp"], function (_exports, _helper, _environment, _regexp) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.appVersion = appVersion; + _exports.default = void 0; + + function appVersion(_, hash = {}) { + const version = _environment.default.APP.version; // e.g. 1.0.0-alpha.1+4jds75hf + // Allow use of 'hideSha' and 'hideVersion' For backwards compatibility + + let versionOnly = hash.versionOnly || hash.hideSha; + let shaOnly = hash.shaOnly || hash.hideVersion; + let match = null; + + if (versionOnly) { + if (hash.showExtended) { + match = version.match(_regexp.versionExtendedRegExp); // 1.0.0-alpha.1 + } // Fallback to just version + + + if (!match) { + match = version.match(_regexp.versionRegExp); // 1.0.0 + } + } + + if (shaOnly) { + match = version.match(_regexp.shaRegExp); // 4jds75hf + } + + return match ? match[0] : version; + } + + var _default = (0, _helper.helper)(appVersion); + + _exports.default = _default; +}); +;define("reading-list/initializers/app-version", ["exports", "ember-cli-app-version/initializer-factory", "reading-list/config/environment"], function (_exports, _initializerFactory, _environment) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + let name, version; + + if (_environment.default.APP) { + name = _environment.default.APP.name; + version = _environment.default.APP.version; + } + + var _default = { + name: 'App Version', + initialize: (0, _initializerFactory.default)(name, version) + }; + _exports.default = _default; +}); +;define("reading-list/initializers/container-debug-adapter", ["exports", "ember-resolver/resolvers/classic/container-debug-adapter"], function (_exports, _containerDebugAdapter) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + var _default = { + name: 'container-debug-adapter', + + initialize() { + let app = arguments[1] || arguments[0]; + app.register('container-debug-adapter:main', _containerDebugAdapter.default); + app.inject('container-debug-adapter:main', 'namespace', 'application:main'); + } + + }; + _exports.default = _default; +}); +;define("reading-list/initializers/export-application-global", ["exports", "ember", "reading-list/config/environment"], function (_exports, _ember, _environment) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.initialize = initialize; + _exports.default = void 0; + + function initialize() { + var application = arguments[1] || arguments[0]; + + if (_environment.default.exportApplicationGlobal !== false) { + var theGlobal; + + if (typeof window !== 'undefined') { + theGlobal = window; + } else if (typeof global !== 'undefined') { + theGlobal = global; + } else if (typeof self !== 'undefined') { + theGlobal = self; + } else { + // no reasonable global, just bail + return; + } + + var value = _environment.default.exportApplicationGlobal; + var globalName; + + if (typeof value === 'string') { + globalName = value; + } else { + globalName = _ember.default.String.classify(_environment.default.modulePrefix); + } + + if (!theGlobal[globalName]) { + theGlobal[globalName] = application; + application.reopen({ + willDestroy: function () { + this._super.apply(this, arguments); + + delete theGlobal[globalName]; + } + }); + } + } + } + + var _default = { + name: 'export-application-global', + initialize: initialize + }; + _exports.default = _default; +}); +;define("reading-list/router", ["exports", "@ember/routing/router", "reading-list/config/environment"], function (_exports, _router, _environment) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + class Router extends _router.default { + constructor(...args) { + super(...args); + + _defineProperty(this, "location", _environment.default.locationType); + + _defineProperty(this, "rootURL", _environment.default.rootURL); + } + + } + + _exports.default = Router; + Router.map(function () {}); +}); +;define("reading-list/templates/application", ["exports", "@ember/template-factory"], function (_exports, _templateFactory) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + + var _default = (0, _templateFactory.createTemplateFactory)({ + "id": "VMPMPwMX", + "block": "[[[8,[39,0],null,null,null]],[],false,[\"main\"]]", + "moduleName": "reading-list/templates/application.hbs", + "isStrictMode": false + }); + + _exports.default = _default; +}); +; + +;define('reading-list/config/environment', [], function() { + var prefix = 'reading-list'; +try { + var metaName = prefix + '/config/environment'; + var rawConfig = document.querySelector('meta[name="' + metaName + '"]').getAttribute('content'); + var config = JSON.parse(decodeURIComponent(rawConfig)); + + var exports = { 'default': config }; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; +} +catch(err) { + throw new Error('Could not read config from meta tag with name "' + metaName + '".'); +} + +}); + +; + if (!runningTests) { + require("reading-list/app")["default"].create({"name":"reading-list","version":"0.0.0+33d058ab"}); + } + +//# sourceMappingURL=reading-list.map diff --git a/tests/assets/reading-list/ember-3-dist/assets/vendor.js b/tests/assets/reading-list/ember-3-dist/assets/vendor.js new file mode 100644 index 00000000000000..cdb5b58ab2d58c --- /dev/null +++ b/tests/assets/reading-list/ember-3-dist/assets/vendor.js @@ -0,0 +1,95418 @@ +window.EmberENV = (function(EmberENV, extra) { + for (var key in extra) { + EmberENV[key] = extra[key]; + } + + return EmberENV; +})(window.EmberENV || {}, {"FEATURES":{},"EXTEND_PROTOTYPES":{"Date":false},"_APPLICATION_TEMPLATE_WRAPPER":false,"_DEFAULT_ASYNC_OBSERVERS":true,"_JQUERY_INTEGRATION":false,"_TEMPLATE_ONLY_GLIMMER_COMPONENTS":true}); + +var runningTests = false; + + + +;var loader, define, requireModule, require, requirejs; + +(function (global) { + 'use strict'; + + function dict() { + var obj = Object.create(null); + obj['__'] = undefined; + delete obj['__']; + return obj; + } + + // Save off the original values of these globals, so we can restore them if someone asks us to + var oldGlobals = { + loader: loader, + define: define, + requireModule: requireModule, + require: require, + requirejs: requirejs + }; + + requirejs = require = requireModule = function (id) { + var pending = []; + var mod = findModule(id, '(require)', pending); + + for (var i = pending.length - 1; i >= 0; i--) { + pending[i].exports(); + } + + return mod.module.exports; + }; + + loader = { + noConflict: function (aliases) { + var oldName, newName; + + for (oldName in aliases) { + if (aliases.hasOwnProperty(oldName)) { + if (oldGlobals.hasOwnProperty(oldName)) { + newName = aliases[oldName]; + + global[newName] = global[oldName]; + global[oldName] = oldGlobals[oldName]; + } + } + } + }, + // Option to enable or disable the generation of default exports + makeDefaultExport: true + }; + + var registry = dict(); + var seen = dict(); + + var uuid = 0; + + function unsupportedModule(length) { + throw new Error('an unsupported module was defined, expected `define(id, deps, module)` instead got: `' + length + '` arguments to define`'); + } + + var defaultDeps = ['require', 'exports', 'module']; + + function Module(id, deps, callback, alias) { + this.uuid = uuid++; + this.id = id; + this.deps = !deps.length && callback.length ? defaultDeps : deps; + this.module = { exports: {} }; + this.callback = callback; + this.hasExportsAsDep = false; + this.isAlias = alias; + this.reified = new Array(deps.length); + + /* + Each module normally passes through these states, in order: + new : initial state + pending : this module is scheduled to be executed + reifying : this module's dependencies are being executed + reified : this module's dependencies finished executing successfully + errored : this module's dependencies failed to execute + finalized : this module executed successfully + */ + this.state = 'new'; + } + + Module.prototype.makeDefaultExport = function () { + var exports = this.module.exports; + if (exports !== null && (typeof exports === 'object' || typeof exports === 'function') && exports['default'] === undefined && Object.isExtensible(exports)) { + exports['default'] = exports; + } + }; + + Module.prototype.exports = function () { + // if finalized, there is no work to do. If reifying, there is a + // circular dependency so we must return our (partial) exports. + if (this.state === 'finalized' || this.state === 'reifying') { + return this.module.exports; + } + + + if (loader.wrapModules) { + this.callback = loader.wrapModules(this.id, this.callback); + } + + this.reify(); + + var result = this.callback.apply(this, this.reified); + this.reified.length = 0; + this.state = 'finalized'; + + if (!(this.hasExportsAsDep && result === undefined)) { + this.module.exports = result; + } + if (loader.makeDefaultExport) { + this.makeDefaultExport(); + } + return this.module.exports; + }; + + Module.prototype.unsee = function () { + this.state = 'new'; + this.module = { exports: {} }; + }; + + Module.prototype.reify = function () { + if (this.state === 'reified') { + return; + } + this.state = 'reifying'; + try { + this.reified = this._reify(); + this.state = 'reified'; + } finally { + if (this.state === 'reifying') { + this.state = 'errored'; + } + } + }; + + Module.prototype._reify = function () { + var reified = this.reified.slice(); + for (var i = 0; i < reified.length; i++) { + var mod = reified[i]; + reified[i] = mod.exports ? mod.exports : mod.module.exports(); + } + return reified; + }; + + Module.prototype.findDeps = function (pending) { + if (this.state !== 'new') { + return; + } + + this.state = 'pending'; + + var deps = this.deps; + + for (var i = 0; i < deps.length; i++) { + var dep = deps[i]; + var entry = this.reified[i] = { exports: undefined, module: undefined }; + if (dep === 'exports') { + this.hasExportsAsDep = true; + entry.exports = this.module.exports; + } else if (dep === 'require') { + entry.exports = this.makeRequire(); + } else if (dep === 'module') { + entry.exports = this.module; + } else { + entry.module = findModule(resolve(dep, this.id), this.id, pending); + } + } + }; + + Module.prototype.makeRequire = function () { + var id = this.id; + var r = function (dep) { + return require(resolve(dep, id)); + }; + r['default'] = r; + r.moduleId = id; + r.has = function (dep) { + return has(resolve(dep, id)); + }; + return r; + }; + + define = function (id, deps, callback) { + var module = registry[id]; + + // If a module for this id has already been defined and is in any state + // other than `new` (meaning it has been or is currently being required), + // then we return early to avoid redefinition. + if (module && module.state !== 'new') { + return; + } + + if (arguments.length < 2) { + unsupportedModule(arguments.length); + } + + if (!Array.isArray(deps)) { + callback = deps; + deps = []; + } + + if (callback instanceof Alias) { + registry[id] = new Module(callback.id, deps, callback, true); + } else { + registry[id] = new Module(id, deps, callback, false); + } + }; + + define.exports = function (name, defaultExport) { + var module = registry[name]; + + // If a module for this name has already been defined and is in any state + // other than `new` (meaning it has been or is currently being required), + // then we return early to avoid redefinition. + if (module && module.state !== 'new') { + return; + } + + module = new Module(name, [], noop, null); + module.module.exports = defaultExport; + module.state = 'finalized'; + registry[name] = module; + + return module; + }; + + function noop() {} + // we don't support all of AMD + // define.amd = {}; + + function Alias(id) { + this.id = id; + } + + define.alias = function (id, target) { + if (arguments.length === 2) { + return define(target, new Alias(id)); + } + + return new Alias(id); + }; + + function missingModule(id, referrer) { + throw new Error('Could not find module `' + id + '` imported from `' + referrer + '`'); + } + + function findModule(id, referrer, pending) { + var mod = registry[id] || registry[id + '/index']; + + while (mod && mod.isAlias) { + mod = registry[mod.id] || registry[mod.id + '/index']; + } + + if (!mod) { + missingModule(id, referrer); + } + + if (pending && mod.state !== 'pending' && mod.state !== 'finalized') { + mod.findDeps(pending); + pending.push(mod); + } + return mod; + } + + function resolve(child, id) { + if (child.charAt(0) !== '.') { + return child; + } + + + var parts = child.split('/'); + var nameParts = id.split('/'); + var parentBase = nameParts.slice(0, -1); + + for (var i = 0, l = parts.length; i < l; i++) { + var part = parts[i]; + + if (part === '..') { + if (parentBase.length === 0) { + throw new Error('Cannot access parent module of root'); + } + parentBase.pop(); + } else if (part === '.') { + continue; + } else { + parentBase.push(part); + } + } + + return parentBase.join('/'); + } + + function has(id) { + return !!(registry[id] || registry[id + '/index']); + } + + requirejs.entries = requirejs._eak_seen = registry; + requirejs.has = has; + requirejs.unsee = function (id) { + findModule(id, '(unsee)', false).unsee(); + }; + + requirejs.clear = function () { + requirejs.entries = requirejs._eak_seen = registry = dict(); + seen = dict(); + }; + + // This code primes the JS engine for good performance by warming the + // JIT compiler for these functions. + define('foo', function () {}); + define('foo/bar', [], function () {}); + define('foo/asdf', ['module', 'exports', 'require'], function (module, exports, require) { + if (require.has('foo/bar')) { + require('foo/bar'); + } + }); + define('foo/baz', [], define.alias('foo')); + define('foo/quz', define.alias('foo')); + define.alias('foo', 'foo/qux'); + define('foo/bar', ['foo', './quz', './baz', './asdf', './bar', '../foo'], function () {}); + define('foo/main', ['foo/bar'], function () {}); + define.exports('foo/exports', {}); + + require('foo/exports'); + require('foo/main'); + require.unsee('foo/bar'); + + requirejs.clear(); + + if (typeof exports === 'object' && typeof module === 'object' && module.exports) { + module.exports = { require: require, define: define }; + } +})(this); +;(function() { +/*! + * @overview Ember - JavaScript Application Framework + * @copyright Copyright 2011-2021 Tilde Inc. and contributors + * Portions Copyright 2006-2011 Strobe Inc. + * Portions Copyright 2008-2011 Apple Inc. All rights reserved. + * @license Licensed under MIT license + * See https://raw.github.com/emberjs/ember.js/master/LICENSE + * @version 3.27.5 + */ +/* eslint-disable no-var */ + +/* globals global globalThis self */ +var define, require; + +(function () { + var globalObj = typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : null; + + if (globalObj === null) { + throw new Error('unable to locate global object'); + } + + if (typeof globalObj.define === 'function' && typeof globalObj.require === 'function') { + define = globalObj.define; + require = globalObj.require; + return; + } + + var registry = Object.create(null); + var seen = Object.create(null); + + function missingModule(name, referrerName) { + if (referrerName) { + throw new Error('Could not find module ' + name + ' required by: ' + referrerName); + } else { + throw new Error('Could not find module ' + name); + } + } + + function internalRequire(_name, referrerName) { + var name = _name; + var mod = registry[name]; + + if (!mod) { + name = name + '/index'; + mod = registry[name]; + } + + var exports = seen[name]; + + if (exports !== undefined) { + return exports; + } + + exports = seen[name] = {}; + + if (!mod) { + missingModule(_name, referrerName); + } + + var deps = mod.deps; + var callback = mod.callback; + var reified = new Array(deps.length); + + for (var i = 0; i < deps.length; i++) { + if (deps[i] === 'exports') { + reified[i] = exports; + } else if (deps[i] === 'require') { + reified[i] = require; + } else { + reified[i] = require(deps[i], name); + } + } + + callback.apply(this, reified); + return exports; + } + + require = function (name) { + return internalRequire(name, null); + }; // eslint-disable-next-line no-unused-vars + + + define = function (name, deps, callback) { + registry[name] = { + deps: deps, + callback: callback + }; + }; // setup `require` module + + + require['default'] = require; + + require.has = function registryHas(moduleName) { + return Boolean(registry[moduleName]) || Boolean(registry[moduleName + '/index']); + }; + + require._eak_seen = require.entries = registry; +})(); +define("@ember/-internals/bootstrap/index", ["@ember/-internals/environment", "@ember/-internals/overrides", "@ember/debug", "require"], function (_environment, _overrides, _debug, _require) { + "use strict"; + + (function bootstrap() { + var Ember; + + var get = () => { + if (!Ember) { + // tslint:disable-next-line: no-require-imports + Ember = (0, _require.default)("ember").default; + } + + return Ember; + }; + + if (true + /* DEBUG */ + ) { + var defaultHandler = () => { + return 'Usage of the Ember Global is deprecated. You should import the Ember module or the specific API instead.'; + }; + + var handler = _overrides.onEmberGlobalAccess || defaultHandler; + var _get = get; + + get = () => { + var message = handler(); + + if (message !== null) { + (true && !(false) && (0, _debug.deprecate)(message, false, { + id: 'ember-global', + until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-global', + for: 'ember-source', + since: { + enabled: '3.27.0' + } + })); + } + + return _get(); + }; + } + + function defineEmber(key) { + Object.defineProperty(_environment.context.exports, key, { + enumerable: true, + configurable: true, + get + }); + } // Bootstrap the global + + + defineEmber('Ember'); + defineEmber('Em'); // Bootstrap Node module + // eslint-disable-next-line no-undef + + if (typeof module === 'object' && typeof module.require === 'function') { + // tslint:disable-next-line: no-require-imports + module.exports = Ember = (0, _require.default)("ember").default; + } + })(); +}); +define("@ember/-internals/browser-environment/index", ["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.hasDOM = _exports.isIE = _exports.isFirefox = _exports.isChrome = _exports.userAgent = _exports.history = _exports.location = _exports.window = void 0; + // check if window exists and actually is the global + var hasDom = typeof self === 'object' && self !== null && self.Object === Object && typeof Window !== 'undefined' && self.constructor === Window && typeof document === 'object' && document !== null && self.document === document && typeof location === 'object' && location !== null && self.location === location && typeof history === 'object' && history !== null && self.history === history && typeof navigator === 'object' && navigator !== null && self.navigator === navigator && typeof navigator.userAgent === 'string'; + _exports.hasDOM = hasDom; + var window = hasDom ? self : null; + _exports.window = window; + var location$1 = hasDom ? self.location : null; + _exports.location = location$1; + var history$1 = hasDom ? self.history : null; + _exports.history = history$1; + var userAgent = hasDom ? self.navigator.userAgent : 'Lynx (textmode)'; + _exports.userAgent = userAgent; + var isChrome = hasDom ? typeof chrome === 'object' && !(typeof opera === 'object') : false; + _exports.isChrome = isChrome; + var isFirefox = hasDom ? typeof InstallTrigger !== 'undefined' : false; + _exports.isFirefox = isFirefox; + var isIE = hasDom ? typeof MSInputMethodContext !== 'undefined' && typeof documentMode !== 'undefined' : false; + _exports.isIE = isIE; +}); +define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/deprecated-features"], function (_exports, _debug, _deprecatedFeatures) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + // Deliver message that the function is deprecated + var DEPRECATION_MESSAGE = 'Use of Ember.Logger is deprecated. Please use `console` for logging.'; + var DEPRECATION_ID = 'ember-console.deprecate-logger'; + var DEPRECATION_URL = 'https://deprecations.emberjs.com/v3.x#toc_use-console-rather-than-ember-logger'; + /** + @module ember + */ + + /** + Inside Ember-Metal, simply uses the methods from `imports.console`. + Override this to provide more robust logging functionality. + + @class Logger + @deprecated Use 'console' instead + + @namespace Ember + @public + */ + + var DEPRECATED_LOGGER; + + if (_deprecatedFeatures.LOGGER) { + DEPRECATED_LOGGER = { + /** + Logs the arguments to the console. + You can pass as many arguments as you want and they will be joined together with a space. + ```javascript + var foo = 1; + Ember.Logger.log('log value of foo:', foo); + // "log value of foo: 1" will be printed to the console + ``` + @method log + @for Ember.Logger + @param {*} arguments + @public + */ + log() { + (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { + id: DEPRECATION_ID, + until: '4.0.0', + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } + })); + return console.log(...arguments); // eslint-disable-line no-console + }, + + /** + Prints the arguments to the console with a warning icon. + You can pass as many arguments as you want and they will be joined together with a space. + ```javascript + Ember.Logger.warn('Something happened!'); + // "Something happened!" will be printed to the console with a warning icon. + ``` + @method warn + @for Ember.Logger + @param {*} arguments + @public + */ + warn() { + (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { + id: DEPRECATION_ID, + until: '4.0.0', + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } + })); + return console.warn(...arguments); // eslint-disable-line no-console + }, + + /** + Prints the arguments to the console with an error icon, red text and a stack trace. + You can pass as many arguments as you want and they will be joined together with a space. + ```javascript + Ember.Logger.error('Danger! Danger!'); + // "Danger! Danger!" will be printed to the console in red text. + ``` + @method error + @for Ember.Logger + @param {*} arguments + @public + */ + error() { + (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { + id: DEPRECATION_ID, + until: '4.0.0', + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } + })); + return console.error(...arguments); // eslint-disable-line no-console + }, + + /** + Logs the arguments to the console. + You can pass as many arguments as you want and they will be joined together with a space. + ```javascript + var foo = 1; + Ember.Logger.info('log value of foo:', foo); + // "log value of foo: 1" will be printed to the console + ``` + @method info + @for Ember.Logger + @param {*} arguments + @public + */ + info() { + (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { + id: DEPRECATION_ID, + until: '4.0.0', + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } + })); + return console.info(...arguments); // eslint-disable-line no-console + }, + + /** + Logs the arguments to the console in blue text. + You can pass as many arguments as you want and they will be joined together with a space. + ```javascript + var foo = 1; + Ember.Logger.debug('log value of foo:', foo); + // "log value of foo: 1" will be printed to the console + ``` + @method debug + @for Ember.Logger + @param {*} arguments + @public + */ + debug() { + (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { + id: DEPRECATION_ID, + until: '4.0.0', + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } + })); + /* eslint-disable no-console */ + + if (console.debug) { + return console.debug(...arguments); + } + + return console.info(...arguments); + /* eslint-enable no-console */ + }, + + /** + If the value passed into `Ember.Logger.assert` is not truthy it will throw an error with a stack trace. + ```javascript + Ember.Logger.assert(true); // undefined + Ember.Logger.assert(true === false); // Throws an Assertion failed error. + Ember.Logger.assert(true === false, 'Something invalid'); // Throws an Assertion failed error with message. + ``` + @method assert + @for Ember.Logger + @param {Boolean} bool Value to test + @param {String} message Assertion message on failed + @public + */ + assert() { + (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { + id: DEPRECATION_ID, + until: '4.0.0', + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } + })); + return console.assert(...arguments); // eslint-disable-line no-console + } + + }; + } + + var _default = DEPRECATED_LOGGER; + _exports.default = _default; +}); +define("@ember/-internals/container/index", ["exports", "@ember/-internals/owner", "@ember/-internals/utils", "@ember/debug", "@ember/polyfills"], function (_exports, _owner, _utils, _debug, _polyfills) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.privatize = privatize; + _exports.getFactoryFor = getFactoryFor; + _exports.setFactoryFor = setFactoryFor; + _exports.INIT_FACTORY = _exports.Container = _exports.Registry = void 0; + var leakTracking; + var containers; + + if (true + /* DEBUG */ + ) { + // requires v8 + // chrome --js-flags="--allow-natives-syntax --expose-gc" + // node --allow-natives-syntax --expose-gc + try { + if (typeof gc === 'function') { + leakTracking = (() => { + // avoid syntax errors when --allow-natives-syntax not present + var GetWeakSetValues = new Function('weakSet', 'return %GetWeakSetValues(weakSet, 0)'); + containers = new WeakSet(); + return { + hasContainers() { + gc(); + return GetWeakSetValues(containers).length > 0; + }, + + reset() { + var values = GetWeakSetValues(containers); + + for (var i = 0; i < values.length; i++) { + containers.delete(values[i]); + } + } + + }; + })(); + } + } catch (e) {// ignore + } + } + /** + A container used to instantiate and cache objects. + + Every `Container` must be associated with a `Registry`, which is referenced + to determine the factory and options that should be used to instantiate + objects. + + The public API for `Container` is still in flux and should not be considered + stable. + + @private + @class Container + */ + + + class Container { + constructor(registry, options = {}) { + this.registry = registry; + this.owner = options.owner || null; + this.cache = (0, _utils.dictionary)(options.cache || null); + this.factoryManagerCache = (0, _utils.dictionary)(options.factoryManagerCache || null); + this.isDestroyed = false; + this.isDestroying = false; + + if (true + /* DEBUG */ + ) { + this.validationCache = (0, _utils.dictionary)(options.validationCache || null); + + if (containers !== undefined) { + containers.add(this); + } + } + } + /** + @private + @property registry + @type Registry + @since 1.11.0 + */ + + /** + @private + @property cache + @type InheritingDict + */ + + /** + @private + @property validationCache + @type InheritingDict + */ + + /** + Given a fullName return a corresponding instance. + The default behavior is for lookup to return a singleton instance. + The singleton is scoped to the container, allowing multiple containers + to all have their own locally scoped singletons. + ```javascript + let registry = new Registry(); + let container = registry.container(); + registry.register('api:twitter', Twitter); + let twitter = container.lookup('api:twitter'); + twitter instanceof Twitter; // => true + // by default the container will return singletons + let twitter2 = container.lookup('api:twitter'); + twitter2 instanceof Twitter; // => true + twitter === twitter2; //=> true + ``` + If singletons are not wanted, an optional flag can be provided at lookup. + ```javascript + let registry = new Registry(); + let container = registry.container(); + registry.register('api:twitter', Twitter); + let twitter = container.lookup('api:twitter', { singleton: false }); + let twitter2 = container.lookup('api:twitter', { singleton: false }); + twitter === twitter2; //=> false + ``` + @private + @method lookup + @param {String} fullName + @param {Object} [options] + @param {String} [options.source] The fullname of the request source (used for local lookup) + @return {any} + */ + + + lookup(fullName, options) { + if (this.isDestroyed) { + throw new Error(`Can not call \`.lookup\` after the owner has been destroyed`); + } + + (true && !(this.registry.isValidFullName(fullName)) && (0, _debug.assert)('fullName must be a proper full name', this.registry.isValidFullName(fullName))); + return lookup(this, this.registry.normalize(fullName), options); + } + /** + A depth first traversal, destroying the container, its descendant containers and all + their managed objects. + @private + @method destroy + */ + + + destroy() { + this.isDestroying = true; + destroyDestroyables(this); + } + + finalizeDestroy() { + resetCache(this); + this.isDestroyed = true; + } + /** + Clear either the entire cache or just the cache for a particular key. + @private + @method reset + @param {String} fullName optional key to reset; if missing, resets everything + */ + + + reset(fullName) { + if (this.isDestroyed) return; + + if (fullName === undefined) { + destroyDestroyables(this); + resetCache(this); + } else { + resetMember(this, this.registry.normalize(fullName)); + } + } + /** + Returns an object that can be used to provide an owner to a + manually created instance. + @private + @method ownerInjection + @returns { Object } + */ + + + ownerInjection() { + var injection = {}; + (0, _owner.setOwner)(injection, this.owner); + return injection; + } + /** + Given a fullName, return the corresponding factory. The consumer of the factory + is responsible for the destruction of any factory instances, as there is no + way for the container to ensure instances are destroyed when it itself is + destroyed. + @public + @method factoryFor + @param {String} fullName + @param {Object} [options] + @param {String} [options.source] The fullname of the request source (used for local lookup) + @return {any} + */ + + + factoryFor(fullName) { + if (this.isDestroyed) { + throw new Error(`Can not call \`.factoryFor\` after the owner has been destroyed`); + } + + var normalizedName = this.registry.normalize(fullName); + (true && !(this.registry.isValidFullName(normalizedName)) && (0, _debug.assert)('fullName must be a proper full name', this.registry.isValidFullName(normalizedName))); + return factoryFor(this, normalizedName, fullName); + } + + } + + _exports.Container = Container; + + if (true + /* DEBUG */ + ) { + Container._leakTracking = leakTracking; + } + /* + * Wrap a factory manager in a proxy which will not permit properties to be + * set on the manager. + */ + + + function wrapManagerInDeprecationProxy(manager) { + if (_utils.HAS_NATIVE_PROXY) { + var validator = { + set(_obj, prop) { + throw new Error(`You attempted to set "${prop}" on a factory manager created by container#factoryFor. A factory manager is a read-only construct.`); + } + + }; // Note: + // We have to proxy access to the manager here so that private property + // access doesn't cause the above errors to occur. + + var m = manager; + var proxiedManager = { + class: m.class, + + create(props) { + return m.create(props); + } + + }; + return new Proxy(proxiedManager, validator); + } + + return manager; + } + + function isSingleton(container, fullName) { + return container.registry.getOption(fullName, 'singleton') !== false; + } + + function isInstantiatable(container, fullName) { + return container.registry.getOption(fullName, 'instantiate') !== false; + } + + function lookup(container, fullName, options = {}) { + var normalizedName = fullName; + + if (options.singleton !== false) { + var cached = container.cache[normalizedName]; + + if (cached !== undefined) { + return cached; + } + } + + return instantiateFactory(container, normalizedName, fullName, options); + } + + function factoryFor(container, normalizedName, fullName) { + var cached = container.factoryManagerCache[normalizedName]; + + if (cached !== undefined) { + return cached; + } + + var factory = container.registry.resolve(normalizedName); + + if (factory === undefined) { + return; + } + + if (true + /* DEBUG */ + && factory && typeof factory._onLookup === 'function') { + factory._onLookup(fullName); + } + + var manager = new FactoryManager(container, factory, fullName, normalizedName); + + if (true + /* DEBUG */ + ) { + manager = wrapManagerInDeprecationProxy(manager); + } + + container.factoryManagerCache[normalizedName] = manager; + return manager; + } + + function isSingletonClass(container, fullName, { + instantiate, + singleton + }) { + return singleton !== false && !instantiate && isSingleton(container, fullName) && !isInstantiatable(container, fullName); + } + + function isSingletonInstance(container, fullName, { + instantiate, + singleton + }) { + return singleton !== false && instantiate !== false && isSingleton(container, fullName) && isInstantiatable(container, fullName); + } + + function isFactoryClass(container, fullname, { + instantiate, + singleton + }) { + return instantiate === false && (singleton === false || !isSingleton(container, fullname)) && !isInstantiatable(container, fullname); + } + + function isFactoryInstance(container, fullName, { + instantiate, + singleton + }) { + return instantiate !== false && (singleton !== false || isSingleton(container, fullName)) && isInstantiatable(container, fullName); + } + + function instantiateFactory(container, normalizedName, fullName, options) { + var factoryManager = factoryFor(container, normalizedName, fullName); + + if (factoryManager === undefined) { + return; + } // SomeClass { singleton: true, instantiate: true } | { singleton: true } | { instantiate: true } | {} + // By default majority of objects fall into this case + + + if (isSingletonInstance(container, fullName, options)) { + var instance = container.cache[normalizedName] = factoryManager.create(); // if this lookup happened _during_ destruction (emits a deprecation, but + // is still possible) ensure that it gets destroyed + + if (container.isDestroying) { + if (typeof instance.destroy === 'function') { + instance.destroy(); + } + } + + return instance; + } // SomeClass { singleton: false, instantiate: true } + + + if (isFactoryInstance(container, fullName, options)) { + return factoryManager.create(); + } // SomeClass { singleton: true, instantiate: false } | { instantiate: false } | { singleton: false, instantiation: false } + + + if (isSingletonClass(container, fullName, options) || isFactoryClass(container, fullName, options)) { + return factoryManager.class; + } + + throw new Error('Could not create factory'); + } + + function processInjections(container, injections, result) { + if (true + /* DEBUG */ + ) { + container.registry.validateInjections(injections); + } + + var hash = result.injections; + + for (var i = 0; i < injections.length; i++) { + var { + property, + specifier + } = injections[i]; + hash[property] = lookup(container, specifier); + + if (!result.isDynamic) { + result.isDynamic = !isSingleton(container, specifier); + } + } + } + + function buildInjections(container, typeInjections, injections) { + var injectionsHash = {}; + (0, _owner.setOwner)(injectionsHash, container.owner); + var result = { + injections: injectionsHash, + isDynamic: false + }; + + if (typeInjections !== undefined) { + processInjections(container, typeInjections, result); + } + + if (injections !== undefined) { + processInjections(container, injections, result); + } + + return result; + } + + function injectionsFor(container, fullName) { + var registry = container.registry; + var [type] = fullName.split(':'); + var typeInjections = registry.getTypeInjections(type); + var injections = registry.getInjections(fullName); + return buildInjections(container, typeInjections, injections); + } + + function destroyDestroyables(container) { + var cache = container.cache; + var keys = Object.keys(cache); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = cache[key]; + + if (value.destroy) { + value.destroy(); + } + } + } + + function resetCache(container) { + container.cache = (0, _utils.dictionary)(null); + container.factoryManagerCache = (0, _utils.dictionary)(null); + } + + function resetMember(container, fullName) { + var member = container.cache[fullName]; + delete container.factoryManagerCache[fullName]; + + if (member) { + delete container.cache[fullName]; + + if (member.destroy) { + member.destroy(); + } + } + } + + var INIT_FACTORY = (0, _utils.symbol)('INIT_FACTORY'); + _exports.INIT_FACTORY = INIT_FACTORY; + + function getFactoryFor(obj) { + return obj[INIT_FACTORY]; + } + + function setFactoryFor(obj, factory) { + obj[INIT_FACTORY] = factory; + } + + class FactoryManager { + constructor(container, factory, fullName, normalizedName) { + this.container = container; + this.owner = container.owner; + this.class = factory; + this.fullName = fullName; + this.normalizedName = normalizedName; + this.madeToString = undefined; + this.injections = undefined; + setFactoryFor(this, this); + + if (factory && (_utils.HAS_NATIVE_SYMBOL || INIT_FACTORY in factory)) { + setFactoryFor(factory, this); + } + } + + toString() { + if (this.madeToString === undefined) { + this.madeToString = this.container.registry.makeToString(this.class, this.fullName); + } + + return this.madeToString; + } + + create(options) { + var { + container + } = this; + + if (container.isDestroyed) { + throw new Error(`Can not create new instances after the owner has been destroyed (you attempted to create ${this.fullName})`); + } + + var props = this.injections; + + if (props === undefined) { + var { + injections, + isDynamic + } = injectionsFor(this.container, this.normalizedName); + setFactoryFor(injections, this); + props = injections; + + if (!isDynamic) { + this.injections = injections; + } + } + + if (options !== undefined) { + props = (0, _polyfills.assign)({}, props, options); + } + + if (true + /* DEBUG */ + ) { + var lazyInjections; + var validationCache = this.container.validationCache; // Ensure that all lazy injections are valid at instantiation time + + if (!validationCache[this.fullName] && this.class && typeof this.class._lazyInjections === 'function') { + lazyInjections = this.class._lazyInjections(); + lazyInjections = this.container.registry.normalizeInjectionsHash(lazyInjections); + this.container.registry.validateInjections(lazyInjections); + } + + validationCache[this.fullName] = true; + (true && !(typeof this.class.create === 'function') && (0, _debug.assert)(`Failed to create an instance of '${this.normalizedName}'. Most likely an improperly defined class or an invalid module export.`, typeof this.class.create === 'function')); + } + + return this.class.create(props); + } + + } + + var VALID_FULL_NAME_REGEXP = /^[^:]+:[^:]+$/; + /** + A registry used to store factory and option information keyed + by type. + + A `Registry` stores the factory and option information needed by a + `Container` to instantiate and cache objects. + + The API for `Registry` is still in flux and should not be considered stable. + + @private + @class Registry + @since 1.11.0 + */ + + class Registry { + constructor(options = {}) { + this.fallback = options.fallback || null; + this.resolver = options.resolver || null; + this.registrations = (0, _utils.dictionary)(options.registrations || null); + this._typeInjections = (0, _utils.dictionary)(null); + this._injections = (0, _utils.dictionary)(null); + this._localLookupCache = Object.create(null); + this._normalizeCache = (0, _utils.dictionary)(null); + this._resolveCache = (0, _utils.dictionary)(null); + this._failSet = new Set(); + this._options = (0, _utils.dictionary)(null); + this._typeOptions = (0, _utils.dictionary)(null); + } + /** + A backup registry for resolving registrations when no matches can be found. + @private + @property fallback + @type Registry + */ + + /** + An object that has a `resolve` method that resolves a name. + @private + @property resolver + @type Resolver + */ + + /** + @private + @property registrations + @type InheritingDict + */ + + /** + @private + @property _typeInjections + @type InheritingDict + */ + + /** + @private + @property _injections + @type InheritingDict + */ + + /** + @private + @property _normalizeCache + @type InheritingDict + */ + + /** + @private + @property _resolveCache + @type InheritingDict + */ + + /** + @private + @property _options + @type InheritingDict + */ + + /** + @private + @property _typeOptions + @type InheritingDict + */ + + /** + Creates a container based on this registry. + @private + @method container + @param {Object} options + @return {Container} created container + */ + + + container(options) { + return new Container(this, options); + } + /** + Registers a factory for later injection. + Example: + ```javascript + let registry = new Registry(); + registry.register('model:user', Person, {singleton: false }); + registry.register('fruit:favorite', Orange); + registry.register('communication:main', Email, {singleton: false}); + ``` + @private + @method register + @param {String} fullName + @param {Function} factory + @param {Object} options + */ + + + register(fullName, factory, options = {}) { + (true && !(this.isValidFullName(fullName)) && (0, _debug.assert)('fullName must be a proper full name', this.isValidFullName(fullName))); + (true && !(factory !== undefined) && (0, _debug.assert)(`Attempting to register an unknown factory: '${fullName}'`, factory !== undefined)); + var normalizedName = this.normalize(fullName); + (true && !(!this._resolveCache[normalizedName]) && (0, _debug.assert)(`Cannot re-register: '${fullName}', as it has already been resolved.`, !this._resolveCache[normalizedName])); + + this._failSet.delete(normalizedName); + + this.registrations[normalizedName] = factory; + this._options[normalizedName] = options; + } + /** + Unregister a fullName + ```javascript + let registry = new Registry(); + registry.register('model:user', User); + registry.resolve('model:user').create() instanceof User //=> true + registry.unregister('model:user') + registry.resolve('model:user') === undefined //=> true + ``` + @private + @method unregister + @param {String} fullName + */ + + + unregister(fullName) { + (true && !(this.isValidFullName(fullName)) && (0, _debug.assert)('fullName must be a proper full name', this.isValidFullName(fullName))); + var normalizedName = this.normalize(fullName); + this._localLookupCache = Object.create(null); + delete this.registrations[normalizedName]; + delete this._resolveCache[normalizedName]; + delete this._options[normalizedName]; + + this._failSet.delete(normalizedName); + } + /** + Given a fullName return the corresponding factory. + By default `resolve` will retrieve the factory from + the registry. + ```javascript + let registry = new Registry(); + registry.register('api:twitter', Twitter); + registry.resolve('api:twitter') // => Twitter + ``` + Optionally the registry can be provided with a custom resolver. + If provided, `resolve` will first provide the custom resolver + the opportunity to resolve the fullName, otherwise it will fallback + to the registry. + ```javascript + let registry = new Registry(); + registry.resolver = function(fullName) { + // lookup via the module system of choice + }; + // the twitter factory is added to the module system + registry.resolve('api:twitter') // => Twitter + ``` + @private + @method resolve + @param {String} fullName + @param {Object} [options] + @param {String} [options.source] the fullname of the request source (used for local lookups) + @return {Function} fullName's factory + */ + + + resolve(fullName) { + var factory = resolve(this, this.normalize(fullName)); + + if (factory === undefined && this.fallback !== null) { + factory = this.fallback.resolve(...arguments); + } + + return factory; + } + /** + A hook that can be used to describe how the resolver will + attempt to find the factory. + For example, the default Ember `.describe` returns the full + class name (including namespace) where Ember's resolver expects + to find the `fullName`. + @private + @method describe + @param {String} fullName + @return {string} described fullName + */ + + + describe(fullName) { + if (this.resolver !== null && this.resolver.lookupDescription) { + return this.resolver.lookupDescription(fullName); + } else if (this.fallback !== null) { + return this.fallback.describe(fullName); + } else { + return fullName; + } + } + /** + A hook to enable custom fullName normalization behavior + @private + @method normalizeFullName + @param {String} fullName + @return {string} normalized fullName + */ + + + normalizeFullName(fullName) { + if (this.resolver !== null && this.resolver.normalize) { + return this.resolver.normalize(fullName); + } else if (this.fallback !== null) { + return this.fallback.normalizeFullName(fullName); + } else { + return fullName; + } + } + /** + Normalize a fullName based on the application's conventions + @private + @method normalize + @param {String} fullName + @return {string} normalized fullName + */ + + + normalize(fullName) { + return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this.normalizeFullName(fullName)); + } + /** + @method makeToString + @private + @param {any} factory + @param {string} fullName + @return {function} toString function + */ + + + makeToString(factory, fullName) { + var _a; + + if (this.resolver !== null && this.resolver.makeToString) { + return this.resolver.makeToString(factory, fullName); + } else if (this.fallback !== null) { + return this.fallback.makeToString(factory, fullName); + } else { + return typeof factory === 'string' ? factory : (_a = factory.name) !== null && _a !== void 0 ? _a : '(unknown class)'; + } + } + /** + Given a fullName check if the container is aware of its factory + or singleton instance. + @private + @method has + @param {String} fullName + @param {Object} [options] + @param {String} [options.source] the fullname of the request source (used for local lookups) + @return {Boolean} + */ + + + has(fullName) { + if (!this.isValidFullName(fullName)) { + return false; + } + + return has(this, this.normalize(fullName)); + } + /** + Allow registering options for all factories of a type. + ```javascript + let registry = new Registry(); + let container = registry.container(); + // if all of type `connection` must not be singletons + registry.optionsForType('connection', { singleton: false }); + registry.register('connection:twitter', TwitterConnection); + registry.register('connection:facebook', FacebookConnection); + let twitter = container.lookup('connection:twitter'); + let twitter2 = container.lookup('connection:twitter'); + twitter === twitter2; // => false + let facebook = container.lookup('connection:facebook'); + let facebook2 = container.lookup('connection:facebook'); + facebook === facebook2; // => false + ``` + @private + @method optionsForType + @param {String} type + @param {Object} options + */ + + + optionsForType(type, options) { + this._typeOptions[type] = options; + } + + getOptionsForType(type) { + var optionsForType = this._typeOptions[type]; + + if (optionsForType === undefined && this.fallback !== null) { + optionsForType = this.fallback.getOptionsForType(type); + } + + return optionsForType; + } + /** + @private + @method options + @param {String} fullName + @param {Object} options + */ + + + options(fullName, options) { + var normalizedName = this.normalize(fullName); + this._options[normalizedName] = options; + } + + getOptions(fullName) { + var normalizedName = this.normalize(fullName); + var options = this._options[normalizedName]; + + if (options === undefined && this.fallback !== null) { + options = this.fallback.getOptions(fullName); + } + + return options; + } + + getOption(fullName, optionName) { + var options = this._options[fullName]; + + if (options !== undefined && options[optionName] !== undefined) { + return options[optionName]; + } + + var type = fullName.split(':')[0]; + options = this._typeOptions[type]; + + if (options && options[optionName] !== undefined) { + return options[optionName]; + } else if (this.fallback !== null) { + return this.fallback.getOption(fullName, optionName); + } + + return undefined; + } + /** + Used only via `injection`. + Provides a specialized form of injection, specifically enabling + all objects of one type to be injected with a reference to another + object. + For example, provided each object of type `controller` needed a `router`. + one would do the following: + ```javascript + let registry = new Registry(); + let container = registry.container(); + registry.register('router:main', Router); + registry.register('controller:user', UserController); + registry.register('controller:post', PostController); + registry.typeInjection('controller', 'router', 'router:main'); + let user = container.lookup('controller:user'); + let post = container.lookup('controller:post'); + user.router instanceof Router; //=> true + post.router instanceof Router; //=> true + // both controllers share the same router + user.router === post.router; //=> true + ``` + @private + @method typeInjection + @param {String} type + @param {String} property + @param {String} fullName + */ + + + typeInjection(type, property, fullName) { + (true && !(this.isValidFullName(fullName)) && (0, _debug.assert)('fullName must be a proper full name', this.isValidFullName(fullName))); + var fullNameType = fullName.split(':')[0]; + (true && !(fullNameType !== type) && (0, _debug.assert)(`Cannot inject a '${fullName}' on other ${type}(s).`, fullNameType !== type)); + var injections = this._typeInjections[type] || (this._typeInjections[type] = []); + injections.push({ + property, + specifier: fullName + }); + } + /** + Defines injection rules. + These rules are used to inject dependencies onto objects when they + are instantiated. + Two forms of injections are possible: + * Injecting one fullName on another fullName + * Injecting one fullName on a type + Example: + ```javascript + let registry = new Registry(); + let container = registry.container(); + registry.register('source:main', Source); + registry.register('model:user', User); + registry.register('model:post', Post); + // injecting one fullName on another fullName + // eg. each user model gets a post model + registry.injection('model:user', 'post', 'model:post'); + // injecting one fullName on another type + registry.injection('model', 'source', 'source:main'); + let user = container.lookup('model:user'); + let post = container.lookup('model:post'); + user.source instanceof Source; //=> true + post.source instanceof Source; //=> true + user.post instanceof Post; //=> true + // and both models share the same source + user.source === post.source; //=> true + ``` + @private + @method injection + @param {String} factoryName + @param {String} property + @param {String} injectionName + */ + + + injection(fullName, property, injectionName) { + (true && !(this.isValidFullName(injectionName)) && (0, _debug.assert)(`Invalid injectionName, expected: 'type:name' got: ${injectionName}`, this.isValidFullName(injectionName))); + var normalizedInjectionName = this.normalize(injectionName); + + if (fullName.indexOf(':') === -1) { + return this.typeInjection(fullName, property, normalizedInjectionName); + } + + (true && !(this.isValidFullName(fullName)) && (0, _debug.assert)('fullName must be a proper full name', this.isValidFullName(fullName))); + var normalizedName = this.normalize(fullName); + var injections = this._injections[normalizedName] || (this._injections[normalizedName] = []); + injections.push({ + property, + specifier: normalizedInjectionName + }); + } + /** + @private + @method knownForType + @param {String} type the type to iterate over + */ + + + knownForType(type) { + var localKnown = (0, _utils.dictionary)(null); + var registeredNames = Object.keys(this.registrations); + + for (var index = 0; index < registeredNames.length; index++) { + var fullName = registeredNames[index]; + var itemType = fullName.split(':')[0]; + + if (itemType === type) { + localKnown[fullName] = true; + } + } + + var fallbackKnown, resolverKnown; + + if (this.fallback !== null) { + fallbackKnown = this.fallback.knownForType(type); + } + + if (this.resolver !== null && this.resolver.knownForType) { + resolverKnown = this.resolver.knownForType(type); + } + + return (0, _polyfills.assign)({}, fallbackKnown, localKnown, resolverKnown); + } + + isValidFullName(fullName) { + return VALID_FULL_NAME_REGEXP.test(fullName); + } + + getInjections(fullName) { + var injections = this._injections[fullName]; + + if (this.fallback !== null) { + var fallbackInjections = this.fallback.getInjections(fullName); + + if (fallbackInjections !== undefined) { + injections = injections === undefined ? fallbackInjections : injections.concat(fallbackInjections); + } + } + + return injections; + } + + getTypeInjections(type) { + var injections = this._typeInjections[type]; + + if (this.fallback !== null) { + var fallbackInjections = this.fallback.getTypeInjections(type); + + if (fallbackInjections !== undefined) { + injections = injections === undefined ? fallbackInjections : injections.concat(fallbackInjections); + } + } + + return injections; + } + + } + + _exports.Registry = Registry; + + if (true + /* DEBUG */ + ) { + var proto = Registry.prototype; + + proto.normalizeInjectionsHash = function (hash) { + var injections = []; + + for (var key in hash) { + if (Object.prototype.hasOwnProperty.call(hash, key)) { + var { + specifier + } = hash[key]; + (true && !(this.isValidFullName(specifier)) && (0, _debug.assert)(`Expected a proper full name, given '${specifier}'`, this.isValidFullName(specifier))); + injections.push({ + property: key, + specifier + }); + } + } + + return injections; + }; + + proto.validateInjections = function (injections) { + if (!injections) { + return; + } + + for (var i = 0; i < injections.length; i++) { + var { + specifier + } = injections[i]; + (true && !(this.has(specifier)) && (0, _debug.assert)(`Attempting to inject an unknown injection: '${specifier}'`, this.has(specifier))); + } + }; + } + + function resolve(registry, _normalizedName) { + var normalizedName = _normalizedName; + var cached = registry._resolveCache[normalizedName]; + + if (cached !== undefined) { + return cached; + } + + if (registry._failSet.has(normalizedName)) { + return; + } + + var resolved; + + if (registry.resolver) { + resolved = registry.resolver.resolve(normalizedName); + } + + if (resolved === undefined) { + resolved = registry.registrations[normalizedName]; + } + + if (resolved === undefined) { + registry._failSet.add(normalizedName); + } else { + registry._resolveCache[normalizedName] = resolved; + } + + return resolved; + } + + function has(registry, fullName) { + return registry.resolve(fullName) !== undefined; + } + + var privateNames = (0, _utils.dictionary)(null); + var privateSuffix = `${Math.random()}${Date.now()}`.replace('.', ''); + + function privatize([fullName]) { + var name = privateNames[fullName]; + + if (name) { + return name; + } + + var [type, rawName] = fullName.split(':'); + return privateNames[fullName] = (0, _utils.intern)(`${type}:${rawName}-${privateSuffix}`); + } + /* + Public API for the container is still in flux. + The public API, specified on the application namespace should be considered the stable API. + // @module container + @private + */ + +}); +define("@ember/-internals/environment/index", ["exports", "@ember/deprecated-features"], function (_exports, _deprecatedFeatures) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.getLookup = getLookup; + _exports.setLookup = setLookup; + _exports.getENV = getENV; + _exports.ENV = _exports.context = _exports.global = void 0; + + // from lodash to catch fake globals + function checkGlobal(value) { + return value && value.Object === Object ? value : undefined; + } // element ids can ruin global miss checks + + + function checkElementIdShadowing(value) { + return value && value.nodeType === undefined ? value : undefined; + } // export real global + + + var global$1 = checkGlobal(checkElementIdShadowing(typeof global === 'object' && global)) || checkGlobal(typeof self === 'object' && self) || checkGlobal(typeof window === 'object' && window) || typeof mainContext !== 'undefined' && mainContext || // set before strict mode in Ember loader/wrapper + new Function('return this')(); // eval outside of strict mode + + _exports.global = global$1; + + var context = function (global, Ember) { + return Ember === undefined ? { + imports: global, + exports: global, + lookup: global + } : { + // import jQuery + imports: Ember.imports || global, + // export Ember + exports: Ember.exports || global, + // search for Namespaces + lookup: Ember.lookup || global + }; + }(global$1, global$1.Ember); + + _exports.context = context; + + function getLookup() { + return context.lookup; + } + + function setLookup(value) { + context.lookup = value; + } + /** + The hash of environment variables used to control various configuration + settings. To specify your own or override default settings, add the + desired properties to a global hash named `EmberENV` (or `ENV` for + backwards compatibility with earlier versions of Ember). The `EmberENV` + hash must be created before loading Ember. + + @class EmberENV + @type Object + @public + */ + + + var ENV = { + ENABLE_OPTIONAL_FEATURES: false, + + /** + Determines whether Ember should add to `Array`, `Function`, and `String` + native object prototypes, a few extra methods in order to provide a more + friendly API. + We generally recommend leaving this option set to true however, if you need + to turn it off, you can add the configuration property + `EXTEND_PROTOTYPES` to `EmberENV` and set it to `false`. + Note, when disabled (the default configuration for Ember Addons), you will + instead have to access all methods and functions from the Ember + namespace. + @property EXTEND_PROTOTYPES + @type Boolean + @default true + @for EmberENV + @public + */ + EXTEND_PROTOTYPES: { + Array: true, + Function: true, + String: true + }, + + /** + The `LOG_STACKTRACE_ON_DEPRECATION` property, when true, tells Ember to log + a full stack trace during deprecation warnings. + @property LOG_STACKTRACE_ON_DEPRECATION + @type Boolean + @default true + @for EmberENV + @public + */ + LOG_STACKTRACE_ON_DEPRECATION: true, + + /** + The `LOG_VERSION` property, when true, tells Ember to log versions of all + dependent libraries in use. + @property LOG_VERSION + @type Boolean + @default true + @for EmberENV + @public + */ + LOG_VERSION: true, + RAISE_ON_DEPRECATION: false, + STRUCTURED_PROFILE: false, + + /** + Whether to insert a `
` wrapper around the + application template. See RFC #280. + This is not intended to be set directly, as the implementation may change in + the future. Use `@ember/optional-features` instead. + @property _APPLICATION_TEMPLATE_WRAPPER + @for EmberENV + @type Boolean + @default true + @private + */ + _APPLICATION_TEMPLATE_WRAPPER: true, + + /** + Whether to use Glimmer Component semantics (as opposed to the classic "Curly" + components semantics) for template-only components. See RFC #278. + This is not intended to be set directly, as the implementation may change in + the future. Use `@ember/optional-features` instead. + @property _TEMPLATE_ONLY_GLIMMER_COMPONENTS + @for EmberENV + @type Boolean + @default false + @private + */ + _TEMPLATE_ONLY_GLIMMER_COMPONENTS: false, + + /** + Whether to perform extra bookkeeping needed to make the `captureRenderTree` + API work. + This has to be set before the ember JavaScript code is evaluated. This is + usually done by setting `window.EmberENV = { _DEBUG_RENDER_TREE: true };` + before the "vendor" `'; + }; + + return EventedTokenizer; + }(); + + _exports.EventedTokenizer = EventedTokenizer; + + var Tokenizer = + /** @class */ + function () { + function Tokenizer(entityParser, options) { + if (options === void 0) { + options = {}; + } + + this.options = options; + this.token = null; + this.startLine = 1; + this.startColumn = 0; + this.tokens = []; + this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); + this._currentAttribute = undefined; + } + + Tokenizer.prototype.tokenize = function (input) { + this.tokens = []; + this.tokenizer.tokenize(input); + return this.tokens; + }; + + Tokenizer.prototype.tokenizePart = function (input) { + this.tokens = []; + this.tokenizer.tokenizePart(input); + return this.tokens; + }; + + Tokenizer.prototype.tokenizeEOF = function () { + this.tokens = []; + this.tokenizer.tokenizeEOF(); + return this.tokens[0]; + }; + + Tokenizer.prototype.reset = function () { + this.token = null; + this.startLine = 1; + this.startColumn = 0; + }; + + Tokenizer.prototype.current = function () { + var token = this.token; + + if (token === null) { + throw new Error('token was unexpectedly null'); + } + + if (arguments.length === 0) { + return token; + } + + for (var i = 0; i < arguments.length; i++) { + if (token.type === arguments[i]) { + return token; + } + } + + throw new Error("token type was unexpectedly " + token.type); + }; + + Tokenizer.prototype.push = function (token) { + this.token = token; + this.tokens.push(token); + }; + + Tokenizer.prototype.currentAttribute = function () { + return this._currentAttribute; + }; + + Tokenizer.prototype.addLocInfo = function () { + if (this.options.loc) { + this.current().loc = { + start: { + line: this.startLine, + column: this.startColumn + }, + end: { + line: this.tokenizer.line, + column: this.tokenizer.column + } + }; + } + + this.startLine = this.tokenizer.line; + this.startColumn = this.tokenizer.column; + }; // Data + + + Tokenizer.prototype.beginData = function () { + this.push({ + type: "Chars" + /* Chars */ + , + chars: '' + }); + }; + + Tokenizer.prototype.appendToData = function (char) { + this.current("Chars" + /* Chars */ + ).chars += char; + }; + + Tokenizer.prototype.finishData = function () { + this.addLocInfo(); + }; // Comment + + + Tokenizer.prototype.beginComment = function () { + this.push({ + type: "Comment" + /* Comment */ + , + chars: '' + }); + }; + + Tokenizer.prototype.appendToCommentData = function (char) { + this.current("Comment" + /* Comment */ + ).chars += char; + }; + + Tokenizer.prototype.finishComment = function () { + this.addLocInfo(); + }; // Tags - basic + + + Tokenizer.prototype.tagOpen = function () {}; + + Tokenizer.prototype.beginStartTag = function () { + this.push({ + type: "StartTag" + /* StartTag */ + , + tagName: '', + attributes: [], + selfClosing: false + }); + }; + + Tokenizer.prototype.beginEndTag = function () { + this.push({ + type: "EndTag" + /* EndTag */ + , + tagName: '' + }); + }; + + Tokenizer.prototype.finishTag = function () { + this.addLocInfo(); + }; + + Tokenizer.prototype.markTagAsSelfClosing = function () { + this.current("StartTag" + /* StartTag */ + ).selfClosing = true; + }; // Tags - name + + + Tokenizer.prototype.appendToTagName = function (char) { + this.current("StartTag" + /* StartTag */ + , "EndTag" + /* EndTag */ + ).tagName += char; + }; // Tags - attributes + + + Tokenizer.prototype.beginAttribute = function () { + this._currentAttribute = ['', '', false]; + }; + + Tokenizer.prototype.appendToAttributeName = function (char) { + this.currentAttribute()[0] += char; + }; + + Tokenizer.prototype.beginAttributeValue = function (isQuoted) { + this.currentAttribute()[2] = isQuoted; + }; + + Tokenizer.prototype.appendToAttributeValue = function (char) { + this.currentAttribute()[1] += char; + }; + + Tokenizer.prototype.finishAttributeValue = function () { + this.current("StartTag" + /* StartTag */ + ).attributes.push(this._currentAttribute); + }; + + Tokenizer.prototype.reportSyntaxError = function (message) { + this.current().syntaxError = message; + }; + + return Tokenizer; + }(); + + _exports.Tokenizer = Tokenizer; + + function tokenize(input, options) { + var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); + return tokenizer.tokenize(input); + } +}); +(function (m) { if (typeof module === "object" && module.exports) { module.exports = m } }(require("ember-template-compiler"))); +}()); + +;define("@ember/test-waiters/build-waiter", ["exports", "@ember/debug", "@ember/test-waiters/token", "@ember/test-waiters/waiter-manager"], function (_exports, _debug, _token, _waiterManager) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports._resetWaiterNames = _resetWaiterNames; + _exports.default = buildWaiter; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + const WAITER_NAME_PATTERN = /^[^:]*:?.*/; + let WAITER_NAMES = true + /* DEBUG */ + ? new Set() : undefined; + + function _resetWaiterNames() { + WAITER_NAMES = new Set(); + } + + function getNextToken() { + return new _token.default(); + } + + class TestWaiterImpl { + constructor(name, nextToken) { + _defineProperty(this, "isRegistered", false); + + _defineProperty(this, "items", new Map()); + + _defineProperty(this, "completedOperationsForTokens", new WeakMap()); + + _defineProperty(this, "completedOperationsForPrimitives", new Map()); + + this.name = name; // @ts-ignore + + this.nextToken = nextToken || getNextToken; + } + + beginAsync(token = this.nextToken(), label) { + this._register(); + + if (this.items.has(token)) { + throw new Error(`beginAsync called for ${token} but it is already pending.`); + } + + let error = new Error(); + this.items.set(token, { + get stack() { + return error.stack; + }, + + label + }); + return token; + } + + endAsync(token) { + if (!this.items.has(token) && !this._getCompletedOperations(token).has(token)) { + throw new Error(`endAsync called with no preceding beginAsync call.`); + } + + this.items.delete(token); // Mark when a waiter operation has completed so we can distinguish + // whether endAsync is being called before a prior beginAsync call above. + + this._getCompletedOperations(token).set(token, true); + } + + waitUntil() { + return this.items.size === 0; + } + + debugInfo() { + let result = []; + this.items.forEach(value => { + result.push(value); + }); + return result; + } + + reset() { + this.items.clear(); + } + + _register() { + if (!this.isRegistered) { + (0, _waiterManager.register)(this); + this.isRegistered = true; + } + } + + _getCompletedOperations(token) { + let type = typeof token; + let isFunction = type === 'function'; + let isObject = token !== null && type === 'object'; + let isPrimitive = !isFunction && !isObject; + return isPrimitive ? this.completedOperationsForPrimitives : this.completedOperationsForTokens; + } + + } + + class NoopTestWaiter { + constructor(name) { + this.name = name; + } + + beginAsync() { + return this; + } + + endAsync() {} + + waitUntil() { + return true; + } + + debugInfo() { + return []; + } + + reset() {} + + } + /** + * Builds and returns a test waiter. The type of the + * returned waiter is dependent on whether the app or + * addon is in `DEBUG` mode or not. + * + * @public + * + * @param name {string} The name of the test waiter + * @returns {TestWaiter} + * + * @example + * + * import Component from '@ember/component'; + * import { buildWaiter } from '@ember/test-waiters'; + * + * if (DEBUG) { + * let waiter = buildWaiter('friend-waiter'); + * } + * + * export default class Friendz extends Component { + * didInsertElement() { + * let token = waiter.beginAsync(this); + * + * someAsyncWork().then(() => { + * waiter.endAsync(token); + * }); + * } + * } + */ + + + function buildWaiter(name) { + if (true + /* DEBUG */ + ) { + (true && (0, _debug.warn)(`The waiter name '${name}' is already in use`, !WAITER_NAMES.has(name), { + id: '@ember/test-waiters.duplicate-waiter-name' + })); + WAITER_NAMES.add(name); + } + + if (!true + /* DEBUG */ + ) { + return new NoopTestWaiter(name); + } + + (true && (0, _debug.warn)(`You must provide a name that contains a descriptive prefix separated by a colon. + + Example: ember-fictitious-addon:some-file + + You passed: ${name}`, WAITER_NAME_PATTERN.test(name), { + id: '@ember/test-waiters.invalid-waiter-name' + })); + return new TestWaiterImpl(name); + } +}); +;define("@ember/test-waiters/index", ["exports", "@ember/test-waiters/waiter-manager", "@ember/test-waiters/build-waiter", "@ember/test-waiters/wait-for-promise", "@ember/test-waiters/wait-for"], function (_exports, _waiterManager, _buildWaiter, _waitForPromise, _waitFor) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "register", { + enumerable: true, + get: function () { + return _waiterManager.register; + } + }); + Object.defineProperty(_exports, "unregister", { + enumerable: true, + get: function () { + return _waiterManager.unregister; + } + }); + Object.defineProperty(_exports, "getWaiters", { + enumerable: true, + get: function () { + return _waiterManager.getWaiters; + } + }); + Object.defineProperty(_exports, "_reset", { + enumerable: true, + get: function () { + return _waiterManager._reset; + } + }); + Object.defineProperty(_exports, "getPendingWaiterState", { + enumerable: true, + get: function () { + return _waiterManager.getPendingWaiterState; + } + }); + Object.defineProperty(_exports, "hasPendingWaiters", { + enumerable: true, + get: function () { + return _waiterManager.hasPendingWaiters; + } + }); + Object.defineProperty(_exports, "buildWaiter", { + enumerable: true, + get: function () { + return _buildWaiter.default; + } + }); + Object.defineProperty(_exports, "_resetWaiterNames", { + enumerable: true, + get: function () { + return _buildWaiter._resetWaiterNames; + } + }); + Object.defineProperty(_exports, "waitForPromise", { + enumerable: true, + get: function () { + return _waitForPromise.default; + } + }); + Object.defineProperty(_exports, "waitFor", { + enumerable: true, + get: function () { + return _waitFor.default; + } + }); +}); +;define("@ember/test-waiters/token", ["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + + /** + * A class representing a test waiter token. + * + * @public + * @class + */ + class Token {} + + _exports.default = Token; +}); +;define("@ember/test-waiters/types/index", ["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); +}); +;define("@ember/test-waiters/wait-for-promise", ["exports", "@ember/test-waiters/build-waiter"], function (_exports, _buildWaiter) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = waitForPromise; + const PROMISE_WAITER = (0, _buildWaiter.default)('@ember/test-waiters:promise-waiter'); + /** + * A convenient utility function to simplify waiting for a promise. + * + * @public + * @param promise {Promise | RSVP.Promise} The promise to track async operations for + * @param label {string} An optional string to identify the promise + * + * @example + * + * import Component from '@ember/component'; + * import { waitForPromise } from '@ember/test-waiters'; + * + * export default class Friendz extends Component { + * didInsertElement() { + * waitForPromise(new Promise(resolve => { + * doSomeWork(); + * resolve(); + * })); + * } + * } + */ + + function waitForPromise(promise, label) { + let result = promise; + + if (true + /* DEBUG */ + ) { + PROMISE_WAITER.beginAsync(promise, label); + result = promise.then(value => { + PROMISE_WAITER.endAsync(promise); + return value; + }, error => { + PROMISE_WAITER.endAsync(promise); + throw error; + }); + } + + return result; + } +}); +;define("@ember/test-waiters/wait-for", ["exports", "@ember/test-waiters/wait-for-promise", "@ember/test-waiters/build-waiter"], function (_exports, _waitForPromise, _buildWaiter) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = waitFor; + + function waitFor(...args) { + let isFunction = args.length < 3; + + if (isFunction) { + let [fn, label] = args; + return wrapFunction(fn, label); + } else { + let [,, descriptor, label] = args; + + if (!true + /* DEBUG */ + ) { + return descriptor; + } + + let fn = descriptor.value; + descriptor.value = wrapFunction(fn, label); + return descriptor; + } + } + + function wrapFunction(fn, label) { + if (!true + /* DEBUG */ + ) { + return fn; + } + + return function (...args) { + let result = fn.call(this, ...args); + + if (isThenable(result)) { + return (0, _waitForPromise.default)(result, label); + } else if (isGenerator(result)) { + return waitForGenerator(result, label); + } else { + return result; + } + }; + } + + function isThenable(maybePromise) { + let type = typeof maybePromise; + return (maybePromise !== null && type === 'object' || type === 'function') && typeof maybePromise.then === 'function'; + } + + function isGenerator(maybeGenerator) { + // Because we don't have Symbol.iterator in IE11 + return typeof maybeGenerator.next === 'function' && typeof maybeGenerator.return === 'function' && typeof maybeGenerator.throw === 'function'; + } + + const GENERATOR_WAITER = (0, _buildWaiter.default)('@ember/test-waiters:generator-waiter'); + + function waitForGenerator(generator, label) { + GENERATOR_WAITER.beginAsync(generator, label); + let isWaiting = true; + + function stopWaiting() { + if (isWaiting) { + GENERATOR_WAITER.endAsync(generator); + isWaiting = false; + } + } + + return { + next(...args) { + let hasErrored = true; + + try { + let val = generator.next(...args); + hasErrored = false; + + if (val.done) { + stopWaiting(); + } + + return val; + } finally { + // If generator.next() throws, we need to stop waiting. But if we catch + // and re-throw exceptions, it could move the location from which the + // uncaught exception is thrown, interfering with the developer + // debugging experience if they have break-on-exceptions enabled. So we + // use a boolean flag and a finally block to emulate a catch block. + if (hasErrored) { + stopWaiting(); + } + } + }, + + return(...args) { + stopWaiting(); + return generator.return(...args); + }, + + throw(...args) { + stopWaiting(); + return generator.throw(...args); + } + + }; + } +}); +;define("@ember/test-waiters/waiter-manager", ["exports", "ember", "@ember/test"], function (_exports, _ember, _test) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.register = register; + _exports.unregister = unregister; + _exports.getWaiters = getWaiters; + _exports._reset = _reset; + _exports.getPendingWaiterState = getPendingWaiterState; + _exports.hasPendingWaiters = hasPendingWaiters; + const WAITERS = new Map(); + /** + * Backwards compatibility with legacy waiters system. + * + * We want to always register a waiter using the legacy waiter system, as right + * now if consumers are not on the right version of @ember/test-helpers, using + * this addon will result in none of these waiters waiting. + */ + // eslint-disable-next-line ember/new-module-imports + + if (_ember.default.Test) { + (0, _test.registerWaiter)(() => !hasPendingWaiters()); + } + /** + * Registers a waiter. + * + * @public + * @param waiter {Waiter} A test waiter instance + */ + + + function register(waiter) { + WAITERS.set(waiter.name, waiter); + } + /** + * Un-registers a waiter. + * + * @public + * @param waiter {Waiter} A test waiter instance + */ + + + function unregister(waiter) { + WAITERS.delete(waiter.name); + } + /** + * Gets an array of all waiters current registered. + * + * @public + * @returns {Waiter[]} + */ + + + function getWaiters() { + let result = []; + WAITERS.forEach(value => { + result.push(value); + }); + return result; + } + /** + * Clears all waiters. + * + * @private + */ + + + function _reset() { + for (let waiter of getWaiters()) { + waiter.isRegistered = false; + } + + WAITERS.clear(); + } + /** + * Gets the current state of all waiters. Any waiters whose + * `waitUntil` method returns false will be considered `pending`. + * + * @returns {PendingWaiterState} An object containing a count of all waiters + * pending and a `waiters` object containing the name of all pending waiters + * and their debug info. + */ + + + function getPendingWaiterState() { + let result = { + pending: 0, + waiters: {} + }; + WAITERS.forEach(waiter => { + if (!waiter.waitUntil()) { + result.pending++; + let debugInfo = waiter.debugInfo(); + result.waiters[waiter.name] = debugInfo || true; + } + }); + return result; + } + /** + * Determines if there are any pending waiters. + * + * @returns {boolean} `true` if there are pending waiters, otherwise `false`. + */ + + + function hasPendingWaiters() { + let state = getPendingWaiterState(); + return state.pending > 0; + } +}); +;define("@glimmer/component/-private/base-component-manager", ["exports", "@glimmer/component/-private/component"], function (_exports, _component) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = BaseComponentManager; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + /** + * This factory function returns a component manager class with common behavior + * that can be extend to add Glimmer.js- or Ember.js-specific functionality. As + * these environments converge, the need for two component manager + * implementations (and thus this factory) should go away. + */ + function BaseComponentManager(setOwner, getOwner, capabilities) { + return class { + static create(attrs) { + let owner = getOwner(attrs); + return new this(owner); + } + + constructor(owner) { + _defineProperty(this, "capabilities", capabilities); + + setOwner(this, owner); + } + + createComponent(ComponentClass, args) { + if (true + /* DEBUG */ + ) { + _component.ARGS_SET.set(args.named, true); + } + + return new ComponentClass(getOwner(this), args.named); + } + + getContext(component) { + return component; + } + + }; + } +}); +;define("@glimmer/component/-private/component", ["exports", "@glimmer/component/-private/owner", "@glimmer/component/-private/destroyables"], function (_exports, _owner, _destroyables) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = _exports.ARGS_SET = void 0; + + function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + let ARGS_SET; + _exports.ARGS_SET = ARGS_SET; + + if (true + /* DEBUG */ + ) { + _exports.ARGS_SET = ARGS_SET = new WeakMap(); + } + /** + * The `Component` class defines an encapsulated UI element that is rendered to + * the DOM. A component is made up of a template and, optionally, this component + * object. + * + * ## Defining a Component + * + * To define a component, subclass `Component` and add your own properties, + * methods and lifecycle hooks: + * + * ```ts + * import Component from '@glimmer/component'; + * + * export default class extends Component { + * } + * ``` + * + * ## Lifecycle Hooks + * + * Lifecycle hooks allow you to respond to changes to a component, such as when + * it gets created, rendered, updated or destroyed. To add a lifecycle hook to a + * component, implement the hook as a method on your component subclass. + * + * For example, to be notified when Glimmer has rendered your component so you + * can attach a legacy jQuery plugin, implement the `didInsertElement()` method: + * + * ```ts + * import Component from '@glimmer/component'; + * + * export default class extends Component { + * didInsertElement() { + * $(this.element).pickadate(); + * } + * } + * ``` + * + * ## Data for Templates + * + * `Component`s have two different kinds of data, or state, that can be + * displayed in templates: + * + * 1. Arguments + * 2. Properties + * + * Arguments are data that is passed in to a component from its parent + * component. For example, if I have a `UserGreeting` component, I can pass it + * a name and greeting to use: + * + * ```hbs + * + * ``` + * + * Inside my `UserGreeting` template, I can access the `@name` and `@greeting` + * arguments that I've been given: + * + * ```hbs + * {{@greeting}}, {{@name}}! + * ``` + * + * Arguments are also available inside my component: + * + * ```ts + * console.log(this.args.greeting); // prints "Olá" + * ``` + * + * Properties, on the other hand, are internal to the component and declared in + * the class. You can use properties to store data that you want to show in the + * template, or pass to another component as an argument. + * + * ```ts + * import Component from '@glimmer/component'; + * + * export default class extends Component { + * user = { + * name: 'Robbie' + * } + * } + * ``` + * + * In the above example, we've defined a component with a `user` property that + * contains an object with its own `name` property. + * + * We can render that property in our template: + * + * ```hbs + * Hello, {{user.name}}! + * ``` + * + * We can also take that property and pass it as an argument to the + * `UserGreeting` component we defined above: + * + * ```hbs + * + * ``` + * + * ## Arguments vs. Properties + * + * Remember, arguments are data that was given to your component by its parent + * component, and properties are data your component has defined for itself. + * + * You can tell the difference between arguments and properties in templates + * because arguments always start with an `@` sign (think "A is for arguments"): + * + * ```hbs + * {{@firstName}} + * ``` + * + * We know that `@firstName` came from the parent component, not the current + * component, because it starts with `@` and is therefore an argument. + * + * On the other hand, if we see: + * + * ```hbs + * {{name}} + * ``` + * + * We know that `name` is a property on the component. If we want to know where + * the data is coming from, we can go look at our component class to find out. + * + * Inside the component itself, arguments always show up inside the component's + * `args` property. For example, if `{{@firstName}}` is `Tom` in the template, + * inside the component `this.args.firstName` would also be `Tom`. + */ + + + class BaseComponent { + /** + * Constructs a new component and assigns itself the passed properties. You + * should not construct new components yourself. Instead, Glimmer will + * instantiate new components automatically as it renders. + * + * @param owner + * @param args + */ + constructor(owner, args) { + _defineProperty(this, "args", void 0); + + if (true + /* DEBUG */ + && !(owner !== null && typeof owner === 'object' && ARGS_SET.has(args))) { + throw new Error(`You must pass both the owner and args to super() in your component: ${this.constructor.name}. You can pass them directly, or use ...arguments to pass all arguments through.`); + } + + this.args = args; + (0, _owner.setOwner)(this, owner); + } + /** + * Named arguments passed to the component from its parent component. + * They can be accessed in JavaScript via `this.args.argumentName` and in the template via `@argumentName`. + * + * Say you have the following component, which will have two `args`, `firstName` and `lastName`: + * + * ```hbs + * + * ``` + * + * If you needed to calculate `fullName` by combining both of them, you would do: + * + * ```ts + * didInsertElement() { + * console.log(`Hi, my full name is ${this.args.firstName} ${this.args.lastName}`); + * } + * ``` + * + * While in the template you could do: + * + * ```hbs + *

Welcome, {{@firstName}} {{@lastName}}!

+ * ``` + */ + + + get isDestroying() { + return (0, _destroyables.isDestroying)(this); + } + + get isDestroyed() { + return (0, _destroyables.isDestroyed)(this); + } + /** + * Called before the component has been removed from the DOM. + */ + + + willDestroy() {} + + } + + _exports.default = BaseComponent; +}); +;define("@glimmer/component/-private/destroyables", ["exports", "ember"], function (_exports, _ember) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.isDestroyed = _exports.isDestroying = void 0; + const isDestroying = _ember.default._isDestroying; + _exports.isDestroying = isDestroying; + const isDestroyed = _ember.default._isDestroyed; + _exports.isDestroyed = isDestroyed; +}); +;define("@glimmer/component/-private/ember-component-manager", ["exports", "ember", "@ember/object", "@ember/application", "@ember/component", "@ember/runloop", "@glimmer/component/-private/base-component-manager", "@glimmer/component/-private/destroyables"], function (_exports, _ember, _object, _application, _component, _runloop, _baseComponentManager, destroyables) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + const { + setDestroyed, + setDestroying + } = destroyables; + const CAPABILITIES = true // @ts-ignore + // @ts-ignore + ? (0, _component.capabilities)('3.13', { + destructor: true, + asyncLifecycleCallbacks: false, + updateHook: false + }) : (0, _component.capabilities)('3.4', { + destructor: true, + asyncLifecycleCallbacks: false + }); + const scheduledDestroyComponent = true ? undefined : (component, meta) => { + if (component.isDestroyed) { + return; + } + + _ember.default.destroy(component); + + meta.setSourceDestroyed(); + setDestroyed(component); + }; + const destroy = true ? _ember.default.destroy : component => { + if (component.isDestroying) { + return; + } + + let meta = _ember.default.meta(component); + + meta.setSourceDestroying(); + setDestroying(component); + (0, _runloop.schedule)('actions', component, component.willDestroy); + (0, _runloop.schedule)('destroy', void 0, scheduledDestroyComponent, component, meta); + }; + const registerDestructor = true ? _ember.default._registerDestructor : true ? _ember.default.__loader.require('@glimmer/runtime').registerDestructor : undefined; + /** + * This component manager runs in Ember.js environments and extends the base component manager to: + * + * 1. Properly destroy the component's associated `meta` data structure + * 2. Schedule destruction using Ember's runloop + */ + + class EmberGlimmerComponentManager extends (0, _baseComponentManager.default)(_application.setOwner, _application.getOwner, CAPABILITIES) { + createComponent(ComponentClass, args) { + const component = super.createComponent(ComponentClass, args); + + if (true) { + registerDestructor(component, () => { + component.willDestroy(); + }); + } + + return component; + } + + destroyComponent(component) { + destroy(component); + } + + } + + // In Ember 3.12 and earlier, the updateComponent hook was mandatory. + // As of Ember 3.13, the `args` object is stable and each property of the + // object participates in the autotrack stack on its own. This means we do not + // need to set the `args` property on the component instance to invalidate + // tracked getters that rely on `args`, and therefore don't require the `updateComponent` + // hook at all. + if (!true) { + EmberGlimmerComponentManager.prototype.updateComponent = function updateComponent(component, args) { + let argSnapshot = args.named; + + if (true + /* DEBUG */ + ) { + argSnapshot = Object.freeze(argSnapshot); + } + + (0, _object.set)(component, 'args', argSnapshot); + }; + } + + var _default = EmberGlimmerComponentManager; + _exports.default = _default; +}); +;define("@glimmer/component/-private/owner", ["exports", "@ember/application"], function (_exports, _application) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "setOwner", { + enumerable: true, + get: function () { + return _application.setOwner; + } + }); +}); +;define("@glimmer/component/index", ["exports", "@ember/component", "@glimmer/component/-private/ember-component-manager", "@glimmer/component/-private/component"], function (_exports, _component, _emberComponentManager, _component2) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + let GlimmerComponent = _component2.default; + + if (true + /* DEBUG */ + ) { + // Add assertions against using Glimmer.js only APIs + // TODO: Add GlimmerComponent API docs link to these messages once API docs are live + function throwMethodUseError(methodName) { + throw new Error(`You attempted to define the '${methodName}' method on a Glimmer Component, but that lifecycle hook does not exist in Ember.js applications, it only exists in Glimmer.js apps. You can rename this method, and you can trigger it using a modifier such as {{did-insert}} from '@ember/render-modifiers': https://github.com/emberjs/ember-render-modifiers.`); + } + + function throwPropertyUseError(propertyName) { + throw new Error(`You attempted to access the '${propertyName}' property on a Glimmer Component, but that property does not exist in Ember.js applications, it only exists in Glimmer.js apps. You define a class field with the same name on your component class and it will overwrite this error message, but it will not be used by the framework.`); + } + + GlimmerComponent = class GlimmerDebugComponent extends GlimmerComponent { + constructor(owner, args) { + super(owner, args); + + if (typeof this['didInsertElement'] === 'function') { + throwMethodUseError('didInsertElement'); + } + + if (typeof this['didUpdate'] === 'function') { + throwMethodUseError('didUpdate'); + } + } + + }; + let proto = GlimmerComponent.prototype; + + function defineErrorProp(proto, key, getterMethod) { + Object.defineProperty(proto, key, { + get: () => getterMethod(key), + + set(value) { + Object.defineProperty(this, key, { + value + }); + } + + }); + } // Methods should still throw whenever they are accessed + + + defineErrorProp(proto, 'bounds', throwPropertyUseError); + defineErrorProp(proto, 'element', throwPropertyUseError); + defineErrorProp(proto, 'debugName', throwPropertyUseError); + } + + if (true) { + (0, _component.setComponentManager)(owner => { + return new _emberComponentManager.default(owner); + }, GlimmerComponent); + } else { + (0, _component.setComponentManager)('glimmer', GlimmerComponent); + } + + var _default = GlimmerComponent; + _exports.default = _default; +}); +;define("ember-cli-app-version/initializer-factory", ["exports", "ember", "@ember/string"], function (_exports, _ember, _string) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = initializerFactory; + const { + libraries + } = _ember.default; + + function initializerFactory(name, version) { + let registered = false; + return function () { + if (!registered && name && version) { + let appName = (0, _string.classify)(name); + libraries.register(appName, version); + registered = true; + } + }; + } +}); +;define("ember-cli-app-version/utils/regexp", ["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.shaRegExp = _exports.versionExtendedRegExp = _exports.versionRegExp = void 0; + const versionRegExp = /\d+[.]\d+[.]\d+/; // Match any number of 3 sections of digits separated by . + + _exports.versionRegExp = versionRegExp; + const versionExtendedRegExp = /\d+[.]\d+[.]\d+-[a-z]*([.]\d+)?/; // Match the above but also hyphen followed by any number of lowercase letters, then optionally period and digits + + _exports.versionExtendedRegExp = versionExtendedRegExp; + const shaRegExp = /[a-z\d]{8}$/; // Match 8 lowercase letters and digits, at the end of the string only (to avoid matching with version extended part) + + _exports.shaRegExp = shaRegExp; +}); +;define("ember-load-initializers/index", ["exports", "require"], function (_exports, _require) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = loadInitializers; + + function resolveInitializer(moduleName) { + var module = (0, _require.default)(moduleName, null, null, true); + + if (!module) { + throw new Error(moduleName + ' must export an initializer.'); + } + + var initializer = module['default']; + + if (!initializer) { + throw new Error(moduleName + ' must have a default export'); + } + + if (!initializer.name) { + initializer.name = moduleName.slice(moduleName.lastIndexOf('/') + 1); + } + + return initializer; + } + + function registerInitializers(app, moduleNames) { + for (var i = 0; i < moduleNames.length; i++) { + app.initializer(resolveInitializer(moduleNames[i])); + } + } + + function registerInstanceInitializers(app, moduleNames) { + for (var i = 0; i < moduleNames.length; i++) { + app.instanceInitializer(resolveInitializer(moduleNames[i])); + } + } + + function _endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + /** + * Configure your application as it boots + */ + + + function loadInitializers(app, prefix) { + var initializerPrefix = prefix + '/initializers/'; + var instanceInitializerPrefix = prefix + '/instance-initializers/'; + var initializers = []; + var instanceInitializers = []; // this is 2 pass because generally the first pass is the problem + // and is reduced, and resolveInitializer has potential to deopt + + var moduleNames = Object.keys(requirejs._eak_seen); + + for (var i = 0; i < moduleNames.length; i++) { + var moduleName = moduleNames[i]; + + if (moduleName.lastIndexOf(initializerPrefix, 0) === 0) { + if (!_endsWith(moduleName, '-test')) { + initializers.push(moduleName); + } + } else if (moduleName.lastIndexOf(instanceInitializerPrefix, 0) === 0) { + if (!_endsWith(moduleName, '-test')) { + instanceInitializers.push(moduleName); + } + } + } + + registerInitializers(app, initializers); + registerInstanceInitializers(app, instanceInitializers); + } +}); +;/* + * This is a stub file, it must be on disk b/c babel-plugin-debug-macros + * does not strip the module require when the transpiled variable usage is + * stripped. + */ +define("ember-resolver/features", [], function () { + "use strict"; +}); +;define("ember-resolver/index", ["exports", "ember-resolver/resolvers/classic"], function (_exports, _classic) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "default", { + enumerable: true, + get: function () { + return _classic.default; + } + }); +}); +;define("ember-resolver/resolver", ["exports", "ember-resolver/resolvers/classic"], function (_exports, _classic) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "default", { + enumerable: true, + get: function () { + return _classic.default; + } + }); +}); +;define("ember-resolver/resolvers/classic/container-debug-adapter", ["exports", "@ember/array", "@ember/debug/container-debug-adapter", "ember-resolver/resolvers/classic/index"], function (_exports, _array, _containerDebugAdapter, _index) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + + function getPod(type, key, prefix) { + let match = key.match(new RegExp('^/?' + prefix + '/(.+)/' + type + '$')); + + if (match !== null) { + return match[1]; + } + } + /* + * This module defines a subclass of Ember.ContainerDebugAdapter that adds + * support for resolving from modules. + * + */ + + + var _default = _containerDebugAdapter.default.extend({ + _moduleRegistry: null, + + init() { + this._super(...arguments); + + if (!this._moduleRegistry) { + this._moduleRegistry = new _index.ModuleRegistry(); + } + }, + + /** + The container of the application being debugged. + This property will be injected + on creation. + @property container + @default null + */ + + /** + The resolver instance of the application + being debugged. This property will be injected + on creation. + @property resolver + @default null + */ + + /** + Returns true if it is possible to catalog a list of available + classes in the resolver for a given type. + @method canCatalogEntriesByType + @param {string} type The type. e.g. "model", "controller", "route" + @return {boolean} whether a list is available for this type. + */ + canCatalogEntriesByType(type) { + if (type === 'model') { + return true; + } + + return this._super(...arguments); + }, + + /** + Returns the available classes a given type. + @method catalogEntriesByType + @param {string} type The type. e.g. "model", "controller", "route" + @return {Array} An array of classes. + */ + catalogEntriesByType(type) { + let moduleNames = this._moduleRegistry.moduleNames(); + + let types = (0, _array.A)(); + let prefix = this.namespace.modulePrefix; + + for (let i = 0, l = moduleNames.length; i < l; i++) { + let key = moduleNames[i]; + + if (key.indexOf(type) !== -1) { + // Check if it's a pod module + let name = getPod(type, key, this.namespace.podModulePrefix || prefix); + + if (!name) { + // Not pod + name = key.split(type + 's/').pop(); // Support for different prefix (such as ember-cli addons). + // Uncomment the code below when + // https://github.com/ember-cli/ember-resolver/pull/80 is merged. + //let match = key.match('^/?(.+)/' + type); + //if (match && match[1] !== prefix) { + // Different prefix such as an addon + //name = match[1] + '@' + name; + //} + } + + types.addObject(name); + } + } + + return types; + } + + }); + + _exports.default = _default; +}); +;define("ember-resolver/resolvers/classic/index", ["exports", "ember", "@ember/debug", "@ember/object", "@ember/string", "ember-resolver/utils/class-factory"], function (_exports, _ember, _debug, _object, _string, _classFactory) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = _exports.ModuleRegistry = void 0; + + /* globals requirejs, require */ + if (typeof requirejs.entries === 'undefined') { + requirejs.entries = requirejs._eak_seen; + } + + class ModuleRegistry { + constructor(entries) { + this._entries = entries || requirejs.entries; + } + + moduleNames() { + return Object.keys(this._entries); + } + + has(moduleName) { + return moduleName in this._entries; + } + + get(moduleName) { + return require(moduleName); + } + + } + /** + * This module defines a subclass of Ember.DefaultResolver that adds two + * important features: + * + * 1) The resolver makes the container aware of es6 modules via the AMD + * output. The loader's _moduleEntries is consulted so that classes can be + * resolved directly via the module loader, without needing a manual + * `import`. + * 2) is able to provide injections to classes that implement `extend` + * (as is typical with Ember). + */ + + + _exports.ModuleRegistry = ModuleRegistry; + + function parseName(fullName) { + if (fullName.parsedName === true) { + return fullName; + } + + let prefix, type, name; + let fullNameParts = fullName.split('@'); + + if (fullNameParts.length === 3) { + if (fullNameParts[0].length === 0) { + // leading scoped namespace: `@scope/pkg@type:name` + prefix = `@${fullNameParts[1]}`; + let prefixParts = fullNameParts[2].split(':'); + type = prefixParts[0]; + name = prefixParts[1]; + } else { + // interweaved scoped namespace: `type:@scope/pkg@name` + prefix = `@${fullNameParts[1]}`; + type = fullNameParts[0].slice(0, -1); + name = fullNameParts[2]; + } + + if (type === 'template:components') { + name = `components/${name}`; + type = 'template'; + } + } else if (fullNameParts.length === 2) { + let prefixParts = fullNameParts[0].split(':'); + + if (prefixParts.length === 2) { + if (prefixParts[1].length === 0) { + type = prefixParts[0]; + name = `@${fullNameParts[1]}`; + } else { + prefix = prefixParts[1]; + type = prefixParts[0]; + name = fullNameParts[1]; + } + } else { + let nameParts = fullNameParts[1].split(':'); + prefix = fullNameParts[0]; + type = nameParts[0]; + name = nameParts[1]; + } + + if (type === 'template' && prefix.lastIndexOf('components/', 0) === 0) { + name = `components/${name}`; + prefix = prefix.slice(11); + } + } else { + fullNameParts = fullName.split(':'); + type = fullNameParts[0]; + name = fullNameParts[1]; + } + + let fullNameWithoutType = name; + let namespace = (0, _object.get)(this, 'namespace'); + let root = namespace; + return { + parsedName: true, + fullName: fullName, + prefix: prefix || this.prefix({ + type: type + }), + type: type, + fullNameWithoutType: fullNameWithoutType, + name: name, + root: root, + resolveMethodName: "resolve" + (0, _string.classify)(type) + }; + } + + function resolveOther(parsedName) { + (true && !(this.namespace.modulePrefix) && (0, _debug.assert)('`modulePrefix` must be defined', this.namespace.modulePrefix)); + let normalizedModuleName = this.findModuleName(parsedName); + + if (normalizedModuleName) { + let defaultExport = this._extractDefaultExport(normalizedModuleName, parsedName); + + if (defaultExport === undefined) { + throw new Error(` Expected to find: '${parsedName.fullName}' within '${normalizedModuleName}' but got 'undefined'. Did you forget to 'export default' within '${normalizedModuleName}'?`); + } + + if (this.shouldWrapInClassFactory(defaultExport, parsedName)) { + defaultExport = (0, _classFactory.default)(defaultExport); + } + + return defaultExport; + } + } + + const Resolver = _object.default.extend({ + resolveOther, + parseName, + pluralizedTypes: null, + moduleRegistry: null, + + makeToString(factory, fullName) { + return '' + this.namespace.modulePrefix + '@' + fullName + ':'; + }, + + shouldWrapInClassFactory() { + return false; + }, + + init() { + this._super(); + + this.moduleBasedResolver = true; + + if (!this._moduleRegistry) { + this._moduleRegistry = new ModuleRegistry(); + } + + this._normalizeCache = Object.create(null); + this.pluralizedTypes = this.pluralizedTypes || Object.create(null); + + if (!this.pluralizedTypes.config) { + this.pluralizedTypes.config = 'config'; + } + + this._deprecatedPodModulePrefix = false; + }, + + normalize(fullName) { + return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this._normalize(fullName)); + }, + + resolve(fullName) { + let parsedName = this.parseName(fullName); + let resolveMethodName = parsedName.resolveMethodName; + let resolved; + + if (typeof this[resolveMethodName] === 'function') { + resolved = this[resolveMethodName](parsedName); + } + + if (resolved == null) { + resolved = this.resolveOther(parsedName); + } + + return resolved; + }, + + _normalize(fullName) { + // A) Convert underscores to dashes + // B) Convert camelCase to dash-case, except for components (their + // templates) and helpers where we want to avoid shadowing camelCase + // expressions + // C) replace `.` with `/` in order to make nested controllers work in the following cases + // 1. `needs: ['posts/post']` + // 2. `{{render "posts/post"}}` + // 3. `this.render('posts/post')` from Route + let split = fullName.split(':'); + + if (split.length > 1) { + let type = split[0]; + + if (type === 'component' || type === 'helper' || type === 'modifier' || type === 'template' && split[1].indexOf('components/') === 0) { + return type + ':' + split[1].replace(/_/g, '-'); + } else { + return type + ':' + (0, _string.dasherize)(split[1].replace(/\./g, '/')); + } + } else { + return fullName; + } + }, + + pluralize(type) { + return this.pluralizedTypes[type] || (this.pluralizedTypes[type] = type + 's'); + }, + + podBasedLookupWithPrefix(podPrefix, parsedName) { + let fullNameWithoutType = parsedName.fullNameWithoutType; + + if (parsedName.type === 'template') { + fullNameWithoutType = fullNameWithoutType.replace(/^components\//, ''); + } + + return podPrefix + '/' + fullNameWithoutType + '/' + parsedName.type; + }, + + podBasedModuleName(parsedName) { + let podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix; + return this.podBasedLookupWithPrefix(podPrefix, parsedName); + }, + + podBasedComponentsInSubdir(parsedName) { + let podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix; + podPrefix = podPrefix + '/components'; + + if (parsedName.type === 'component' || /^components/.test(parsedName.fullNameWithoutType)) { + return this.podBasedLookupWithPrefix(podPrefix, parsedName); + } + }, + + resolveEngine(parsedName) { + let engineName = parsedName.fullNameWithoutType; + let engineModule = engineName + '/engine'; + + if (this._moduleRegistry.has(engineModule)) { + return this._extractDefaultExport(engineModule); + } + }, + + resolveRouteMap(parsedName) { + let engineName = parsedName.fullNameWithoutType; + let engineRoutesModule = engineName + '/routes'; + + if (this._moduleRegistry.has(engineRoutesModule)) { + let routeMap = this._extractDefaultExport(engineRoutesModule); + + (true && !(routeMap.isRouteMap) && (0, _debug.assert)(`The route map for ${engineName} should be wrapped by 'buildRoutes' before exporting.`, routeMap.isRouteMap)); + return routeMap; + } + }, + + resolveTemplate(parsedName) { + let resolved = this.resolveOther(parsedName); + + if (resolved == null) { + resolved = _ember.default.TEMPLATES[parsedName.fullNameWithoutType]; + } + + return resolved; + }, + + mainModuleName(parsedName) { + if (parsedName.fullNameWithoutType === 'main') { + // if router:main or adapter:main look for a module with just the type first + return parsedName.prefix + '/' + parsedName.type; + } + }, + + defaultModuleName(parsedName) { + return parsedName.prefix + '/' + this.pluralize(parsedName.type) + '/' + parsedName.fullNameWithoutType; + }, + + nestedColocationComponentModuleName(parsedName) { + if (parsedName.type === 'component') { + return parsedName.prefix + '/' + this.pluralize(parsedName.type) + '/' + parsedName.fullNameWithoutType + '/index'; + } + }, + + prefix(parsedName) { + let tmpPrefix = this.namespace.modulePrefix; + + if (this.namespace[parsedName.type + 'Prefix']) { + tmpPrefix = this.namespace[parsedName.type + 'Prefix']; + } + + return tmpPrefix; + }, + + /** + A listing of functions to test for moduleName's based on the provided + `parsedName`. This allows easy customization of additional module based + lookup patterns. + @property moduleNameLookupPatterns + @returns {Ember.Array} + */ + moduleNameLookupPatterns: (0, _object.computed)(function () { + return [this.podBasedModuleName, this.podBasedComponentsInSubdir, this.mainModuleName, this.defaultModuleName, this.nestedColocationComponentModuleName]; + }).readOnly(), + + findModuleName(parsedName, loggingDisabled) { + let moduleNameLookupPatterns = this.get('moduleNameLookupPatterns'); + let moduleName; + + for (let index = 0, length = moduleNameLookupPatterns.length; index < length; index++) { + let item = moduleNameLookupPatterns[index]; + let tmpModuleName = item.call(this, parsedName); // allow treat all dashed and all underscored as the same thing + // supports components with dashes and other stuff with underscores. + + if (tmpModuleName) { + tmpModuleName = this.chooseModuleName(tmpModuleName, parsedName); + } + + if (tmpModuleName && this._moduleRegistry.has(tmpModuleName)) { + moduleName = tmpModuleName; + } + + if (!loggingDisabled) { + this._logLookup(moduleName, parsedName, tmpModuleName); + } + + if (moduleName) { + return moduleName; + } + } + }, + + chooseModuleName(moduleName, parsedName) { + let underscoredModuleName = (0, _string.underscore)(moduleName); + + if (moduleName !== underscoredModuleName && this._moduleRegistry.has(moduleName) && this._moduleRegistry.has(underscoredModuleName)) { + throw new TypeError(`Ambiguous module names: '${moduleName}' and '${underscoredModuleName}'`); + } + + if (this._moduleRegistry.has(moduleName)) { + return moduleName; + } else if (this._moduleRegistry.has(underscoredModuleName)) { + return underscoredModuleName; + } // workaround for dasherized partials: + // something/something/-something => something/something/_something + + + let partializedModuleName = moduleName.replace(/\/-([^/]*)$/, '/_$1'); + + if (this._moduleRegistry.has(partializedModuleName)) { + (true && !(false) && (0, _debug.deprecate)('Modules should not contain underscores. ' + 'Attempted to lookup "' + moduleName + '" which ' + 'was not found. Please rename "' + partializedModuleName + '" ' + 'to "' + moduleName + '" instead.', false, { + id: 'ember-resolver.underscored-modules', + until: '3.0.0' + })); + return partializedModuleName; + } + + if (true + /* DEBUG */ + ) { + let isCamelCaseHelper = parsedName.type === 'helper' && /[a-z]+[A-Z]+/.test(moduleName); + + if (isCamelCaseHelper) { + this._camelCaseHelperWarnedNames = this._camelCaseHelperWarnedNames || []; + let alreadyWarned = this._camelCaseHelperWarnedNames.indexOf(parsedName.fullName) > -1; + + if (!alreadyWarned && this._moduleRegistry.has((0, _string.dasherize)(moduleName))) { + this._camelCaseHelperWarnedNames.push(parsedName.fullName); + + (true && (0, _debug.warn)('Attempted to lookup "' + parsedName.fullName + '" which ' + 'was not found. In previous versions of ember-resolver, a bug would have ' + 'caused the module at "' + (0, _string.dasherize)(moduleName) + '" to be ' + 'returned for this camel case helper name. This has been fixed. ' + 'Use the dasherized name to resolve the module that would have been ' + 'returned in previous versions.', false, { + id: 'ember-resolver.camelcase-helper-names', + until: '3.0.0' + })); + } + } + } + }, + + // used by Ember.DefaultResolver.prototype._logLookup + lookupDescription(fullName) { + let parsedName = this.parseName(fullName); + let moduleName = this.findModuleName(parsedName, true); + return moduleName; + }, + + // only needed until 1.6.0-beta.2 can be required + _logLookup(found, parsedName, description) { + if (!_ember.default.ENV.LOG_MODULE_RESOLVER && !parsedName.root.LOG_RESOLVER) { + return; + } + + let padding; + let symbol = found ? '[✓]' : '[ ]'; + + if (parsedName.fullName.length > 60) { + padding = '.'; + } else { + padding = new Array(60 - parsedName.fullName.length).join('.'); + } + + if (!description) { + description = this.lookupDescription(parsedName); + } + /* eslint-disable no-console */ + + + if (console && console.info) { + console.info(symbol, parsedName.fullName, padding, description); + } + }, + + knownForType(type) { + let moduleKeys = this._moduleRegistry.moduleNames(); + + let items = Object.create(null); + + for (let index = 0, length = moduleKeys.length; index < length; index++) { + let moduleName = moduleKeys[index]; + let fullname = this.translateToContainerFullname(type, moduleName); + + if (fullname) { + items[fullname] = true; + } + } + + return items; + }, + + translateToContainerFullname(type, moduleName) { + let prefix = this.prefix({ + type + }); // Note: using string manipulation here rather than regexes for better performance. + // pod modules + // '^' + prefix + '/(.+)/' + type + '$' + + let podPrefix = prefix + '/'; + let podSuffix = '/' + type; + let start = moduleName.indexOf(podPrefix); + let end = moduleName.indexOf(podSuffix); + + if (start === 0 && end === moduleName.length - podSuffix.length && moduleName.length > podPrefix.length + podSuffix.length) { + return type + ':' + moduleName.slice(start + podPrefix.length, end); + } // non-pod modules + // '^' + prefix + '/' + pluralizedType + '/(.+)$' + + + let pluralizedType = this.pluralize(type); + let nonPodPrefix = prefix + '/' + pluralizedType + '/'; + + if (moduleName.indexOf(nonPodPrefix) === 0 && moduleName.length > nonPodPrefix.length) { + return type + ':' + moduleName.slice(nonPodPrefix.length); + } + }, + + _extractDefaultExport(normalizedModuleName) { + let module = require(normalizedModuleName, null, null, true + /* force sync */ + ); + + if (module && module['default']) { + module = module['default']; + } + + return module; + } + + }); + + Resolver.reopenClass({ + moduleBasedResolver: true + }); + var _default = Resolver; + _exports.default = _default; +}); +;define("ember-resolver/utils/class-factory", ["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = classFactory; + + function classFactory(klass) { + return { + create(injections) { + if (typeof klass.extend === 'function') { + return klass.extend(injections); + } else { + return klass; + } + } + + }; + } +}); +;define("ember-test-waiters/index", ["exports", "@ember/debug", "@ember/test-waiters"], function (_exports, _debug, _testWaiters) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.keys(_testWaiters).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in _exports && _exports[key] === _testWaiters[key]) return; + Object.defineProperty(_exports, key, { + enumerable: true, + get: function () { + return _testWaiters[key]; + } + }); + }); + (true && !(false) && (0, _debug.deprecate)('Importing from ember-test-waiters is deprecated. Please import from @ember/test-waiters', false, { + id: 'ember-test-waiters-legacy-module-name', + until: '3.0.0', + for: 'ember-test-waiters', + since: { + enabled: '2.2.0' + } + })); +}); +; +; +var __ember_auto_import__ = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "../../../../../private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js": +/*!****************************************************************************************************************************!*\ + !*** /private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js ***! + \****************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("\nif (typeof document !== 'undefined') {\n __webpack_require__.p = (function(){\n var scripts = document.querySelectorAll('script');\n return scripts[scripts.length - 1].src.replace(/\\/[^/]*$/, '/');\n })();\n}\n\nmodule.exports = (function(){\n var d = _eai_d;\n var r = _eai_r;\n window.emberAutoImportDynamic = function(specifier) {\n if (arguments.length === 1) {\n return r('_eai_dyn_' + specifier);\n } else {\n return r('_eai_dynt_' + specifier)(Array.prototype.slice.call(arguments, 1))\n }\n };\n})();\n\n\n//# sourceURL=webpack://__ember_auto_import__//private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js?"); + +/***/ }), + +/***/ "../../../../../private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js": +/*!**************************************************************************************************************************!*\ + !*** /private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js ***! + \**************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("\nwindow._eai_r = require;\nwindow._eai_d = define;\n\n\n//# sourceURL=webpack://__ember_auto_import__//private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js?"); + +/***/ }), + +/***/ 0: +/*!*****************************************************************************************************************************************************************************************************************************************************!*\ + !*** multi /private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js /private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js ***! + \*****************************************************************************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("__webpack_require__(/*! /private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js */\"../../../../../private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js\");\nmodule.exports = __webpack_require__(/*! /private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js */\"../../../../../private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js\");\n\n\n//# sourceURL=webpack://__ember_auto_import__/multi_/private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/l.js_/private/var/folders/5s/1y9hqll10z37zpn907glnh0c0000gn/T/broccoli-52121uzX6O63VM45v/cache-119-bundler/staging/app.js?"); + +/***/ }) + +/******/ });//# sourceMappingURL=vendor.map diff --git a/tests/assets/reading-list/ember3.html b/tests/assets/reading-list/ember3.html new file mode 100644 index 00000000000000..82be5e07d2ec27 --- /dev/null +++ b/tests/assets/reading-list/ember3.html @@ -0,0 +1,129 @@ + + + + + + + ReadingList + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/css-parser.spec.ts b/tests/css-parser.spec.ts index 33ba62aae3e5e2..5a8eee30bf49d9 100644 --- a/tests/css-parser.spec.ts +++ b/tests/css-parser.spec.ts @@ -18,7 +18,7 @@ import { playwrightTest as it, expect } from './config/browserTest'; import { parseCSS, serializeSelector as serialize } from '../src/server/common/cssParser'; const parse = (selector: string) => { - return parseCSS(selector, new Set(['text', 'not', 'has', 'react', 'scope', 'right-of', 'scope', 'is'])).selector; + return parseCSS(selector, new Set(['text', 'not', 'has', 'react', 'ember', 'scope', 'right-of', 'scope', 'is'])).selector; }; it('should parse css', async () => { diff --git a/tests/page/selectors-ember.spec.ts b/tests/page/selectors-ember.spec.ts new file mode 100644 index 00000000000000..8c879fb2fd9490 --- /dev/null +++ b/tests/page/selectors-ember.spec.ts @@ -0,0 +1,118 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { test as it, expect } from './pageTest'; + +const embers = { + 'ember.3.28': '/reading-list/ember3.html', +}; + +for (const [name, url] of Object.entries(embers)) { + it.describe(name, () => { + it.beforeEach(async ({page, server}) => { + await page.goto(server.PREFIX + url); + }); + + it('should work with single-root elements', async ({page}) => { + expect(await page.$$eval(`_ember=ReadingList`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ListItem`, els => els.length)).toBe(3); + expect(await page.$$eval(`_ember=ReadingList >> _ember=ListItem`, els => els.length)).toBe(3); + expect(await page.$$eval(`_ember=ListItem >> _ember=ReadingList`, els => els.length)).toBe(0); + + }); + + it('should not crash when there is no match', async ({page}) => { + expect(await page.$$eval(`_ember=Apps`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=BookLi`, els => els.length)).toBe(0); + }); + + it('should compose', async ({page}) => { + expect(await page.$eval(`_ember=ListItem >> text=Gatsby`, el => el.textContent.trim())).toBe('The Great Gatsby'); + }); + + it('should query by args combinations', async ({page}) => { + expect(await page.$$eval(`_ember=ListItem[name="The Great Gatsby"]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ListItem[name="the great gatsby" i]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ColorButton[nested.index = 0]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ColorButton[nested.nonexisting.index = 0]`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=ColorButton[nested.index.nonexisting = 0]`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=ColorButton[nested.index.nonexisting = 1]`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=ColorButton[nested.value = 4.1]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ColorButton[disabled = true]`, els => els.length)).toBe(5); + expect(await page.$$eval(`_ember=ColorButton[disabled = false] `, els => els.length)).toBe(4); + expect(await page.$$eval(`_ember=ColorButton[disabled = true][color = "red"]`, els => els.length)).toBe(2); + expect(await page.$$eval(`_ember=ColorButton[disabled = true][color = "red"i][nested.index = 6]`, els => els.length)).toBe(1); + }); + + it('should exact match by args', async ({page}) => { + expect(await page.$eval(`_ember=ListItem[name = "The Great Gatsby"]`, el => el.textContent)).toBe('The Great Gatsby'); + expect(await page.$$eval(`_ember=ListItem[name = "The Great Gatsby"]`, els => els.length)).toBe(1); + // case sensetive by default + expect(await page.$$eval(`_ember=ListItem[name = "the great gatsby"]`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=ListItem[name = "the great gatsby" s]`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=ListItem[name = "the great gatsby" S]`, els => els.length)).toBe(0); + // case insensetive with flag + expect(await page.$$eval(`_ember=ListItem[name = "the great gatsby" i]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ListItem[name = "the great gatsby" I]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ListItem[name = " The Great Gatsby "]`, els => els.length)).toBe(0); + }); + + it('should partially match by args', async ({page}) => { + // Check partial matching + expect(await page.$eval(`_ember=ListItem[name *= "Gatsby"]`, el => el.textContent)).toBe('The Great Gatsby'); + expect(await page.$$eval(`_ember=ListItem[name *= "Gatsby"]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=[name *= "Gatsby"]`, els => els.length)).toBe(1); + + expect(await page.$$eval(`_ember=ListItem[name = "Gatsby"]`, els => els.length)).toBe(0); + }); + + it('should support all string operators', async ({page}) => { + expect(await page.$$eval(`_ember=ColorButton[color = "red"]`, els => els.length)).toBe(3); + expect(await page.$$eval(`_ember=ColorButton[color |= "red"]`, els => els.length)).toBe(3); + expect(await page.$$eval(`_ember=ColorButton[color $= "ed"]`, els => els.length)).toBe(3); + expect(await page.$$eval(`_ember=ColorButton[color ^= "gr"]`, els => els.length)).toBe(3); + expect(await page.$$eval(`_ember=ColorButton[color ~= "e"]`, els => els.length)).toBe(0); + expect(await page.$$eval(`_ember=ListItem[name ~= "gatsby" i]`, els => els.length)).toBe(1); + expect(await page.$$eval(`_ember=ListItem[name *= " gatsby" i]`, els => els.length)).toBe(1); + }); + + // it('should support truthy querying', async ({page}) => { + // expect(await page.$$eval(`_ember=ColorButton[enabled]`, els => els.length)).toBe(5); + // }); + + // it('should work with multiroot react', async ({page}) => { + // await it.step('mount second root', async () => { + // await expect(page.locator(`_ember=BookItem`)).toHaveCount(3); + // await page.evaluate(() => { + // const anotherRoot = document.createElement('div'); + // anotherRoot.id = 'root2'; + // anotherRoot.append(document.createElement('div')); + // document.body.append(anotherRoot); + // // @ts-ignore + // window.mountApp(anotherRoot.querySelector('div')); + // }); + // await expect(page.locator(`_ember=BookItem`)).toHaveCount(6); + // }); + + // await it.step('add a new book to second root', async () => { + // await page.locator('#root2 input').fill('newbook'); + // await page.locator('#root2 >> text=new book').click(); + // await expect(page.locator('css=#root >> _ember=BookItem')).toHaveCount(3); + // await expect(page.locator('css=#root2 >> _ember=BookItem')).toHaveCount(4); + // }); + // }); + }); +} +