UNPKG

strider

Version:

Brilliant continuous deployment platform

1,680 lines (1,403 loc) 6.18 MB
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-2019 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.18.1 */ /*globals process */ var define, require, Ember; // Used in @ember/-internals/environment/lib/global.js mainContext = this; // eslint-disable-line no-undef (function () { var registry; var seen; 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] = internalRequire(deps[i], name); } } callback.apply(this, reified); return exports; } var isNode = typeof window === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; if (!isNode) { Ember = this.Ember = this.Ember || {}; } if (typeof Ember === 'undefined') { Ember = {}; } if (typeof Ember.__loader === 'undefined') { registry = Object.create(null); seen = Object.create(null); define = function (name, deps, callback) { var value = {}; if (!callback) { value.deps = []; value.callback = deps; } else { value.deps = deps; value.callback = callback; } registry[name] = value; }; require = function (name) { return internalRequire(name, null); }; // setup `require` module require['default'] = require; require.has = function registryHas(moduleName) { return Boolean(registry[moduleName]) || Boolean(registry[moduleName + '/index']); }; require._eak_seen = registry; Ember.__loader = { define: define, require: require, registry: registry }; } else { define = Ember.__loader.define; require = Ember.__loader.require; } })(); define("@ember/-internals/browser-environment/index", ["exports"], function (_exports) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.hasDOM = _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 ? Boolean(window.chrome) && !window.opera : false; _exports.isChrome = isChrome; var isFirefox = hasDom ? typeof InstallTrigger !== 'undefined' : false; _exports.isFirefox = isFirefox; }); 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://emberjs.com/deprecations/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 })); 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 })); 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 })); 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 })); 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 })); /* 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 })); 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.FACTORY_FOR = _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() { return { [_owner.OWNER]: this.owner }; } /** 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, options = {}) { 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))); (true && !(false /* EMBER_MODULE_UNIFICATION */ || !options.namespace) && (0, _debug.assert)('EMBER_MODULE_UNIFICATION must be enabled to pass a namespace option to factoryFor', false || !options.namespace)); if (options.source || options.namespace) { normalizedName = this.registry.expandLocalLookup(fullName, options); if (!normalizedName) { return; } } 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); } }; var proxy = new Proxy(proxiedManager, validator); FACTORY_FOR.set(proxy, manager); } 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 = {}) { (true && !(false /* EMBER_MODULE_UNIFICATION */ || !options.namespace) && (0, _debug.assert)('EMBER_MODULE_UNIFICATION must be enabled to pass a namespace option to lookup', false || !options.namespace)); var normalizedName = fullName; if (options.source || options.namespace) { normalizedName = container.registry.expandLocalLookup(fullName, options); if (!normalizedName) { return; } } 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; if (hash === undefined) { hash = result.injections = {}; } for (var i = 0; i < injections.length; i++) { var { property, specifier, source } = injections[i]; if (source) { hash[property] = lookup(container, specifier, { source }); } else { hash[property] = lookup(container, specifier); } if (!result.isDynamic) { result.isDynamic = !isSingleton(container, specifier); } } } function buildInjections(container, typeInjections, injections) { var result = { injections: undefined, 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 FACTORY_FOR = new WeakMap(); _exports.FACTORY_FOR = FACTORY_FOR; 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; FACTORY_FOR.set(this, 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 injectionsCache = this.injections; if (injectionsCache === undefined) { var { injections, isDynamic } = injectionsFor(this.container, this.normalizedName); injectionsCache = injections; if (!isDynamic) { this.injections = injections; } } var props = injectionsCache; if (options !== undefined) { props = (0, _polyfills.assign)({}, injectionsCache, 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; } if (!this.class.create) { throw new Error(`Failed to create an instance of '${this.normalizedName}'. Most likely an improperly defined class or an invalid module export.`); } // required to allow access to things like // the customized toString, _debugContainerKey, // owner, etc. without a double extend and without // modifying the objects properties if (typeof this.class._initFactory === 'function') { this.class._initFactory(this); } else { // in the non-EmberObject case we need to still setOwner // this is required for supporting glimmer environment and // template instantiation which rely heavily on // `options[OWNER]` being passed into `create` // TODO: clean this up, and remove in future versions if (options === undefined || props === undefined) { // avoid mutating `props` here since they are the cached injections props = (0, _polyfills.assign)({}, props); } (0, _owner.setOwner)(props, this.owner); } var instance = this.class.create(props); FACTORY_FOR.set(instance, this); return instance; } } 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, options) { var factory = resolve(this, this.normalize(fullName), options); 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) { 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 factory.toString(); } } /** 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, options) { if (!this.isValidFullName(fullName)) { return false; } var source = options && options.source && this.normalize(options.source); var namespace = options && options.namespace || undefined; return has(this, this.normalize(fullName), source, namespace); } /** 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) {