PageSourceSearch

https://ember-youtube.surge.sh/assets/vendor.js

js ember-youtube.surge.sh collected 2026-10-03 14:55:44 UTC 2,774,832 bytes, 85,955 lines download raw bytes

1/* jshint ignore:start */
2
3window.EmberENV = {"FEATURES":{}};
4var runningTests = false;
5
6
7
8/* jshint ignore:end */
9
10;var loader, define, requireModule, require, requirejs;
11
12(function(global) {
13  'use strict';
14
15  var stats;
16
17  // Save off the original values of these globals, so we can restore them if someone asks us to
18  var oldGlobals = {
19    loader: loader,
20    define: define,
21    requireModule: requireModule,
22    require: require,
23    requirejs: requirejs
24  };
25
26  requirejs = require = requireModule = function(name) {
27    stats.require++;
28    var pending = [];
29    var mod = findModule(name, '(require)', pending);
30
31    for (var i = pending.length - 1; i >= 0; i--) {
32      pending[i].exports();
33    }
34
35    return mod.module.exports;
36  };
37
38  function resetStats() {
39    stats = {
40      define: 0,
41      require: 0,
42      reify: 0,
43      findDeps: 0,
44      modules: 0,
45      exports: 0,
46      resolve: 0,
47      resolveRelative: 0,
48      findModule: 0,
49      pendingQueueLength: 0
50    };
51    requirejs._stats = stats;
52  }
53
54
55  resetStats();
56
57  loader = {
58    noConflict: function(aliases) {
59      var oldName, newName;
60
61      for (oldName in aliases) {
62        if (aliases.hasOwnProperty(oldName)) {
63          if (oldGlobals.hasOwnProperty(oldName)) {
64            newName = aliases[oldName];
65
66            global[newName] = global[oldName];
67            global[oldName] = oldGlobals[oldName];
68          }
69        }
70      }
71    }
72  };
73
74  var _isArray;
75  if (!Array.isArray) {
76    _isArray = function (x) {
77      return Object.prototype.toString.call(x) === '[object Array]';
78    };
79  } else {
80    _isArray = Array.isArray;
81  }
82
83  var registry = {};
84  var seen = {};
85
86  var uuid = 0;
87
88  function unsupportedModule(length) {
89    throw new Error('an unsupported module was defined, expected `define(name, deps, module)` instead got: `' +
90                    length + '` arguments to define`');
91  }
92
93  var defaultDeps = ['require', 'exports', 'module'];
94
95  function Module(name, deps, callback, alias) {
96    stats.modules++;
97    this.id        = uuid++;
98    this.name      = name;
99    this.deps      = !deps.length && callback.length ? defaultDeps : deps;
100    this.module    = { exports: {} };
101    this.callback  = callback;
102    this.finalized = false;
103    this.hasExportsAsDep = false;
104    this.isAlias = alias;
105    this.reified = new Array(deps.length);
106    this._foundDeps = false;
107    this.isPending = false;
108  }
109
110  Module.prototype.makeDefaultExport = function() {
111    var exports = this.module.exports;
112    if (exports !== null &&
113        (typeof exports === 'object' || typeof exports === 'function') &&
114          exports['default'] === undefined) {
115      exports['default'] = exports;
116    }
117  };
118
119  Module.prototype.exports = function() {
120    if (this.finalized) { return this.module.exports; }
121    stats.exports++;
122
123    this.finalized = true;
124    this.isPending = false;
125
126    if (loader.wrapModules) {
127      this.callback = loader.wrapModules(this.name, this.callback);
128    }
129
130    this.reify();
131
132    var result = this.callback.apply(this, this.reified);
133
134    if (!(this.hasExportsAsDep && result === undefined)) {
135      this.module.exports = result;
136    }
137    this.makeDefaultExport();
138    return this.module.exports;
139  };
140
141  Module.prototype.unsee = function() {
142    this.finalized = false;
143    this._foundDeps = false;
144    this.isPending = false;
145    this.module = { exports: {} };
146  };
147
148  Module.prototype.reify = function() {
149    stats.reify++;
150    var reified = this.reified;
151    for (var i = 0; i < reified.length; i++) {
152      var mod = reified[i];
153      reified[i] = mod.exports ? mod.exports : mod.module.exports();
154    }
155  };
156
157  Module.prototype.findDeps = function(pending) {
158    if (this._foundDeps) {
159      return;
160    }
161
162    stats.findDeps++;
163    this._foundDeps = true;
164    this.isPending = true;
165
166    var deps = this.deps;
167
168    for (var i = 0; i < deps.length; i++) {
169      var dep = deps[i];
170      var entry = this.reified[i] = { exports: undefined, module: undefined };
171      if (dep === 'exports') {
172        this.hasExportsAsDep = true;
173        entry.exports = this.module.exports;
174      } else if (dep === 'require') {
175        entry.exports = this.makeRequire();
176      } else if (dep === 'module') {
177        entry.exports = this.module;
178      } else {
179        entry.module = findModule(resolve(dep, this.name), this.name, pending);
180      }
181    }
182  };
183
184  Module.prototype.makeRequire = function() {
185    var name = this.name;
186    var r = function(dep) {
187      return require(resolve(dep, name));
188    };
189    r['default'] = r;
190    r.has = function(dep) {
191      return has(resolve(dep, name));
192    };
193    return r;
194  };
195
196  define = function(name, deps, callback) {
197    stats.define++;
198    if (arguments.length < 2) {
199      unsupportedModule(arguments.length);
200    }
201
202    if (!_isArray(deps)) {
203      callback = deps;
204      deps     =  [];
205    }
206
207    if (callback instanceof Alias) {
208      registry[name] = new Module(callback.name, deps, callback, true);
209    } else {
210      registry[name] = new Module(name, deps, callback, false);
211    }
212  };
213
214  // we don't support all of AMD
215  // define.amd = {};
216  // we will support petals...
217  define.petal = { };
218
219  function Alias(path) {
220    this.name = path;
221  }
222
223  define.alias = function(path) {
224    return new Alias(path);
225  };
226
227  function missingModule(name, referrer) {
228    throw new Error('Could not find module `' + name + '` imported from `' + referrer + '`');
229  }
230
231  function findModule(name, referrer, pending) {
232    stats.findModule++;
233    var mod = registry[name] || registry[name + '/index'];
234
235    while (mod && mod.isAlias) {
236      mod = registry[mod.name];
237    }
238
239    if (!mod) { missingModule(name, referrer); }
240
241    if (pending && !mod.finalized && !mod.isPending) {
242      mod.findDeps(pending);
243      pending.push(mod);
244      stats.pendingQueueLength++;
245    }
246    return mod;
247  }
248
249  function resolve(child, name) {
250    stats.resolve++;
251    if (child.charAt(0) !== '.') { return child; }
252    stats.resolveRelative++;
253
254    var parts = child.split('/');
255    var nameParts = name.split('/');
256    var parentBase = nameParts.slice(0, -1);
257
258    for (var i = 0, l = parts.length; i < l; i++) {
259      var part = parts[i];
260
261      if (part === '..') {
262        if (parentBase.length === 0) {
263          throw new Error('Cannot access parent module of root');
264        }
265        parentBase.pop();
266      } else if (part === '.') {
267        continue;
268      } else { parentBase.push(part); }
269    }
270
271    return parentBase.join('/');
272  }
273
274  function has(name) {
275    return !!(registry[name] || registry[name + '/index']);
276  }
277
278  requirejs.entries = requirejs._eak_seen = registry;
279  requirejs.has = has;
280  requirejs.unsee = function(moduleName) {
281    findModule(moduleName, '(unsee)', false).unsee();
282  };
283
284  requirejs.clear = function() {
285    resetStats();
286    requirejs.entries = requirejs._eak_seen = registry = {};
287    seen = {};
288  };
289
290  // prime
291  define('foo',      function() {});
292  define('foo/bar',  [], function() {});
293  define('foo/asdf', ['module', 'exports', 'require'], function(module, exports, require) {
294    if (require.has('foo/bar')) {
295      require('foo/bar');
296    }
297  });
298  define('foo/baz',  [], define.alias('foo'));
299  define('foo/quz',  define.alias('foo'));
300  define('foo/bar',  ['foo', './quz', './baz', './asdf', './bar', '../foo'], function() {});
301  define('foo/main', ['foo/bar'], function() {});
302
303  require('foo/main');
304  require.unsee('foo/bar');
305
306  requirejs.clear();
307
308  if (typeof exports === 'object' && typeof module === 'object' && module.exports) {
309    module.exports = { require: require, define: define };
310  }
311})(this);
312
313;self.EmberENV.EXTEND_PROTOTYPES = false;
314
315;
vendor: 257,552 bytes, lines 315-10129
315/*!
316 * jQuery JavaScript Library v2.2.4
317 * http://jquery.com/
318 *
319 * Includes Sizzle.js
320 * http://sizzlejs.com/
321 *
322 * Copyright jQuery Foundation and other contributors
323 * Released under the MIT license
324 * http://jquery.org/license
325 *
326 * Date: 2016-05-20T17:23Z
327 */
328
329(function( global, factory ) {
330
331	if ( typeof module === "object" && typeof module.exports === "object" ) {
332		// For CommonJS and CommonJS-like environments where a proper `window`
333		// is present, execute the factory and get jQuery.
334		// For environments that do not have a `window` with a `document`
335		// (such as Node.js), expose a factory as module.exports.
336		// This accentuates the need for the creation of a real `window`.
337		// e.g. var jQuery = require("jquery")(window);
338		// See ticket #14549 for more info.
339		module.exports = global.document ?
340			factory( global, true ) :
341			function( w ) {
342				if ( !w.document ) {
343					throw new Error( "jQuery requires a window with a document" );
344				}
345				return factory( w );
346			};
347	} else {
348		factory( global );
349	}
350
351// Pass this if window is not defined yet
352}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
353
354// Support: Firefox 18+
355// Can't be in strict mode, several libs including ASP.NET trace
356// the stack via arguments.caller.callee and Firefox dies if
357// you try to trace through "use strict" call chains. (#13335)
358//"use strict";
359var arr = [];
360
361var document = window.document;
362
363var slice = arr.slice;
364
365var concat = arr.concat;
366
367var push = arr.push;
368
369var indexOf = arr.indexOf;
370
371var class2type = {};
372
373var toString = class2type.toString;
374
375var hasOwn = class2type.hasOwnProperty;
376
377var support = {};
378
379
380
381var
382	version = "2.2.4",
383
384	// Define a local copy of jQuery
385	jQuery = function( selector, context ) {
386
387		// The jQuery object is actually just the init constructor 'enhanced'
388		// Need init if jQuery is called (just allow error to be thrown if not included)
389		return new jQuery.fn.init( selector, context );
390	},
391
392	// Support: Android<4.1
393	// Make sure we trim BOM and NBSP
394	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
395
396	// Matches dashed string for camelizing
397	rmsPrefix = /^-ms-/,
398	rdashAlpha = /-([\da-z])/gi,
399
400	// Used by jQuery.camelCase as callback to replace()
401	fcamelCase = function( all, letter ) {
402		return letter.toUpperCase();
403	};
404
405jQuery.fn = jQuery.prototype = {
406
407	// The current version of jQuery being used
408	jquery: version,
409
410	constructor: jQuery,
411
412	// Start with an empty selector
413	selector: "",
414
415	// The default length of a jQuery object is 0
416	length: 0,
417
418	toArray: function() {
419		return slice.call( this );
420	},
421
422	// Get the Nth element in the matched element set OR
423	// Get the whole matched element set as a clean array
424	get: function( num ) {
425		return num != null ?
426
427			// Return just the one element from the set
428			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
429
430			// Return all the elements in a clean array
431			slice.call( this );
432	},
433
434	// Take an array of elements and push it onto the stack
435	// (returning the new matched element set)
436	pushStack: function( elems ) {
437
438		// Build a new jQuery matched element set
439		var ret = jQuery.merge( this.constructor(), elems );
440
441		// Add the old object onto the stack (as a reference)
442		ret.prevObject = this;
443		ret.context = this.context;
444
445		// Return the newly-formed element set
446		return ret;
447	},
448
449	// Execute a callback for every element in the matched set.
450	each: function( callback ) {
451		return jQuery.each( this, callback );
452	},
453
454	map: function( callback ) {
455		return this.pushStack( jQuery.map( this, function( elem, i ) {
456			return callback.call( elem, i, elem );
457		} ) );
458	},
459
460	slice: function() {
461		return this.pushStack( slice.apply( this, arguments ) );
462	},
463
464	first: function() {
465		return this.eq( 0 );
466	},
467
468	last: function() {
469		return this.eq( -1 );
470	},
471
472	eq: function( i ) {
473		var len = this.length,
474			j = +i + ( i < 0 ? len : 0 );
475		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
476	},
477
478	end: function() {
479		return this.prevObject || this.constructor();
480	},
481
482	// For internal use only.
483	// Behaves like an Array's method, not like a jQuery method.
484	push: push,
485	sort: arr.sort,
486	splice: arr.splice
487};
488
489jQuery.extend = jQuery.fn.extend = function() {
490	var options, name, src, copy, copyIsArray, clone,
491		target = arguments[ 0 ] || {},
492		i = 1,
493		length = arguments.length,
494		deep = false;
495
496	// Handle a deep copy situation
497	if ( typeof target === "boolean" ) {
498		deep = target;
499
500		// Skip the boolean and the target
501		target = arguments[ i ] || {};
502		i++;
503	}
504
505	// Handle case when target is a string or something (possible in deep copy)
506	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
507		target = {};
508	}
509
510	// Extend jQuery itself if only one argument is passed
511	if ( i === length ) {
512		target = this;
513		i--;
514	}
515
516	for ( ; i < length; i++ ) {
517
518		// Only deal with non-null/undefined values
519		if ( ( options = arguments[ i ] ) != null ) {
520
521			// Extend the base object
522			for ( name in options ) {
523				src = target[ name ];
524				copy = options[ name ];
525
526				// Prevent never-ending loop
527				if ( target === copy ) {
528					continue;
529				}
530
531				// Recurse if we're merging plain objects or arrays
532				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
533					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
534
535					if ( copyIsArray ) {
536						copyIsArray = false;
537						clone = src && jQuery.isArray( src ) ? src : [];
538
539					} else {
540						clone = src && jQuery.isPlainObject( src ) ? src : {};
541					}
542
543					// Never move original objects, clone them
544					target[ name ] = jQuery.extend( deep, clone, copy );
545
546				// Don't bring in undefined values
547				} else if ( copy !== undefined ) {
548					target[ name ] = copy;
549				}
550			}
551		}
552	}
553
554	// Return the modified object
555	return target;
556};
557
558jQuery.extend( {
559
560	// Unique for each copy of jQuery on the page
561	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
562
563	// Assume jQuery is ready without the ready module
564	isReady: true,
565
566	error: function( msg ) {
567		throw new Error( msg );
568	},
569
570	noop: function() {},
571
572	isFunction: function( obj ) {
573		return jQuery.type( obj ) === "function";
574	},
575
576	isArray: Array.isArray,
577
578	isWindow: function( obj ) {
579		return obj != null && obj === obj.window;
580	},
581
582	isNumeric: function( obj ) {
583
584		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
585		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
586		// subtraction forces infinities to NaN
587		// adding 1 corrects loss of precision from parseFloat (#15100)
588		var realStringObj = obj && obj.toString();
589		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
590	},
591
592	isPlainObject: function( obj ) {
593		var key;
594
595		// Not plain objects:
596		// - Any object or value whose internal [[Class]] property is not "[object Object]"
597		// - DOM nodes
598		// - window
599		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
600			return false;
601		}
602
603		// Not own constructor property must be Object
604		if ( obj.constructor &&
605				!hasOwn.call( obj, "constructor" ) &&
606				!hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
607			return false;
608		}
609
610		// Own properties are enumerated firstly, so to speed up,
611		// if last one is own, then all properties are own
612		for ( key in obj ) {}
613
614		return key === undefined || hasOwn.call( obj, key );
615	},
616
617	isEmptyObject: function( obj ) {
618		var name;
619		for ( name in obj ) {
620			return false;
621		}
622		return true;
623	},
624
625	type: function( obj ) {
626		if ( obj == null ) {
627			return obj + "";
628		}
629
630		// Support: Android<4.0, iOS<6 (functionish RegExp)
631		return typeof obj === "object" || typeof obj === "function" ?
632			class2type[ toString.call( obj ) ] || "object" :
633			typeof obj;
634	},
635
636	// Evaluates a script in a global context
637	globalEval: function( code ) {
638		var script,
639			indirect = eval;
640
641		code = jQuery.trim( code );
642
643		if ( code ) {
644
645			// If the code includes a valid, prologue position
646			// strict mode pragma, execute code by injecting a
647			// script tag into the document.
648			if ( code.indexOf( "use strict" ) === 1 ) {
649				script = document.createElement( "script" );
650				script.text = code;
651				document.head.appendChild( script ).parentNode.removeChild( script );
652			} else {
653
654				// Otherwise, avoid the DOM node creation, insertion
655				// and removal by using an indirect global eval
656
657				indirect( code );
658			}
659		}
660	},
661
662	// Convert dashed to camelCase; used by the css and data modules
663	// Support: IE9-11+
664	// Microsoft forgot to hump their vendor prefix (#9572)
665	camelCase: function( string ) {
666		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
667	},
668
669	nodeName: function( elem, name ) {
670		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
671	},
672
673	each: function( obj, callback ) {
674		var length, i = 0;
675
676		if ( isArrayLike( obj ) ) {
677			length = obj.length;
678			for ( ; i < length; i++ ) {
679				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
680					break;
681				}
682			}
683		} else {
684			for ( i in obj ) {
685				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
686					break;
687				}
688			}
689		}
690
691		return obj;
692	},
693
694	// Support: Android<4.1
695	trim: function( text ) {
696		return text == null ?
697			"" :
698			( text + "" ).replace( rtrim, "" );
699	},
700
701	// results is for internal usage only
702	makeArray: function( arr, results ) {
703		var ret = results || [];
704
705		if ( arr != null ) {
706			if ( isArrayLike( Object( arr ) ) ) {
707				jQuery.merge( ret,
708					typeof arr === "string" ?
709					[ arr ] : arr
710				);
711			} else {
712				push.call( ret, arr );
713			}
714		}
715
716		return ret;
717	},
718
719	inArray: function( elem, arr, i ) {
720		return arr == null ? -1 : indexOf.call( arr, elem, i );
721	},
722
723	merge: function( first, second ) {
724		var len = +second.length,
725			j = 0,
726			i = first.length;
727
728		for ( ; j < len; j++ ) {
729			first[ i++ ] = second[ j ];
730		}
731
732		first.length = i;
733
734		return first;
735	},
736
737	grep: function( elems, callback, invert ) {
738		var callbackInverse,
739			matches = [],
740			i = 0,
741			length = elems.length,
742			callbackExpect = !invert;
743
744		// Go through the array, only saving the items
745		// that pass the validator function
746		for ( ; i < length; i++ ) {
747			callbackInverse = !callback( elems[ i ], i );
748			if ( callbackInverse !== callbackExpect ) {
749				matches.push( elems[ i ] );
750			}
751		}
752
753		return matches;
754	},
755
756	// arg is for internal usage only
757	map: function( elems, callback, arg ) {
758		var length, value,
759			i = 0,
760			ret = [];
761
762		// Go through the array, translating each of the items to their new values
763		if ( isArrayLike( elems ) ) {
764			length = elems.length;
765			for ( ; i < length; i++ ) {
766				value = callback( elems[ i ], i, arg );
767
768				if ( value != null ) {
769					ret.push( value );
770				}
771			}
772
773		// Go through every key on the object,
774		} else {
775			for ( i in elems ) {
776				value = callback( elems[ i ], i, arg );
777
778				if ( value != null ) {
779					ret.push( value );
780				}
781			}
782		}
783
784		// Flatten any nested arrays
785		return concat.apply( [], ret );
786	},
787
788	// A global GUID counter for objects
789	guid: 1,
790
791	// Bind a function to a context, optionally partially applying any
792	// arguments.
793	proxy: function( fn, context ) {
794		var tmp, args, proxy;
795
796		if ( typeof context === "string" ) {
797			tmp = fn[ context ];
798			context = fn;
799			fn = tmp;
800		}
801
802		// Quick check to determine if target is callable, in the spec
803		// this throws a TypeError, but we will just return undefined.
804		if ( !jQuery.isFunction( fn ) ) {
805			return undefined;
806		}
807
808		// Simulated bind
809		args = slice.call( arguments, 2 );
810		proxy = function() {
811			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
812		};
813
814		// Set the guid of unique handler to the same of original handler, so it can be removed
815		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
816
817		return proxy;
818	},
819
820	now: Date.now,
821
822	// jQuery.support is not used in Core but other projects attach their
823	// properties to it so it needs to exist.
824	support: support
825} );
826
827// JSHint would error on this code due to the Symbol not being defined in ES5.
828// Defining this global in .jshintrc would create a danger of using the global
829// unguarded in another place, it seems safer to just disable JSHint for these
830// three lines.
831/* jshint ignore: start */
832if ( typeof Symbol === "function" ) {
833	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
834}
835/* jshint ignore: end */
836
837// Populate the class2type map
838jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
839function( i, name ) {
840	class2type[ "[object " + name + "]" ] = name.toLowerCase();
841} );
842
843function isArrayLike( obj ) {
844
845	// Support: iOS 8.2 (not reproducible in simulator)
846	// `in` check used to prevent JIT error (gh-2145)
847	// hasOwn isn't used here due to false negatives
848	// regarding Nodelist length in IE
849	var length = !!obj && "length" in obj && obj.length,
850		type = jQuery.type( obj );
851
852	if ( type === "function" || jQuery.isWindow( obj ) ) {
853		return false;
854	}
855
856	return type === "array" || length === 0 ||
857		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
858}
859var Sizzle =
860/*!
861 * Sizzle CSS Selector Engine v2.2.1
862 * http://sizzlejs.com/
863 *
864 * Copyright jQuery Foundation and other contributors
865 * Released under the MIT license
866 * http://jquery.org/license
867 *
868 * Date: 2015-10-17
869 */
870(function( window ) {
871
872var i,
873	support,
874	Expr,
875	getText,
876	isXML,
877	tokenize,
878	compile,
879	select,
880	outermostContext,
881	sortInput,
882	hasDuplicate,
883
884	// Local document vars
885	setDocument,
886	document,
887	docElem,
888	documentIsHTML,
889	rbuggyQSA,
890	rbuggyMatches,
891	matches,
892	contains,
893
894	// Instance-specific data
895	expando = "sizzle" + 1 * new Date(),
896	preferredDoc = window.document,
897	dirruns = 0,
898	done = 0,
899	classCache = createCache(),
900	tokenCache = createCache(),
901	compilerCache = createCache(),
902	sortOrder = function( a, b ) {
903		if ( a === b ) {
904			hasDuplicate = true;
905		}
906		return 0;
907	},
908
909	// General-purpose constants
910	MAX_NEGATIVE = 1 << 31,
911
912	// Instance methods
913	hasOwn = ({}).hasOwnProperty,
914	arr = [],
915	pop = arr.pop,
916	push_native = arr.push,
917	push = arr.push,
918	slice = arr.slice,
919	// Use a stripped-down indexOf as it's faster than native
920	// http://jsperf.com/thor-indexof-vs-for/5
921	indexOf = function( list, elem ) {
922		var i = 0,
923			len = list.length;
924		for ( ; i < len; i++ ) {
925			if ( list[i] === elem ) {
926				return i;
927			}
928		}
929		return -1;
930	},
931
932	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
933
934	// Regular expressions
935
936	// http://www.w3.org/TR/css3-selectors/#whitespace
937	whitespace = "[\\x20\\t\\r\\n\\f]",
938
939	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
940	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
941
942	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
943	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
944		// Operator (capture 2)
945		"*([*^$|!~]?=)" + whitespace +
946		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
947		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
948		"*\\]",
949
950	pseudos = ":(" + identifier + ")(?:\\((" +
951		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
952		// 1. quoted (capture 3; capture 4 or capture 5)
953		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
954		// 2. simple (capture 6)
955		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
956		// 3. anything else (capture 2)
957		".*" +
958		")\\)|)",
959
960	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
961	rwhitespace = new RegExp( whitespace + "+", "g" ),
962	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
963
964	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
965	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
966
967	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
968
969	rpseudo = new RegExp( pseudos ),
970	ridentifier = new RegExp( "^" + identifier + "$" ),
971
972	matchExpr = {
973		"ID": new RegExp( "^#(" + identifier + ")" ),
974		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
975		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
976		"ATTR": new RegExp( "^" + attributes ),
977		"PSEUDO": new RegExp( "^" + pseudos ),
978		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
979			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
980			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
981		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
982		// For use in libraries implementing .is()
983		// We use this for POS matching in `select`
984		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
985			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
986	},
987
988	rinputs = /^(?:input|select|textarea|button)$/i,
989	rheader = /^h\d$/i,
990
991	rnative = /^[^{]+\{\s*\[native \w/,
992
993	// Easily-parseable/retrievable ID or TAG or CLASS selectors
994	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
995
996	rsibling = /[+~]/,
997	rescape = /'|\\/g,
998
999	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
1000	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
1001	funescape = function( _, escaped, escapedWhitespace ) {
1002		var high = "0x" + escaped - 0x10000;
1003		// NaN means non-codepoint
1004		// Support: Firefox<24
1005		// Workaround erroneous numeric interpretation of +"0x"
1006		return high !== high || escapedWhitespace ?
1007			escaped :
1008			high < 0 ?
1009				// BMP codepoint
1010				String.fromCharCode( high + 0x10000 ) :
1011				// Supplemental Plane codepoint (surrogate pair)
1012				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
1013	},
1014
1015	// Used for iframes
1016	// See setDocument()
1017	// Removing the function wrapper causes a "Permission Denied"
1018	// error in IE
1019	unloadHandler = function() {
1020		setDocument();
1021	};
1022
1023// Optimize for push.apply( _, NodeList )
1024try {
1025	push.apply(
1026		(arr = slice.call( preferredDoc.childNodes )),
1027		preferredDoc.childNodes
1028	);
1029	// Support: Android<4.0
1030	// Detect silently failing push.apply
1031	arr[ preferredDoc.childNodes.length ].nodeType;
1032} catch ( e ) {
1033	push = { apply: arr.length ?
1034
1035		// Leverage slice if possible
1036		function( target, els ) {
1037			push_native.apply( target, slice.call(els) );
1038		} :
1039
1040		// Support: IE<9
1041		// Otherwise append directly
1042		function( target, els ) {
1043			var j = target.length,
1044				i = 0;
1045			// Can't trust NodeList.length
1046			while ( (target[j++] = els[i++]) ) {}
1047			target.length = j - 1;
1048		}
1049	};
1050}
1051
1052function Sizzle( selector, context, results, seed ) {
1053	var m, i, elem, nid, nidselect, match, groups, newSelector,
1054		newContext = context && context.ownerDocument,
1055
1056		// nodeType defaults to 9, since context defaults to document
1057		nodeType = context ? context.nodeType : 9;
1058
1059	results = results || [];
1060
1061	// Return early from calls with invalid selector or context
1062	if ( typeof selector !== "string" || !selector ||
1063		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
1064
1065		return results;
1066	}
1067
1068	// Try to shortcut find operations (as opposed to filters) in HTML documents
1069	if ( !seed ) {
1070
1071		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
1072			setDocument( context );
1073		}
1074		context = context || document;
1075
1076		if ( documentIsHTML ) {
1077
1078			// If the selector is sufficiently simple, try using a "get*By*" DOM method
1079			// (excepting DocumentFragment context, where the methods don't exist)
1080			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
1081
1082				// ID selector
1083				if ( (m = match[1]) ) {
1084
1085					// Document context
1086					if ( nodeType === 9 ) {
1087						if ( (elem = context.getElementById( m )) ) {
1088
1089							// Support: IE, Opera, Webkit
1090							// TODO: identify versions
1091							// getElementById can match elements by name instead of ID
1092							if ( elem.id === m ) {
1093								results.push( elem );
1094								return results;
1095							}
1096						} else {
1097							return results;
1098						}
1099
1100					// Element context
1101					} else {
1102
1103						// Support: IE, Opera, Webkit
1104						// TODO: identify versions
1105						// getElementById can match elements by name instead of ID
1106						if ( newContext && (elem = newContext.getElementById( m )) &&
1107							contains( context, elem ) &&
1108							elem.id === m ) {
1109
1110							results.push( elem );
1111							return results;
1112						}
1113					}
1114
1115				// Type selector
1116				} else if ( match[2] ) {
1117					push.apply( results, context.getElementsByTagName( selector ) );
1118					return results;
1119
1120				// Class selector
1121				} else if ( (m = match[3]) && support.getElementsByClassName &&
1122					context.getElementsByClassName ) {
1123
1124					push.apply( results, context.getElementsByClassName( m ) );
1125					return results;
1126				}
1127			}
1128
1129			// Take advantage of querySelectorAll
1130			if ( support.qsa &&
1131				!compilerCache[ selector + " " ] &&
1132				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
1133
1134				if ( nodeType !== 1 ) {
1135					newContext = context;
1136					newSelector = selector;
1137
1138				// qSA looks outside Element context, which is not what we want
1139				// Thanks to Andrew Dupont for this workaround technique
1140				// Support: IE <=8
1141				// Exclude object elements
1142				} else if ( context.nodeName.toLowerCase() !== "object" ) {
1143
1144					// Capture the context ID, setting it first if necessary
1145					if ( (nid = context.getAttribute( "id" )) ) {
1146						nid = nid.replace( rescape, "\\$&" );
1147					} else {
1148						context.setAttribute( "id", (nid = expando) );
1149					}
1150
1151					// Prefix every selector in the list
1152					groups = tokenize( selector );
1153					i = groups.length;
1154					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
1155					while ( i-- ) {
1156						groups[i] = nidselect + " " + toSelector( groups[i] );
1157					}
1158					newSelector = groups.join( "," );
1159
1160					// Expand context for sibling selectors
1161					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
1162						context;
1163				}
1164
1165				if ( newSelector ) {
1166					try {
1167						push.apply( results,
1168							newContext.querySelectorAll( newSelector )
1169						);
1170						return results;
1171					} catch ( qsaError ) {
1172					} finally {
1173						if ( nid === expando ) {
1174							context.removeAttribute( "id" );
1175						}
1176					}
1177				}
1178			}
1179		}
1180	}
1181
1182	// All others
1183	return select( selector.replace( rtrim, "$1" ), context, results, seed );
1184}
1185
1186/**
1187 * Create key-value caches of limited size
1188 * @returns {function(string, object)} Returns the Object data after storing it on itself with
1189 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
1190 *	deleting the oldest entry
1191 */
1192function createCache() {
1193	var keys = [];
1194
1195	function cache( key, value ) {
1196		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
1197		if ( keys.push( key + " " ) > Expr.cacheLength ) {
1198			// Only keep the most recent entries
1199			delete cache[ keys.shift() ];
1200		}
1201		return (cache[ key + " " ] = value);
1202	}
1203	return cache;
1204}
1205
1206/**
1207 * Mark a function for special use by Sizzle
1208 * @param {Function} fn The function to mark
1209 */
1210function markFunction( fn ) {
1211	fn[ expando ] = true;
1212	return fn;
1213}
1214
1215/**
1216 * Support testing using an element
1217 * @param {Function} fn Passed the created div and expects a boolean result
1218 */
1219function assert( fn ) {
1220	var div = document.createElement("div");
1221
1222	try {
1223		return !!fn( div );
1224	} catch (e) {
1225		return false;
1226	} finally {
1227		// Remove from its parent by default
1228		if ( div.parentNode ) {
1229			div.parentNode.removeChild( div );
1230		}
1231		// release memory in IE
1232		div = null;
1233	}
1234}
1235
1236/**
1237 * Adds the same handler for all of the specified attrs
1238 * @param {String} attrs Pipe-separated list of attributes
1239 * @param {Function} handler The method that will be applied
1240 */
1241function addHandle( attrs, handler ) {
1242	var arr = attrs.split("|"),
1243		i = arr.length;
1244
1245	while ( i-- ) {
1246		Expr.attrHandle[ arr[i] ] = handler;
1247	}
1248}
1249
1250/**
1251 * Checks document order of two siblings
1252 * @param {Element} a
1253 * @param {Element} b
1254 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1255 */
1256function siblingCheck( a, b ) {
1257	var cur = b && a,
1258		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
1259			( ~b.sourceIndex || MAX_NEGATIVE ) -
1260			( ~a.sourceIndex || MAX_NEGATIVE );
1261
1262	// Use IE sourceIndex if available on both nodes
1263	if ( diff ) {
1264		return diff;
1265	}
1266
1267	// Check if b follows a
1268	if ( cur ) {
1269		while ( (cur = cur.nextSibling) ) {
1270			if ( cur === b ) {
1271				return -1;
1272			}
1273		}
1274	}
1275
1276	return a ? 1 : -1;
1277}
1278
1279/**
1280 * Returns a function to use in pseudos for input types
1281 * @param {String} type
1282 */
1283function createInputPseudo( type ) {
1284	return function( elem ) {
1285		var name = elem.nodeName.toLowerCase();
1286		return name === "input" && elem.type === type;
1287	};
1288}
1289
1290/**
1291 * Returns a function to use in pseudos for buttons
1292 * @param {String} type
1293 */
1294function createButtonPseudo( type ) {
1295	return function( elem ) {
1296		var name = elem.nodeName.toLowerCase();
1297		return (name === "input" || name === "button") && elem.type === type;
1298	};
1299}
1300
1301/**
1302 * Returns a function to use in pseudos for positionals
1303 * @param {Function} fn
1304 */
1305function createPositionalPseudo( fn ) {
1306	return markFunction(function( argument ) {
1307		argument = +argument;
1308		return markFunction(function( seed, matches ) {
1309			var j,
1310				matchIndexes = fn( [], seed.length, argument ),
1311				i = matchIndexes.length;
1312
1313			// Match elements found at the specified indexes
1314			while ( i-- ) {
1315				if ( seed[ (j = matchIndexes[i]) ] ) {
1316					seed[j] = !(matches[j] = seed[j]);
1317				}
1318			}
1319		});
1320	});
1321}
1322
1323/**
1324 * Checks a node for validity as a Sizzle context
1325 * @param {Element|Object=} context
1326 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1327 */
1328function testContext( context ) {
1329	return context && typeof context.getElementsByTagName !== "undefined" && context;
1330}
1331
1332// Expose support vars for convenience
1333support = Sizzle.support = {};
1334
1335/**
1336 * Detects XML nodes
1337 * @param {Element|Object} elem An element or a document
1338 * @returns {Boolean} True iff elem is a non-HTML XML node
1339 */
1340isXML = Sizzle.isXML = function( elem ) {
1341	// documentElement is verified for cases where it doesn't yet exist
1342	// (such as loading iframes in IE - #4833)
1343	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1344	return documentElement ? documentElement.nodeName !== "HTML" : false;
1345};
1346
1347/**
1348 * Sets document-related variables once based on the current document
1349 * @param {Element|Object} [doc] An element or document object to use to set the document
1350 * @returns {Object} Returns the current document
1351 */
1352setDocument = Sizzle.setDocument = function( node ) {
1353	var hasCompare, parent,
1354		doc = node ? node.ownerDocument || node : preferredDoc;
1355
1356	// Return early if doc is invalid or already selected
1357	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1358		return document;
1359	}
1360
1361	// Update global variables
1362	document = doc;
1363	docElem = document.documentElement;
1364	documentIsHTML = !isXML( document );
1365
1366	// Support: IE 9-11, Edge
1367	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1368	if ( (parent = document.defaultView) && parent.top !== parent ) {
1369		// Support: IE 11
1370		if ( parent.addEventListener ) {
1371			parent.addEventListener( "unload", unloadHandler, false );
1372
1373		// Support: IE 9 - 10 only
1374		} else if ( parent.attachEvent ) {
1375			parent.attachEvent( "onunload", unloadHandler );
1376		}
1377	}
1378
1379	/* Attributes
1380	---------------------------------------------------------------------- */
1381
1382	// Support: IE<8
1383	// Verify that getAttribute really returns attributes and not properties
1384	// (excepting IE8 booleans)
1385	support.attributes = assert(function( div ) {
1386		div.className = "i";
1387		return !div.getAttribute("className");
1388	});
1389
1390	/* getElement(s)By*
1391	---------------------------------------------------------------------- */
1392
1393	// Check if getElementsByTagName("*") returns only elements
1394	support.getElementsByTagName = assert(function( div ) {
1395		div.appendChild( document.createComment("") );
1396		return !div.getElementsByTagName("*").length;
1397	});
1398
1399	// Support: IE<9
1400	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1401
1402	// Support: IE<10
1403	// Check if getElementById returns elements by name
1404	// The broken getElementById methods don't pick up programatically-set names,
1405	// so use a roundabout getElementsByName test
1406	support.getById = assert(function( div ) {
1407		docElem.appendChild( div ).id = expando;
1408		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1409	});
1410
1411	// ID find and filter
1412	if ( support.getById ) {
1413		Expr.find["ID"] = function( id, context ) {
1414			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1415				var m = context.getElementById( id );
1416				return m ? [ m ] : [];
1417			}
1418		};
1419		Expr.filter["ID"] = function( id ) {
1420			var attrId = id.replace( runescape, funescape );
1421			return function( elem ) {
1422				return elem.getAttribute("id") === attrId;
1423			};
1424		};
1425	} else {
1426		// Support: IE6/7
1427		// getElementById is not reliable as a find shortcut
1428		delete Expr.find["ID"];
1429
1430		Expr.filter["ID"] =  function( id ) {
1431			var attrId = id.replace( runescape, funescape );
1432			return function( elem ) {
1433				var node = typeof elem.getAttributeNode !== "undefined" &&
1434					elem.getAttributeNode("id");
1435				return node && node.value === attrId;
1436			};
1437		};
1438	}
1439
1440	// Tag
1441	Expr.find["TAG"] = support.getElementsByTagName ?
1442		function( tag, context ) {
1443			if ( typeof context.getElementsByTagName !== "undefined" ) {
1444				return context.getElementsByTagName( tag );
1445
1446			// DocumentFragment nodes don't have gEBTN
1447			} else if ( support.qsa ) {
1448				return context.querySelectorAll( tag );
1449			}
1450		} :
1451
1452		function( tag, context ) {
1453			var elem,
1454				tmp = [],
1455				i = 0,
1456				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1457				results = context.getElementsByTagName( tag );
1458
1459			// Filter out possible comments
1460			if ( tag === "*" ) {
1461				while ( (elem = results[i++]) ) {
1462					if ( elem.nodeType === 1 ) {
1463						tmp.push( elem );
1464					}
1465				}
1466
1467				return tmp;
1468			}
1469			return results;
1470		};
1471
1472	// Class
1473	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1474		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1475			return context.getElementsByClassName( className );
1476		}
1477	};
1478
1479	/* QSA/matchesSelector
1480	---------------------------------------------------------------------- */
1481
1482	// QSA and matchesSelector support
1483
1484	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1485	rbuggyMatches = [];
1486
1487	// qSa(:focus) reports false when true (Chrome 21)
1488	// We allow this because of a bug in IE8/9 that throws an error
1489	// whenever `document.activeElement` is accessed on an iframe
1490	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1491	// See http://bugs.jquery.com/ticket/13378
1492	rbuggyQSA = [];
1493
1494	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1495		// Build QSA regex
1496		// Regex strategy adopted from Diego Perini
1497		assert(function( div ) {
1498			// Select is set to empty string on purpose
1499			// This is to test IE's treatment of not explicitly
1500			// setting a boolean content attribute,
1501			// since its presence should be enough
1502			// http://bugs.jquery.com/ticket/12359
1503			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1504				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1505				"<option selected=''></option></select>";
1506
1507			// Support: IE8, Opera 11-12.16
1508			// Nothing should be selected when empty strings follow ^= or $= or *=
1509			// The test attribute must be unknown in Opera but "safe" for WinRT
1510			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1511			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1512				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1513			}
1514
1515			// Support: IE8
1516			// Boolean attributes and "value" are not treated correctly
1517			if ( !div.querySelectorAll("[selected]").length ) {
1518				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1519			}
1520
1521			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1522			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1523				rbuggyQSA.push("~=");
1524			}
1525
1526			// Webkit/Opera - :checked should return selected option elements
1527			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1528			// IE8 throws error here and will not see later tests
1529			if ( !div.querySelectorAll(":checked").length ) {
1530				rbuggyQSA.push(":checked");
1531			}
1532
1533			// Support: Safari 8+, iOS 8+
1534			// https://bugs.webkit.org/show_bug.cgi?id=136851
1535			// In-page `selector#id sibing-combinator selector` fails
1536			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1537				rbuggyQSA.push(".#.+[+~]");
1538			}
1539		});
1540
1541		assert(function( div ) {
1542			// Support: Windows 8 Native Apps
1543			// The type and name attributes are restricted during .innerHTML assignment
1544			var input = document.createElement("input");
1545			input.setAttribute( "type", "hidden" );
1546			div.appendChild( input ).setAttribute( "name", "D" );
1547
1548			// Support: IE8
1549			// Enforce case-sensitivity of name attribute
1550			if ( div.querySelectorAll("[name=d]").length ) {
1551				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1552			}
1553
1554			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1555			// IE8 throws error here and will not see later tests
1556			if ( !div.querySelectorAll(":enabled").length ) {
1557				rbuggyQSA.push( ":enabled", ":disabled" );
1558			}
1559
1560			// Opera 10-11 does not throw on post-comma invalid pseudos
1561			div.querySelectorAll("*,:x");
1562			rbuggyQSA.push(",.*:");
1563		});
1564	}
1565
1566	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1567		docElem.webkitMatchesSelector ||
1568		docElem.mozMatchesSelector ||
1569		docElem.oMatchesSelector ||
1570		docElem.msMatchesSelector) )) ) {
1571
1572		assert(function( div ) {
1573			// Check to see if it's possible to do matchesSelector
1574			// on a disconnected node (IE 9)
1575			support.disconnectedMatch = matches.call( div, "div" );
1576
1577			// This should fail with an exception
1578			// Gecko does not error, returns false instead
1579			matches.call( div, "[s!='']:x" );
1580			rbuggyMatches.push( "!=", pseudos );
1581		});
1582	}
1583
1584	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1585	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1586
1587	/* Contains
1588	---------------------------------------------------------------------- */
1589	hasCompare = rnative.test( docElem.compareDocumentPosition );
1590
1591	// Element contains another
1592	// Purposefully self-exclusive
1593	// As in, an element does not contain itself
1594	contains = hasCompare || rnative.test( docElem.contains ) ?
1595		function( a, b ) {
1596			var adown = a.nodeType === 9 ? a.documentElement : a,
1597				bup = b && b.parentNode;
1598			return a === bup || !!( bup && bup.nodeType === 1 && (
1599				adown.contains ?
1600					adown.contains( bup ) :
1601					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1602			));
1603		} :
1604		function( a, b ) {
1605			if ( b ) {
1606				while ( (b = b.parentNode) ) {
1607					if ( b === a ) {
1608						return true;
1609					}
1610				}
1611			}
1612			return false;
1613		};
1614
1615	/* Sorting
1616	---------------------------------------------------------------------- */
1617
1618	// Document order sorting
1619	sortOrder = hasCompare ?
1620	function( a, b ) {
1621
1622		// Flag for duplicate removal
1623		if ( a === b ) {
1624			hasDuplicate = true;
1625			return 0;
1626		}
1627
1628		// Sort on method existence if only one input has compareDocumentPosition
1629		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1630		if ( compare ) {
1631			return compare;
1632		}
1633
1634		// Calculate position if both inputs belong to the same document
1635		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1636			a.compareDocumentPosition( b ) :
1637
1638			// Otherwise we know they are disconnected
1639			1;
1640
1641		// Disconnected nodes
1642		if ( compare & 1 ||
1643			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1644
1645			// Choose the first element that is related to our preferred document
1646			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1647				return -1;
1648			}
1649			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1650				return 1;
1651			}
1652
1653			// Maintain original order
1654			return sortInput ?
1655				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1656				0;
1657		}
1658
1659		return compare & 4 ? -1 : 1;
1660	} :
1661	function( a, b ) {
1662		// Exit early if the nodes are identical
1663		if ( a === b ) {
1664			hasDuplicate = true;
1665			return 0;
1666		}
1667
1668		var cur,
1669			i = 0,
1670			aup = a.parentNode,
1671			bup = b.parentNode,
1672			ap = [ a ],
1673			bp = [ b ];
1674
1675		// Parentless nodes are either documents or disconnected
1676		if ( !aup || !bup ) {
1677			return a === document ? -1 :
1678				b === document ? 1 :
1679				aup ? -1 :
1680				bup ? 1 :
1681				sortInput ?
1682				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1683				0;
1684
1685		// If the nodes are siblings, we can do a quick check
1686		} else if ( aup === bup ) {
1687			return siblingCheck( a, b );
1688		}
1689
1690		// Otherwise we need full lists of their ancestors for comparison
1691		cur = a;
1692		while ( (cur = cur.parentNode) ) {
1693			ap.unshift( cur );
1694		}
1695		cur = b;
1696		while ( (cur = cur.parentNode) ) {
1697			bp.unshift( cur );
1698		}
1699
1700		// Walk down the tree looking for a discrepancy
1701		while ( ap[i] === bp[i] ) {
1702			i++;
1703		}
1704
1705		return i ?
1706			// Do a sibling check if the nodes have a common ancestor
1707			siblingCheck( ap[i], bp[i] ) :
1708
1709			// Otherwise nodes in our document sort first
1710			ap[i] === preferredDoc ? -1 :
1711			bp[i] === preferredDoc ? 1 :
1712			0;
1713	};
1714
1715	return document;
1716};
1717
1718Sizzle.matches = function( expr, elements ) {
1719	return Sizzle( expr, null, null, elements );
1720};
1721
1722Sizzle.matchesSelector = function( elem, expr ) {
1723	// Set document vars if needed
1724	if ( ( elem.ownerDocument || elem ) !== document ) {
1725		setDocument( elem );
1726	}
1727
1728	// Make sure that attribute selectors are quoted
1729	expr = expr.replace( rattributeQuotes, "='$1']" );
1730
1731	if ( support.matchesSelector && documentIsHTML &&
1732		!compilerCache[ expr + " " ] &&
1733		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1734		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1735
1736		try {
1737			var ret = matches.call( elem, expr );
1738
1739			// IE 9's matchesSelector returns false on disconnected nodes
1740			if ( ret || support.disconnectedMatch ||
1741					// As well, disconnected nodes are said to be in a document
1742					// fragment in IE 9
1743					elem.document && elem.document.nodeType !== 11 ) {
1744				return ret;
1745			}
1746		} catch (e) {}
1747	}
1748
1749	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1750};
1751
1752Sizzle.contains = function( context, elem ) {
1753	// Set document vars if needed
1754	if ( ( context.ownerDocument || context ) !== document ) {
1755		setDocument( context );
1756	}
1757	return contains( context, elem );
1758};
1759
1760Sizzle.attr = function( elem, name ) {
1761	// Set document vars if needed
1762	if ( ( elem.ownerDocument || elem ) !== document ) {
1763		setDocument( elem );
1764	}
1765
1766	var fn = Expr.attrHandle[ name.toLowerCase() ],
1767		// Don't get fooled by Object.prototype properties (jQuery #13807)
1768		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1769			fn( elem, name, !documentIsHTML ) :
1770			undefined;
1771
1772	return val !== undefined ?
1773		val :
1774		support.attributes || !documentIsHTML ?
1775			elem.getAttribute( name ) :
1776			(val = elem.getAttributeNode(name)) && val.specified ?
1777				val.value :
1778				null;
1779};
1780
1781Sizzle.error = function( msg ) {
1782	throw new Error( "Syntax error, unrecognized expression: " + msg );
1783};
1784
1785/**
1786 * Document sorting and removing duplicates
1787 * @param {ArrayLike} results
1788 */
1789Sizzle.uniqueSort = function( results ) {
1790	var elem,
1791		duplicates = [],
1792		j = 0,
1793		i = 0;
1794
1795	// Unless we *know* we can detect duplicates, assume their presence
1796	hasDuplicate = !support.detectDuplicates;
1797	sortInput = !support.sortStable && results.slice( 0 );
1798	results.sort( sortOrder );
1799
1800	if ( hasDuplicate ) {
1801		while ( (elem = results[i++]) ) {
1802			if ( elem === results[ i ] ) {
1803				j = duplicates.push( i );
1804			}
1805		}
1806		while ( j-- ) {
1807			results.splice( duplicates[ j ], 1 );
1808		}
1809	}
1810
1811	// Clear input after sorting to release objects
1812	// See https://github.com/jquery/sizzle/pull/225
1813	sortInput = null;
1814
1815	return results;
1816};
1817
1818/**
1819 * Utility function for retrieving the text value of an array of DOM nodes
1820 * @param {Array|Element} elem
1821 */
1822getText = Sizzle.getText = function( elem ) {
1823	var node,
1824		ret = "",
1825		i = 0,
1826		nodeType = elem.nodeType;
1827
1828	if ( !nodeType ) {
1829		// If no nodeType, this is expected to be an array
1830		while ( (node = elem[i++]) ) {
1831			// Do not traverse comment nodes
1832			ret += getText( node );
1833		}
1834	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1835		// Use textContent for elements
1836		// innerText usage removed for consistency of new lines (jQuery #11153)
1837		if ( typeof elem.textContent === "string" ) {
1838			return elem.textContent;
1839		} else {
1840			// Traverse its children
1841			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1842				ret += getText( elem );
1843			}
1844		}
1845	} else if ( nodeType === 3 || nodeType === 4 ) {
1846		return elem.nodeValue;
1847	}
1848	// Do not include comment or processing instruction nodes
1849
1850	return ret;
1851};
1852
1853Expr = Sizzle.selectors = {
1854
1855	// Can be adjusted by the user
1856	cacheLength: 50,
1857
1858	createPseudo: markFunction,
1859
1860	match: matchExpr,
1861
1862	attrHandle: {},
1863
1864	find: {},
1865
1866	relative: {
1867		">": { dir: "parentNode", first: true },
1868		" ": { dir: "parentNode" },
1869		"+": { dir: "previousSibling", first: true },
1870		"~": { dir: "previousSibling" }
1871	},
1872
1873	preFilter: {
1874		"ATTR": function( match ) {
1875			match[1] = match[1].replace( runescape, funescape );
1876
1877			// Move the given value to match[3] whether quoted or unquoted
1878			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1879
1880			if ( match[2] === "~=" ) {
1881				match[3] = " " + match[3] + " ";
1882			}
1883
1884			return match.slice( 0, 4 );
1885		},
1886
1887		"CHILD": function( match ) {
1888			/* matches from matchExpr["CHILD"]
1889				1 type (only|nth|...)
1890				2 what (child|of-type)
1891				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1892				4 xn-component of xn+y argument ([+-]?\d*n|)
1893				5 sign of xn-component
1894				6 x of xn-component
1895				7 sign of y-component
1896				8 y of y-component
1897			*/
1898			match[1] = match[1].toLowerCase();
1899
1900			if ( match[1].slice( 0, 3 ) === "nth" ) {
1901				// nth-* requires argument
1902				if ( !match[3] ) {
1903					Sizzle.error( match[0] );
1904				}
1905
1906				// numeric x and y parameters for Expr.filter.CHILD
1907				// remember that false/true cast respectively to 0/1
1908				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1909				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1910
1911			// other types prohibit arguments
1912			} else if ( match[3] ) {
1913				Sizzle.error( match[0] );
1914			}
1915
1916			return match;
1917		},
1918
1919		"PSEUDO": function( match ) {
1920			var excess,
1921				unquoted = !match[6] && match[2];
1922
1923			if ( matchExpr["CHILD"].test( match[0] ) ) {
1924				return null;
1925			}
1926
1927			// Accept quoted arguments as-is
1928			if ( match[3] ) {
1929				match[2] = match[4] || match[5] || "";
1930
1931			// Strip excess characters from unquoted arguments
1932			} else if ( unquoted && rpseudo.test( unquoted ) &&
1933				// Get excess from tokenize (recursively)
1934				(excess = tokenize( unquoted, true )) &&
1935				// advance to the next closing parenthesis
1936				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1937
1938				// excess is a negative index
1939				match[0] = match[0].slice( 0, excess );
1940				match[2] = unquoted.slice( 0, excess );
1941			}
1942
1943			// Return only captures needed by the pseudo filter method (type and argument)
1944			return match.slice( 0, 3 );
1945		}
1946	},
1947
1948	filter: {
1949
1950		"TAG": function( nodeNameSelector ) {
1951			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1952			return nodeNameSelector === "*" ?
1953				function() { return true; } :
1954				function( elem ) {
1955					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1956				};
1957		},
1958
1959		"CLASS": function( className ) {
1960			var pattern = classCache[ className + " " ];
1961
1962			return pattern ||
1963				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1964				classCache( className, function( elem ) {
1965					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1966				});
1967		},
1968
1969		"ATTR": function( name, operator, check ) {
1970			return function( elem ) {
1971				var result = Sizzle.attr( elem, name );
1972
1973				if ( result == null ) {
1974					return operator === "!=";
1975				}
1976				if ( !operator ) {
1977					return true;
1978				}
1979
1980				result += "";
1981
1982				return operator === "=" ? result === check :
1983					operator === "!=" ? result !== check :
1984					operator === "^=" ? check && result.indexOf( check ) === 0 :
1985					operator === "*=" ? check && result.indexOf( check ) > -1 :
1986					operator === "$=" ? check && result.slice( -check.length ) === check :
1987					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1988					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1989					false;
1990			};
1991		},
1992
1993		"CHILD": function( type, what, argument, first, last ) {
1994			var simple = type.slice( 0, 3 ) !== "nth",
1995				forward = type.slice( -4 ) !== "last",
1996				ofType = what === "of-type";
1997
1998			return first === 1 && last === 0 ?
1999
2000				// Shortcut for :nth-*(n)
2001				function( elem ) {
2002					return !!elem.parentNode;
2003				} :
2004
2005				function( elem, context, xml ) {
2006					var cache, uniqueCache, outerCache, node, nodeIndex, start,
2007						dir = simple !== forward ? "nextSibling" : "previousSibling",
2008						parent = elem.parentNode,
2009						name = ofType && elem.nodeName.toLowerCase(),
2010						useCache = !xml && !ofType,
2011						diff = false;
2012
2013					if ( parent ) {
2014
2015						// :(first|last|only)-(child|of-type)
2016						if ( simple ) {
2017							while ( dir ) {
2018								node = elem;
2019								while ( (node = node[ dir ]) ) {
2020									if ( ofType ?
2021										node.nodeName.toLowerCase() === name :
2022										node.nodeType === 1 ) {
2023
2024										return false;
2025									}
2026								}
2027								// Reverse direction for :only-* (if we haven't yet done so)
2028								start = dir = type === "only" && !start && "nextSibling";
2029							}
2030							return true;
2031						}
2032
2033						start = [ forward ? parent.firstChild : parent.lastChild ];
2034
2035						// non-xml :nth-child(...) stores cache data on `parent`
2036						if ( forward && useCache ) {
2037
2038							// Seek `elem` from a previously-cached index
2039
2040							// ...in a gzip-friendly way
2041							node = parent;
2042							outerCache = node[ expando ] || (node[ expando ] = {});
2043
2044							// Support: IE <9 only
2045							// Defend against cloned attroperties (jQuery gh-1709)
2046							uniqueCache = outerCache[ node.uniqueID ] ||
2047								(outerCache[ node.uniqueID ] = {});
2048
2049							cache = uniqueCache[ type ] || [];
2050							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2051							diff = nodeIndex && cache[ 2 ];
2052							node = nodeIndex && parent.childNodes[ nodeIndex ];
2053
2054							while ( (node = ++nodeIndex && node && node[ dir ] ||
2055
2056								// Fallback to seeking `elem` from the start
2057								(diff = nodeIndex = 0) || start.pop()) ) {
2058
2059								// When found, cache indexes on `parent` and break
2060								if ( node.nodeType === 1 && ++diff && node === elem ) {
2061									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
2062									break;
2063								}
2064							}
2065
2066						} else {
2067							// Use previously-cached element index if available
2068							if ( useCache ) {
2069								// ...in a gzip-friendly way
2070								node = elem;
2071								outerCache = node[ expando ] || (node[ expando ] = {});
2072
2073								// Support: IE <9 only
2074								// Defend against cloned attroperties (jQuery gh-1709)
2075								uniqueCache = outerCache[ node.uniqueID ] ||
2076									(outerCache[ node.uniqueID ] = {});
2077
2078								cache = uniqueCache[ type ] || [];
2079								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2080								diff = nodeIndex;
2081							}
2082
2083							// xml :nth-child(...)
2084							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
2085							if ( diff === false ) {
2086								// Use the same loop as above to seek `elem` from the start
2087								while ( (node = ++nodeIndex && node && node[ dir ] ||
2088									(diff = nodeIndex = 0) || start.pop()) ) {
2089
2090									if ( ( ofType ?
2091										node.nodeName.toLowerCase() === name :
2092										node.nodeType === 1 ) &&
2093										++diff ) {
2094
2095										// Cache the index of each encountered element
2096										if ( useCache ) {
2097											outerCache = node[ expando ] || (node[ expando ] = {});
2098
2099											// Support: IE <9 only
2100											// Defend against cloned attroperties (jQuery gh-1709)
2101											uniqueCache = outerCache[ node.uniqueID ] ||
2102												(outerCache[ node.uniqueID ] = {});
2103
2104											uniqueCache[ type ] = [ dirruns, diff ];
2105										}
2106
2107										if ( node === elem ) {
2108											break;
2109										}
2110									}
2111								}
2112							}
2113						}
2114
2115						// Incorporate the offset, then check against cycle size
2116						diff -= last;
2117						return diff === first || ( diff % first === 0 && diff / first >= 0 );
2118					}
2119				};
2120		},
2121
2122		"PSEUDO": function( pseudo, argument ) {
2123			// pseudo-class names are case-insensitive
2124			// http://www.w3.org/TR/selectors/#pseudo-classes
2125			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2126			// Remember that setFilters inherits from pseudos
2127			var args,
2128				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2129					Sizzle.error( "unsupported pseudo: " + pseudo );
2130
2131			// The user may use createPseudo to indicate that
2132			// arguments are needed to create the filter function
2133			// just as Sizzle does
2134			if ( fn[ expando ] ) {
2135				return fn( argument );
2136			}
2137
2138			// But maintain support for old signatures
2139			if ( fn.length > 1 ) {
2140				args = [ pseudo, pseudo, "", argument ];
2141				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2142					markFunction(function( seed, matches ) {
2143						var idx,
2144							matched = fn( seed, argument ),
2145							i = matched.length;
2146						while ( i-- ) {
2147							idx = indexOf( seed, matched[i] );
2148							seed[ idx ] = !( matches[ idx ] = matched[i] );
2149						}
2150					}) :
2151					function( elem ) {
2152						return fn( elem, 0, args );
2153					};
2154			}
2155
2156			return fn;
2157		}
2158	},
2159
2160	pseudos: {
2161		// Potentially complex pseudos
2162		"not": markFunction(function( selector ) {
2163			// Trim the selector passed to compile
2164			// to avoid treating leading and trailing
2165			// spaces as combinators
2166			var input = [],
2167				results = [],
2168				matcher = compile( selector.replace( rtrim, "$1" ) );
2169
2170			return matcher[ expando ] ?
2171				markFunction(function( seed, matches, context, xml ) {
2172					var elem,
2173						unmatched = matcher( seed, null, xml, [] ),
2174						i = seed.length;
2175
2176					// Match elements unmatched by `matcher`
2177					while ( i-- ) {
2178						if ( (elem = unmatched[i]) ) {
2179							seed[i] = !(matches[i] = elem);
2180						}
2181					}
2182				}) :
2183				function( elem, context, xml ) {
2184					input[0] = elem;
2185					matcher( input, null, xml, results );
2186					// Don't keep the element (issue #299)
2187					input[0] = null;
2188					return !results.pop();
2189				};
2190		}),
2191
2192		"has": markFunction(function( selector ) {
2193			return function( elem ) {
2194				return Sizzle( selector, elem ).length > 0;
2195			};
2196		}),
2197
2198		"contains": markFunction(function( text ) {
2199			text = text.replace( runescape, funescape );
2200			return function( elem ) {
2201				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
2202			};
2203		}),
2204
2205		// "Whether an element is represented by a :lang() selector
2206		// is based solely on the element's language value
2207		// being equal to the identifier C,
2208		// or beginning with the identifier C immediately followed by "-".
2209		// The matching of C against the element's language value is performed case-insensitively.
2210		// The identifier C does not have to be a valid language name."
2211		// http://www.w3.org/TR/selectors/#lang-pseudo
2212		"lang": markFunction( function( lang ) {
2213			// lang value must be a valid identifier
2214			if ( !ridentifier.test(lang || "") ) {
2215				Sizzle.error( "unsupported lang: " + lang );
2216			}
2217			lang = lang.replace( runescape, funescape ).toLowerCase();
2218			return function( elem ) {
2219				var elemLang;
2220				do {
2221					if ( (elemLang = documentIsHTML ?
2222						elem.lang :
2223						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
2224
2225						elemLang = elemLang.toLowerCase();
2226						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2227					}
2228				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
2229				return false;
2230			};
2231		}),
2232
2233		// Miscellaneous
2234		"target": function( elem ) {
2235			var hash = window.location && window.location.hash;
2236			return hash && hash.slice( 1 ) === elem.id;
2237		},
2238
2239		"root": function( elem ) {
2240			return elem === docElem;
2241		},
2242
2243		"focus": function( elem ) {
2244			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2245		},
2246
2247		// Boolean properties
2248		"enabled": function( elem ) {
2249			return elem.disabled === false;
2250		},
2251
2252		"disabled": function( elem ) {
2253			return elem.disabled === true;
2254		},
2255
2256		"checked": function( elem ) {
2257			// In CSS3, :checked should return both checked and selected elements
2258			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2259			var nodeName = elem.nodeName.toLowerCase();
2260			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2261		},
2262
2263		"selected": function( elem ) {
2264			// Accessing this property makes selected-by-default
2265			// options in Safari work properly
2266			if ( elem.parentNode ) {
2267				elem.parentNode.selectedIndex;
2268			}
2269
2270			return elem.selected === true;
2271		},
2272
2273		// Contents
2274		"empty": function( elem ) {
2275			// http://www.w3.org/TR/selectors/#empty-pseudo
2276			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2277			//   but not by others (comment: 8; processing instruction: 7; etc.)
2278			// nodeType < 6 works because attributes (2) do not appear as children
2279			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2280				if ( elem.nodeType < 6 ) {
2281					return false;
2282				}
2283			}
2284			return true;
2285		},
2286
2287		"parent": function( elem ) {
2288			return !Expr.pseudos["empty"]( elem );
2289		},
2290
2291		// Element/input types
2292		"header": function( elem ) {
2293			return rheader.test( elem.nodeName );
2294		},
2295
2296		"input": function( elem ) {
2297			return rinputs.test( elem.nodeName );
2298		},
2299
2300		"button": function( elem ) {
2301			var name = elem.nodeName.toLowerCase();
2302			return name === "input" && elem.type === "button" || name === "button";
2303		},
2304
2305		"text": function( elem ) {
2306			var attr;
2307			return elem.nodeName.toLowerCase() === "input" &&
2308				elem.type === "text" &&
2309
2310				// Support: IE<8
2311				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2312				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2313		},
2314
2315		// Position-in-collection
2316		"first": createPositionalPseudo(function() {
2317			return [ 0 ];
2318		}),
2319
2320		"last": createPositionalPseudo(function( matchIndexes, length ) {
2321			return [ length - 1 ];
2322		}),
2323
2324		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2325			return [ argument < 0 ? argument + length : argument ];
2326		}),
2327
2328		"even": createPositionalPseudo(function( matchIndexes, length ) {
2329			var i = 0;
2330			for ( ; i < length; i += 2 ) {
2331				matchIndexes.push( i );
2332			}
2333			return matchIndexes;
2334		}),
2335
2336		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2337			var i = 1;
2338			for ( ; i < length; i += 2 ) {
2339				matchIndexes.push( i );
2340			}
2341			return matchIndexes;
2342		}),
2343
2344		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2345			var i = argument < 0 ? argument + length : argument;
2346			for ( ; --i >= 0; ) {
2347				matchIndexes.push( i );
2348			}
2349			return matchIndexes;
2350		}),
2351
2352		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2353			var i = argument < 0 ? argument + length : argument;
2354			for ( ; ++i < length; ) {
2355				matchIndexes.push( i );
2356			}
2357			return matchIndexes;
2358		})
2359	}
2360};
2361
2362Expr.pseudos["nth"] = Expr.pseudos["eq"];
2363
2364// Add button/input type pseudos
2365for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2366	Expr.pseudos[ i ] = createInputPseudo( i );
2367}
2368for ( i in { submit: true, reset: true } ) {
2369	Expr.pseudos[ i ] = createButtonPseudo( i );
2370}
2371
2372// Easy API for creating new setFilters
2373function setFilters() {}
2374setFilters.prototype = Expr.filters = Expr.pseudos;
2375Expr.setFilters = new setFilters();
2376
2377tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2378	var matched, match, tokens, type,
2379		soFar, groups, preFilters,
2380		cached = tokenCache[ selector + " " ];
2381
2382	if ( cached ) {
2383		return parseOnly ? 0 : cached.slice( 0 );
2384	}
2385
2386	soFar = selector;
2387	groups = [];
2388	preFilters = Expr.preFilter;
2389
2390	while ( soFar ) {
2391
2392		// Comma and first run
2393		if ( !matched || (match = rcomma.exec( soFar )) ) {
2394			if ( match ) {
2395				// Don't consume trailing commas as valid
2396				soFar = soFar.slice( match[0].length ) || soFar;
2397			}
2398			groups.push( (tokens = []) );
2399		}
2400
2401		matched = false;
2402
2403		// Combinators
2404		if ( (match = rcombinators.exec( soFar )) ) {
2405			matched = match.shift();
2406			tokens.push({
2407				value: matched,
2408				// Cast descendant combinators to space
2409				type: match[0].replace( rtrim, " " )
2410			});
2411			soFar = soFar.slice( matched.length );
2412		}
2413
2414		// Filters
2415		for ( type in Expr.filter ) {
2416			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2417				(match = preFilters[ type ]( match ))) ) {
2418				matched = match.shift();
2419				tokens.push({
2420					value: matched,
2421					type: type,
2422					matches: match
2423				});
2424				soFar = soFar.slice( matched.length );
2425			}
2426		}
2427
2428		if ( !matched ) {
2429			break;
2430		}
2431	}
2432
2433	// Return the length of the invalid excess
2434	// if we're just parsing
2435	// Otherwise, throw an error or return tokens
2436	return parseOnly ?
2437		soFar.length :
2438		soFar ?
2439			Sizzle.error( selector ) :
2440			// Cache the tokens
2441			tokenCache( selector, groups ).slice( 0 );
2442};
2443
2444function toSelector( tokens ) {
2445	var i = 0,
2446		len = tokens.length,
2447		selector = "";
2448	for ( ; i < len; i++ ) {
2449		selector += tokens[i].value;
2450	}
2451	return selector;
2452}
2453
2454function addCombinator( matcher, combinator, base ) {
2455	var dir = combinator.dir,
2456		checkNonElements = base && dir === "parentNode",
2457		doneName = done++;
2458
2459	return combinator.first ?
2460		// Check against closest ancestor/preceding element
2461		function( elem, context, xml ) {
2462			while ( (elem = elem[ dir ]) ) {
2463				if ( elem.nodeType === 1 || checkNonElements ) {
2464					return matcher( elem, context, xml );
2465				}
2466			}
2467		} :
2468
2469		// Check against all ancestor/preceding elements
2470		function( elem, context, xml ) {
2471			var oldCache, uniqueCache, outerCache,
2472				newCache = [ dirruns, doneName ];
2473
2474			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2475			if ( xml ) {
2476				while ( (elem = elem[ dir ]) ) {
2477					if ( elem.nodeType === 1 || checkNonElements ) {
2478						if ( matcher( elem, context, xml ) ) {
2479							return true;
2480						}
2481					}
2482				}
2483			} else {
2484				while ( (elem = elem[ dir ]) ) {
2485					if ( elem.nodeType === 1 || checkNonElements ) {
2486						outerCache = elem[ expando ] || (elem[ expando ] = {});
2487
2488						// Support: IE <9 only
2489						// Defend against cloned attroperties (jQuery gh-1709)
2490						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2491
2492						if ( (oldCache = uniqueCache[ dir ]) &&
2493							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2494
2495							// Assign to newCache so results back-propagate to previous elements
2496							return (newCache[ 2 ] = oldCache[ 2 ]);
2497						} else {
2498							// Reuse newcache so results back-propagate to previous elements
2499							uniqueCache[ dir ] = newCache;
2500
2501							// A match means we're done; a fail means we have to keep checking
2502							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2503								return true;
2504							}
2505						}
2506					}
2507				}
2508			}
2509		};
2510}
2511
2512function elementMatcher( matchers ) {
2513	return matchers.length > 1 ?
2514		function( elem, context, xml ) {
2515			var i = matchers.length;
2516			while ( i-- ) {
2517				if ( !matchers[i]( elem, context, xml ) ) {
2518					return false;
2519				}
2520			}
2521			return true;
2522		} :
2523		matchers[0];
2524}
2525
2526function multipleContexts( selector, contexts, results ) {
2527	var i = 0,
2528		len = contexts.length;
2529	for ( ; i < len; i++ ) {
2530		Sizzle( selector, contexts[i], results );
2531	}
2532	return results;
2533}
2534
2535function condense( unmatched, map, filter, context, xml ) {
2536	var elem,
2537		newUnmatched = [],
2538		i = 0,
2539		len = unmatched.length,
2540		mapped = map != null;
2541
2542	for ( ; i < len; i++ ) {
2543		if ( (elem = unmatched[i]) ) {
2544			if ( !filter || filter( elem, context, xml ) ) {
2545				newUnmatched.push( elem );
2546				if ( mapped ) {
2547					map.push( i );
2548				}
2549			}
2550		}
2551	}
2552
2553	return newUnmatched;
2554}
2555
2556function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2557	if ( postFilter && !postFilter[ expando ] ) {
2558		postFilter = setMatcher( postFilter );
2559	}
2560	if ( postFinder && !postFinder[ expando ] ) {
2561		postFinder = setMatcher( postFinder, postSelector );
2562	}
2563	return markFunction(function( seed, results, context, xml ) {
2564		var temp, i, elem,
2565			preMap = [],
2566			postMap = [],
2567			preexisting = results.length,
2568
2569			// Get initial elements from seed or context
2570			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2571
2572			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2573			matcherIn = preFilter && ( seed || !selector ) ?
2574				condense( elems, preMap, preFilter, context, xml ) :
2575				elems,
2576
2577			matcherOut = matcher ?
2578				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2579				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2580
2581					// ...intermediate processing is necessary
2582					[] :
2583
2584					// ...otherwise use results directly
2585					results :
2586				matcherIn;
2587
2588		// Find primary matches
2589		if ( matcher ) {
2590			matcher( matcherIn, matcherOut, context, xml );
2591		}
2592
2593		// Apply postFilter
2594		if ( postFilter ) {
2595			temp = condense( matcherOut, postMap );
2596			postFilter( temp, [], context, xml );
2597
2598			// Un-match failing elements by moving them back to matcherIn
2599			i = temp.length;
2600			while ( i-- ) {
2601				if ( (elem = temp[i]) ) {
2602					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2603				}
2604			}
2605		}
2606
2607		if ( seed ) {
2608			if ( postFinder || preFilter ) {
2609				if ( postFinder ) {
2610					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2611					temp = [];
2612					i = matcherOut.length;
2613					while ( i-- ) {
2614						if ( (elem = matcherOut[i]) ) {
2615							// Restore matcherIn since elem is not yet a final match
2616							temp.push( (matcherIn[i] = elem) );
2617						}
2618					}
2619					postFinder( null, (matcherOut = []), temp, xml );
2620				}
2621
2622				// Move matched elements from seed to results to keep them synchronized
2623				i = matcherOut.length;
2624				while ( i-- ) {
2625					if ( (elem = matcherOut[i]) &&
2626						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2627
2628						seed[temp] = !(results[temp] = elem);
2629					}
2630				}
2631			}
2632
2633		// Add elements to results, through postFinder if defined
2634		} else {
2635			matcherOut = condense(
2636				matcherOut === results ?
2637					matcherOut.splice( preexisting, matcherOut.length ) :
2638					matcherOut
2639			);
2640			if ( postFinder ) {
2641				postFinder( null, results, matcherOut, xml );
2642			} else {
2643				push.apply( results, matcherOut );
2644			}
2645		}
2646	});
2647}
2648
2649function matcherFromTokens( tokens ) {
2650	var checkContext, matcher, j,
2651		len = tokens.length,
2652		leadingRelative = Expr.relative[ tokens[0].type ],
2653		implicitRelative = leadingRelative || Expr.relative[" "],
2654		i = leadingRelative ? 1 : 0,
2655
2656		// The foundational matcher ensures that elements are reachable from top-level context(s)
2657		matchContext = addCombinator( function( elem ) {
2658			return elem === checkContext;
2659		}, implicitRelative, true ),
2660		matchAnyContext = addCombinator( function( elem ) {
2661			return indexOf( checkContext, elem ) > -1;
2662		}, implicitRelative, true ),
2663		matchers = [ function( elem, context, xml ) {
2664			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2665				(checkContext = context).nodeType ?
2666					matchContext( elem, context, xml ) :
2667					matchAnyContext( elem, context, xml ) );
2668			// Avoid hanging onto element (issue #299)
2669			checkContext = null;
2670			return ret;
2671		} ];
2672
2673	for ( ; i < len; i++ ) {
2674		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2675			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2676		} else {
2677			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2678
2679			// Return special upon seeing a positional matcher
2680			if ( matcher[ expando ] ) {
2681				// Find the next relative operator (if any) for proper handling
2682				j = ++i;
2683				for ( ; j < len; j++ ) {
2684					if ( Expr.relative[ tokens[j].type ] ) {
2685						break;
2686					}
2687				}
2688				return setMatcher(
2689					i > 1 && elementMatcher( matchers ),
2690					i > 1 && toSelector(
2691						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2692						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2693					).replace( rtrim, "$1" ),
2694					matcher,
2695					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2696					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2697					j < len && toSelector( tokens )
2698				);
2699			}
2700			matchers.push( matcher );
2701		}
2702	}
2703
2704	return elementMatcher( matchers );
2705}
2706
2707function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2708	var bySet = setMatchers.length > 0,
2709		byElement = elementMatchers.length > 0,
2710		superMatcher = function( seed, context, xml, results, outermost ) {
2711			var elem, j, matcher,
2712				matchedCount = 0,
2713				i = "0",
2714				unmatched = seed && [],
2715				setMatched = [],
2716				contextBackup = outermostContext,
2717				// We must always have either seed elements or outermost context
2718				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2719				// Use integer dirruns iff this is the outermost matcher
2720				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2721				len = elems.length;
2722
2723			if ( outermost ) {
2724				outermostContext = context === document || context || outermost;
2725			}
2726
2727			// Add elements passing elementMatchers directly to results
2728			// Support: IE<9, Safari
2729			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2730			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2731				if ( byElement && elem ) {
2732					j = 0;
2733					if ( !context && elem.ownerDocument !== document ) {
2734						setDocument( elem );
2735						xml = !documentIsHTML;
2736					}
2737					while ( (matcher = elementMatchers[j++]) ) {
2738						if ( matcher( elem, context || document, xml) ) {
2739							results.push( elem );
2740							break;
2741						}
2742					}
2743					if ( outermost ) {
2744						dirruns = dirrunsUnique;
2745					}
2746				}
2747
2748				// Track unmatched elements for set filters
2749				if ( bySet ) {
2750					// They will have gone through all possible matchers
2751					if ( (elem = !matcher && elem) ) {
2752						matchedCount--;
2753					}
2754
2755					// Lengthen the array for every element, matched or not
2756					if ( seed ) {
2757						unmatched.push( elem );
2758					}
2759				}
2760			}
2761
2762			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2763			// makes the latter nonnegative.
2764			matchedCount += i;
2765
2766			// Apply set filters to unmatched elements
2767			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2768			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2769			// no element matchers and no seed.
2770			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2771			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2772			// numerically zero.
2773			if ( bySet && i !== matchedCount ) {
2774				j = 0;
2775				while ( (matcher = setMatchers[j++]) ) {
2776					matcher( unmatched, setMatched, context, xml );
2777				}
2778
2779				if ( seed ) {
2780					// Reintegrate element matches to eliminate the need for sorting
2781					if ( matchedCount > 0 ) {
2782						while ( i-- ) {
2783							if ( !(unmatched[i] || setMatched[i]) ) {
2784								setMatched[i] = pop.call( results );
2785							}
2786						}
2787					}
2788
2789					// Discard index placeholder values to get only actual matches
2790					setMatched = condense( setMatched );
2791				}
2792
2793				// Add matches to results
2794				push.apply( results, setMatched );
2795
2796				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2797				if ( outermost && !seed && setMatched.length > 0 &&
2798					( matchedCount + setMatchers.length ) > 1 ) {
2799
2800					Sizzle.uniqueSort( results );
2801				}
2802			}
2803
2804			// Override manipulation of globals by nested matchers
2805			if ( outermost ) {
2806				dirruns = dirrunsUnique;
2807				outermostContext = contextBackup;
2808			}
2809
2810			return unmatched;
2811		};
2812
2813	return bySet ?
2814		markFunction( superMatcher ) :
2815		superMatcher;
2816}
2817
2818compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2819	var i,
2820		setMatchers = [],
2821		elementMatchers = [],
2822		cached = compilerCache[ selector + " " ];
2823
2824	if ( !cached ) {
2825		// Generate a function of recursive functions that can be used to check each element
2826		if ( !match ) {
2827			match = tokenize( selector );
2828		}
2829		i = match.length;
2830		while ( i-- ) {
2831			cached = matcherFromTokens( match[i] );
2832			if ( cached[ expando ] ) {
2833				setMatchers.push( cached );
2834			} else {
2835				elementMatchers.push( cached );
2836			}
2837		}
2838
2839		// Cache the compiled function
2840		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2841
2842		// Save selector and tokenization
2843		cached.selector = selector;
2844	}
2845	return cached;
2846};
2847
2848/**
2849 * A low-level selection function that works with Sizzle's compiled
2850 *  selector functions
2851 * @param {String|Function} selector A selector or a pre-compiled
2852 *  selector function built with Sizzle.compile
2853 * @param {Element} context
2854 * @param {Array} [results]
2855 * @param {Array} [seed] A set of elements to match against
2856 */
2857select = Sizzle.select = function( selector, context, results, seed ) {
2858	var i, tokens, token, type, find,
2859		compiled = typeof selector === "function" && selector,
2860		match = !seed && tokenize( (selector = compiled.selector || selector) );
2861
2862	results = results || [];
2863
2864	// Try to minimize operations if there is only one selector in the list and no seed
2865	// (the latter of which guarantees us context)
2866	if ( match.length === 1 ) {
2867
2868		// Reduce context if the leading compound selector is an ID
2869		tokens = match[0] = match[0].slice( 0 );
2870		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2871				support.getById && context.nodeType === 9 && documentIsHTML &&
2872				Expr.relative[ tokens[1].type ] ) {
2873
2874			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2875			if ( !context ) {
2876				return results;
2877
2878			// Precompiled matchers will still verify ancestry, so step up a level
2879			} else if ( compiled ) {
2880				context = context.parentNode;
2881			}
2882
2883			selector = selector.slice( tokens.shift().value.length );
2884		}
2885
2886		// Fetch a seed set for right-to-left matching
2887		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2888		while ( i-- ) {
2889			token = tokens[i];
2890
2891			// Abort if we hit a combinator
2892			if ( Expr.relative[ (type = token.type) ] ) {
2893				break;
2894			}
2895			if ( (find = Expr.find[ type ]) ) {
2896				// Search, expanding context for leading sibling combinators
2897				if ( (seed = find(
2898					token.matches[0].replace( runescape, funescape ),
2899					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2900				)) ) {
2901
2902					// If seed is empty or no tokens remain, we can return early
2903					tokens.splice( i, 1 );
2904					selector = seed.length && toSelector( tokens );
2905					if ( !selector ) {
2906						push.apply( results, seed );
2907						return results;
2908					}
2909
2910					break;
2911				}
2912			}
2913		}
2914	}
2915
2916	// Compile and execute a filtering function if one is not provided
2917	// Provide `match` to avoid retokenization if we modified the selector above
2918	( compiled || compile( selector, match ) )(
2919		seed,
2920		context,
2921		!documentIsHTML,
2922		results,
2923		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2924	);
2925	return results;
2926};
2927
2928// One-time assignments
2929
2930// Sort stability
2931support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2932
2933// Support: Chrome 14-35+
2934// Always assume duplicates if they aren't passed to the comparison function
2935support.detectDuplicates = !!hasDuplicate;
2936
2937// Initialize against the default document
2938setDocument();
2939
2940// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2941// Detached nodes confoundingly follow *each other*
2942support.sortDetached = assert(function( div1 ) {
2943	// Should return 1, but returns 4 (following)
2944	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2945});
2946
2947// Support: IE<8
2948// Prevent attribute/property "interpolation"
2949// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2950if ( !assert(function( div ) {
2951	div.innerHTML = "<a href='#'></a>";
2952	return div.firstChild.getAttribute("href") === "#" ;
2953}) ) {
2954	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2955		if ( !isXML ) {
2956			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2957		}
2958	});
2959}
2960
2961// Support: IE<9
2962// Use defaultValue in place of getAttribute("value")
2963if ( !support.attributes || !assert(function( div ) {
2964	div.innerHTML = "<input/>";
2965	div.firstChild.setAttribute( "value", "" );
2966	return div.firstChild.getAttribute( "value" ) === "";
2967}) ) {
2968	addHandle( "value", function( elem, name, isXML ) {
2969		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2970			return elem.defaultValue;
2971		}
2972	});
2973}
2974
2975// Support: IE<9
2976// Use getAttributeNode to fetch booleans when getAttribute lies
2977if ( !assert(function( div ) {
2978	return div.getAttribute("disabled") == null;
2979}) ) {
2980	addHandle( booleans, function( elem, name, isXML ) {
2981		var val;
2982		if ( !isXML ) {
2983			return elem[ name ] === true ? name.toLowerCase() :
2984					(val = elem.getAttributeNode( name )) && val.specified ?
2985					val.value :
2986				null;
2987		}
2988	});
2989}
2990
2991return Sizzle;
2992
2993})( window );
2994
2995
2996
2997jQuery.find = Sizzle;
2998jQuery.expr = Sizzle.selectors;
2999jQuery.expr[ ":" ] = jQuery.expr.pseudos;
3000jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
3001jQuery.text = Sizzle.getText;
3002jQuery.isXMLDoc = Sizzle.isXML;
3003jQuery.contains = Sizzle.contains;
3004
3005
3006
3007var dir = function( elem, dir, until ) {
3008	var matched = [],
3009		truncate = until !== undefined;
3010
3011	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
3012		if ( elem.nodeType === 1 ) {
3013			if ( truncate && jQuery( elem ).is( until ) ) {
3014				break;
3015			}
3016			matched.push( elem );
3017		}
3018	}
3019	return matched;
3020};
3021
3022
3023var siblings = function( n, elem ) {
3024	var matched = [];
3025
3026	for ( ; n; n = n.nextSibling ) {
3027		if ( n.nodeType === 1 && n !== elem ) {
3028			matched.push( n );
3029		}
3030	}
3031
3032	return matched;
3033};
3034
3035
3036var rneedsContext = jQuery.expr.match.needsContext;
3037
3038var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
3039
3040
3041
3042var risSimple = /^.[^:#\[\.,]*$/;
3043
3044// Implement the identical functionality for filter and not
3045function winnow( elements, qualifier, not ) {
3046	if ( jQuery.isFunction( qualifier ) ) {
3047		return jQuery.grep( elements, function( elem, i ) {
3048			/* jshint -W018 */
3049			return !!qualifier.call( elem, i, elem ) !== not;
3050		} );
3051
3052	}
3053
3054	if ( qualifier.nodeType ) {
3055		return jQuery.grep( elements, function( elem ) {
3056			return ( elem === qualifier ) !== not;
3057		} );
3058
3059	}
3060
3061	if ( typeof qualifier === "string" ) {
3062		if ( risSimple.test( qualifier ) ) {
3063			return jQuery.filter( qualifier, elements, not );
3064		}
3065
3066		qualifier = jQuery.filter( qualifier, elements );
3067	}
3068
3069	return jQuery.grep( elements, function( elem ) {
3070		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3071	} );
3072}
3073
3074jQuery.filter = function( expr, elems, not ) {
3075	var elem = elems[ 0 ];
3076
3077	if ( not ) {
3078		expr = ":not(" + expr + ")";
3079	}
3080
3081	return elems.length === 1 && elem.nodeType === 1 ?
3082		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
3083		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3084			return elem.nodeType === 1;
3085		} ) );
3086};
3087
3088jQuery.fn.extend( {
3089	find: function( selector ) {
3090		var i,
3091			len = this.length,
3092			ret = [],
3093			self = this;
3094
3095		if ( typeof selector !== "string" ) {
3096			return this.pushStack( jQuery( selector ).filter( function() {
3097				for ( i = 0; i < len; i++ ) {
3098					if ( jQuery.contains( self[ i ], this ) ) {
3099						return true;
3100					}
3101				}
3102			} ) );
3103		}
3104
3105		for ( i = 0; i < len; i++ ) {
3106			jQuery.find( selector, self[ i ], ret );
3107		}
3108
3109		// Needed because $( selector, context ) becomes $( context ).find( selector )
3110		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
3111		ret.selector = this.selector ? this.selector + " " + selector : selector;
3112		return ret;
3113	},
3114	filter: function( selector ) {
3115		return this.pushStack( winnow( this, selector || [], false ) );
3116	},
3117	not: function( selector ) {
3118		return this.pushStack( winnow( this, selector || [], true ) );
3119	},
3120	is: function( selector ) {
3121		return !!winnow(
3122			this,
3123
3124			// If this is a positional/relative selector, check membership in the returned set
3125			// so $("p:first").is("p:last") won't return true for a doc with two "p".
3126			typeof selector === "string" && rneedsContext.test( selector ) ?
3127				jQuery( selector ) :
3128				selector || [],
3129			false
3130		).length;
3131	}
3132} );
3133
3134
3135// Initialize a jQuery object
3136
3137
3138// A central reference to the root jQuery(document)
3139var rootjQuery,
3140
3141	// A simple way to check for HTML strings
3142	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
3143	// Strict HTML recognition (#11290: must start with <)
3144	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
3145
3146	init = jQuery.fn.init = function( selector, context, root ) {
3147		var match, elem;
3148
3149		// HANDLE: $(""), $(null), $(undefined), $(false)
3150		if ( !selector ) {
3151			return this;
3152		}
3153
3154		// Method init() accepts an alternate rootjQuery
3155		// so migrate can support jQuery.sub (gh-2101)
3156		root = root || rootjQuery;
3157
3158		// Handle HTML strings
3159		if ( typeof selector === "string" ) {
3160			if ( selector[ 0 ] === "<" &&
3161				selector[ selector.length - 1 ] === ">" &&
3162				selector.length >= 3 ) {
3163
3164				// Assume that strings that start and end with <> are HTML and skip the regex check
3165				match = [ null, selector, null ];
3166
3167			} else {
3168				match = rquickExpr.exec( selector );
3169			}
3170
3171			// Match html or make sure no context is specified for #id
3172			if ( match && ( match[ 1 ] || !context ) ) {
3173
3174				// HANDLE: $(html) -> $(array)
3175				if ( match[ 1 ] ) {
3176					context = context instanceof jQuery ? context[ 0 ] : context;
3177
3178					// Option to run scripts is true for back-compat
3179					// Intentionally let the error be thrown if parseHTML is not present
3180					jQuery.merge( this, jQuery.parseHTML(
3181						match[ 1 ],
3182						context && context.nodeType ? context.ownerDocument || context : document,
3183						true
3184					) );
3185
3186					// HANDLE: $(html, props)
3187					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3188						for ( match in context ) {
3189
3190							// Properties of context are called as methods if possible
3191							if ( jQuery.isFunction( this[ match ] ) ) {
3192								this[ match ]( context[ match ] );
3193
3194							// ...and otherwise set as attributes
3195							} else {
3196								this.attr( match, context[ match ] );
3197							}
3198						}
3199					}
3200
3201					return this;
3202
3203				// HANDLE: $(#id)
3204				} else {
3205					elem = document.getElementById( match[ 2 ] );
3206
3207					// Support: Blackberry 4.6
3208					// gEBID returns nodes no longer in the document (#6963)
3209					if ( elem && elem.parentNode ) {
3210
3211						// Inject the element directly into the jQuery object
3212						this.length = 1;
3213						this[ 0 ] = elem;
3214					}
3215
3216					this.context = document;
3217					this.selector = selector;
3218					return this;
3219				}
3220
3221			// HANDLE: $(expr, $(...))
3222			} else if ( !context || context.jquery ) {
3223				return ( context || root ).find( selector );
3224
3225			// HANDLE: $(expr, context)
3226			// (which is just equivalent to: $(context).find(expr)
3227			} else {
3228				return this.constructor( context ).find( selector );
3229			}
3230
3231		// HANDLE: $(DOMElement)
3232		} else if ( selector.nodeType ) {
3233			this.context = this[ 0 ] = selector;
3234			this.length = 1;
3235			return this;
3236
3237		// HANDLE: $(function)
3238		// Shortcut for document ready
3239		} else if ( jQuery.isFunction( selector ) ) {
3240			return root.ready !== undefined ?
3241				root.ready( selector ) :
3242
3243				// Execute immediately if ready is not present
3244				selector( jQuery );
3245		}
3246
3247		if ( selector.selector !== undefined ) {
3248			this.selector = selector.selector;
3249			this.context = selector.context;
3250		}
3251
3252		return jQuery.makeArray( selector, this );
3253	};
3254
3255// Give the init function the jQuery prototype for later instantiation
3256init.prototype = jQuery.fn;
3257
3258// Initialize central reference
3259rootjQuery = jQuery( document );
3260
3261
3262var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3263
3264	// Methods guaranteed to produce a unique set when starting from a unique set
3265	guaranteedUnique = {
3266		children: true,
3267		contents: true,
3268		next: true,
3269		prev: true
3270	};
3271
3272jQuery.fn.extend( {
3273	has: function( target ) {
3274		var targets = jQuery( target, this ),
3275			l = targets.length;
3276
3277		return this.filter( function() {
3278			var i = 0;
3279			for ( ; i < l; i++ ) {
3280				if ( jQuery.contains( this, targets[ i ] ) ) {
3281					return true;
3282				}
3283			}
3284		} );
3285	},
3286
3287	closest: function( selectors, context ) {
3288		var cur,
3289			i = 0,
3290			l = this.length,
3291			matched = [],
3292			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
3293				jQuery( selectors, context || this.context ) :
3294				0;
3295
3296		for ( ; i < l; i++ ) {
3297			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3298
3299				// Always skip document fragments
3300				if ( cur.nodeType < 11 && ( pos ?
3301					pos.index( cur ) > -1 :
3302
3303					// Don't pass non-elements to Sizzle
3304					cur.nodeType === 1 &&
3305						jQuery.find.matchesSelector( cur, selectors ) ) ) {
3306
3307					matched.push( cur );
3308					break;
3309				}
3310			}
3311		}
3312
3313		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3314	},
3315
3316	// Determine the position of an element within the set
3317	index: function( elem ) {
3318
3319		// No argument, return index in parent
3320		if ( !elem ) {
3321			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3322		}
3323
3324		// Index in selector
3325		if ( typeof elem === "string" ) {
3326			return indexOf.call( jQuery( elem ), this[ 0 ] );
3327		}
3328
3329		// Locate the position of the desired element
3330		return indexOf.call( this,
3331
3332			// If it receives a jQuery object, the first element is used
3333			elem.jquery ? elem[ 0 ] : elem
3334		);
3335	},
3336
3337	add: function( selector, context ) {
3338		return this.pushStack(
3339			jQuery.uniqueSort(
3340				jQuery.merge( this.get(), jQuery( selector, context ) )
3341			)
3342		);
3343	},
3344
3345	addBack: function( selector ) {
3346		return this.add( selector == null ?
3347			this.prevObject : this.prevObject.filter( selector )
3348		);
3349	}
3350} );
3351
3352function sibling( cur, dir ) {
3353	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3354	return cur;
3355}
3356
3357jQuery.each( {
3358	parent: function( elem ) {
3359		var parent = elem.parentNode;
3360		return parent && parent.nodeType !== 11 ? parent : null;
3361	},
3362	parents: function( elem ) {
3363		return dir( elem, "parentNode" );
3364	},
3365	parentsUntil: function( elem, i, until ) {
3366		return dir( elem, "parentNode", until );
3367	},
3368	next: function( elem ) {
3369		return sibling( elem, "nextSibling" );
3370	},
3371	prev: function( elem ) {
3372		return sibling( elem, "previousSibling" );
3373	},
3374	nextAll: function( elem ) {
3375		return dir( elem, "nextSibling" );
3376	},
3377	prevAll: function( elem ) {
3378		return dir( elem, "previousSibling" );
3379	},
3380	nextUntil: function( elem, i, until ) {
3381		return dir( elem, "nextSibling", until );
3382	},
3383	prevUntil: function( elem, i, until ) {
3384		return dir( elem, "previousSibling", until );
3385	},
3386	siblings: function( elem ) {
3387		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3388	},
3389	children: function( elem ) {
3390		return siblings( elem.firstChild );
3391	},
3392	contents: function( elem ) {
3393		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3394	}
3395}, function( name, fn ) {
3396	jQuery.fn[ name ] = function( until, selector ) {
3397		var matched = jQuery.map( this, fn, until );
3398
3399		if ( name.slice( -5 ) !== "Until" ) {
3400			selector = until;
3401		}
3402
3403		if ( selector && typeof selector === "string" ) {
3404			matched = jQuery.filter( selector, matched );
3405		}
3406
3407		if ( this.length > 1 ) {
3408
3409			// Remove duplicates
3410			if ( !guaranteedUnique[ name ] ) {
3411				jQuery.uniqueSort( matched );
3412			}
3413
3414			// Reverse order for parents* and prev-derivatives
3415			if ( rparentsprev.test( name ) ) {
3416				matched.reverse();
3417			}
3418		}
3419
3420		return this.pushStack( matched );
3421	};
3422} );
3423var rnotwhite = ( /\S+/g );
3424
3425
3426
3427// Convert String-formatted options into Object-formatted ones
3428function createOptions( options ) {
3429	var object = {};
3430	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3431		object[ flag ] = true;
3432	} );
3433	return object;
3434}
3435
3436/*
3437 * Create a callback list using the following parameters:
3438 *
3439 *	options: an optional list of space-separated options that will change how
3440 *			the callback list behaves or a more traditional option object
3441 *
3442 * By default a callback list will act like an event callback list and can be
3443 * "fired" multiple times.
3444 *
3445 * Possible options:
3446 *
3447 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3448 *
3449 *	memory:			will keep track of previous values and will call any callback added
3450 *					after the list has been fired right away with the latest "memorized"
3451 *					values (like a Deferred)
3452 *
3453 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3454 *
3455 *	stopOnFalse:	interrupt callings when a callback returns false
3456 *
3457 */
3458jQuery.Callbacks = function( options ) {
3459
3460	// Convert options from String-formatted to Object-formatted if needed
3461	// (we check in cache first)
3462	options = typeof options === "string" ?
3463		createOptions( options ) :
3464		jQuery.extend( {}, options );
3465
3466	var // Flag to know if list is currently firing
3467		firing,
3468
3469		// Last fire value for non-forgettable lists
3470		memory,
3471
3472		// Flag to know if list was already fired
3473		fired,
3474
3475		// Flag to prevent firing
3476		locked,
3477
3478		// Actual callback list
3479		list = [],
3480
3481		// Queue of execution data for repeatable lists
3482		queue = [],
3483
3484		// Index of currently firing callback (modified by add/remove as needed)
3485		firingIndex = -1,
3486
3487		// Fire callbacks
3488		fire = function() {
3489
3490			// Enforce single-firing
3491			locked = options.once;
3492
3493			// Execute callbacks for all pending executions,
3494			// respecting firingIndex overrides and runtime changes
3495			fired = firing = true;
3496			for ( ; queue.length; firingIndex = -1 ) {
3497				memory = queue.shift();
3498				while ( ++firingIndex < list.length ) {
3499
3500					// Run callback and check for early termination
3501					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3502						options.stopOnFalse ) {
3503
3504						// Jump to end and forget the data so .add doesn't re-fire
3505						firingIndex = list.length;
3506						memory = false;
3507					}
3508				}
3509			}
3510
3511			// Forget the data if we're done with it
3512			if ( !options.memory ) {
3513				memory = false;
3514			}
3515
3516			firing = false;
3517
3518			// Clean up if we're done firing for good
3519			if ( locked ) {
3520
3521				// Keep an empty list if we have data for future add calls
3522				if ( memory ) {
3523					list = [];
3524
3525				// Otherwise, this object is spent
3526				} else {
3527					list = "";
3528				}
3529			}
3530		},
3531
3532		// Actual Callbacks object
3533		self = {
3534
3535			// Add a callback or a collection of callbacks to the list
3536			add: function() {
3537				if ( list ) {
3538
3539					// If we have memory from a past run, we should fire after adding
3540					if ( memory && !firing ) {
3541						firingIndex = list.length - 1;
3542						queue.push( memory );
3543					}
3544
3545					( function add( args ) {
3546						jQuery.each( args, function( _, arg ) {
3547							if ( jQuery.isFunction( arg ) ) {
3548								if ( !options.unique || !self.has( arg ) ) {
3549									list.push( arg );
3550								}
3551							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3552
3553								// Inspect recursively
3554								add( arg );
3555							}
3556						} );
3557					} )( arguments );
3558
3559					if ( memory && !firing ) {
3560						fire();
3561					}
3562				}
3563				return this;
3564			},
3565
3566			// Remove a callback from the list
3567			remove: function() {
3568				jQuery.each( arguments, function( _, arg ) {
3569					var index;
3570					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3571						list.splice( index, 1 );
3572
3573						// Handle firing indexes
3574						if ( index <= firingIndex ) {
3575							firingIndex--;
3576						}
3577					}
3578				} );
3579				return this;
3580			},
3581
3582			// Check if a given callback is in the list.
3583			// If no argument is given, return whether or not list has callbacks attached.
3584			has: function( fn ) {
3585				return fn ?
3586					jQuery.inArray( fn, list ) > -1 :
3587					list.length > 0;
3588			},
3589
3590			// Remove all callbacks from the list
3591			empty: function() {
3592				if ( list ) {
3593					list = [];
3594				}
3595				return this;
3596			},
3597
3598			// Disable .fire and .add
3599			// Abort any current/pending executions
3600			// Clear all callbacks and values
3601			disable: function() {
3602				locked = queue = [];
3603				list = memory = "";
3604				return this;
3605			},
3606			disabled: function() {
3607				return !list;
3608			},
3609
3610			// Disable .fire
3611			// Also disable .add unless we have memory (since it would have no effect)
3612			// Abort any pending executions
3613			lock: function() {
3614				locked = queue = [];
3615				if ( !memory ) {
3616					list = memory = "";
3617				}
3618				return this;
3619			},
3620			locked: function() {
3621				return !!locked;
3622			},
3623
3624			// Call all callbacks with the given context and arguments
3625			fireWith: function( context, args ) {
3626				if ( !locked ) {
3627					args = args || [];
3628					args = [ context, args.slice ? args.slice() : args ];
3629					queue.push( args );
3630					if ( !firing ) {
3631						fire();
3632					}
3633				}
3634				return this;
3635			},
3636
3637			// Call all the callbacks with the given arguments
3638			fire: function() {
3639				self.fireWith( this, arguments );
3640				return this;
3641			},
3642
3643			// To know if the callbacks have already been called at least once
3644			fired: function() {
3645				return !!fired;
3646			}
3647		};
3648
3649	return self;
3650};
3651
3652
3653jQuery.extend( {
3654
3655	Deferred: function( func ) {
3656		var tuples = [
3657
3658				// action, add listener, listener list, final state
3659				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3660				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3661				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3662			],
3663			state = "pending",
3664			promise = {
3665				state: function() {
3666					return state;
3667				},
3668				always: function() {
3669					deferred.done( arguments ).fail( arguments );
3670					return this;
3671				},
3672				then: function( /* fnDone, fnFail, fnProgress */ ) {
3673					var fns = arguments;
3674					return jQuery.Deferred( function( newDefer ) {
3675						jQuery.each( tuples, function( i, tuple ) {
3676							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3677
3678							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3679							deferred[ tuple[ 1 ] ]( function() {
3680								var returned = fn && fn.apply( this, arguments );
3681								if ( returned && jQuery.isFunction( returned.promise ) ) {
3682									returned.promise()
3683										.progress( newDefer.notify )
3684										.done( newDefer.resolve )
3685										.fail( newDefer.reject );
3686								} else {
3687									newDefer[ tuple[ 0 ] + "With" ](
3688										this === promise ? newDefer.promise() : this,
3689										fn ? [ returned ] : arguments
3690									);
3691								}
3692							} );
3693						} );
3694						fns = null;
3695					} ).promise();
3696				},
3697
3698				// Get a promise for this deferred
3699				// If obj is provided, the promise aspect is added to the object
3700				promise: function( obj ) {
3701					return obj != null ? jQuery.extend( obj, promise ) : promise;
3702				}
3703			},
3704			deferred = {};
3705
3706		// Keep pipe for back-compat
3707		promise.pipe = promise.then;
3708
3709		// Add list-specific methods
3710		jQuery.each( tuples, function( i, tuple ) {
3711			var list = tuple[ 2 ],
3712				stateString = tuple[ 3 ];
3713
3714			// promise[ done | fail | progress ] = list.add
3715			promise[ tuple[ 1 ] ] = list.add;
3716
3717			// Handle state
3718			if ( stateString ) {
3719				list.add( function() {
3720
3721					// state = [ resolved | rejected ]
3722					state = stateString;
3723
3724				// [ reject_list | resolve_list ].disable; progress_list.lock
3725				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3726			}
3727
3728			// deferred[ resolve | reject | notify ]
3729			deferred[ tuple[ 0 ] ] = function() {
3730				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3731				return this;
3732			};
3733			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3734		} );
3735
3736		// Make the deferred a promise
3737		promise.promise( deferred );
3738
3739		// Call given func if any
3740		if ( func ) {
3741			func.call( deferred, deferred );
3742		}
3743
3744		// All done!
3745		return deferred;
3746	},
3747
3748	// Deferred helper
3749	when: function( subordinate /* , ..., subordinateN */ ) {
3750		var i = 0,
3751			resolveValues = slice.call( arguments ),
3752			length = resolveValues.length,
3753
3754			// the count of uncompleted subordinates
3755			remaining = length !== 1 ||
3756				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3757
3758			// the master Deferred.
3759			// If resolveValues consist of only a single Deferred, just use that.
3760			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3761
3762			// Update function for both resolve and progress values
3763			updateFunc = function( i, contexts, values ) {
3764				return function( value ) {
3765					contexts[ i ] = this;
3766					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3767					if ( values === progressValues ) {
3768						deferred.notifyWith( contexts, values );
3769					} else if ( !( --remaining ) ) {
3770						deferred.resolveWith( contexts, values );
3771					}
3772				};
3773			},
3774
3775			progressValues, progressContexts, resolveContexts;
3776
3777		// Add listeners to Deferred subordinates; treat others as resolved
3778		if ( length > 1 ) {
3779			progressValues = new Array( length );
3780			progressContexts = new Array( length );
3781			resolveContexts = new Array( length );
3782			for ( ; i < length; i++ ) {
3783				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3784					resolveValues[ i ].promise()
3785						.progress( updateFunc( i, progressContexts, progressValues ) )
3786						.done( updateFunc( i, resolveContexts, resolveValues ) )
3787						.fail( deferred.reject );
3788				} else {
3789					--remaining;
3790				}
3791			}
3792		}
3793
3794		// If we're not waiting on anything, resolve the master
3795		if ( !remaining ) {
3796			deferred.resolveWith( resolveContexts, resolveValues );
3797		}
3798
3799		return deferred.promise();
3800	}
3801} );
3802
3803
3804// The deferred used on DOM ready
3805var readyList;
3806
3807jQuery.fn.ready = function( fn ) {
3808
3809	// Add the callback
3810	jQuery.ready.promise().done( fn );
3811
3812	return this;
3813};
3814
3815jQuery.extend( {
3816
3817	// Is the DOM ready to be used? Set to true once it occurs.
3818	isReady: false,
3819
3820	// A counter to track how many items to wait for before
3821	// the ready event fires. See #6781
3822	readyWait: 1,
3823
3824	// Hold (or release) the ready event
3825	holdReady: function( hold ) {
3826		if ( hold ) {
3827			jQuery.readyWait++;
3828		} else {
3829			jQuery.ready( true );
3830		}
3831	},
3832
3833	// Handle when the DOM is ready
3834	ready: function( wait ) {
3835
3836		// Abort if there are pending holds or we're already ready
3837		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3838			return;
3839		}
3840
3841		// Remember that the DOM is ready
3842		jQuery.isReady = true;
3843
3844		// If a normal DOM Ready event fired, decrement, and wait if need be
3845		if ( wait !== true && --jQuery.readyWait > 0 ) {
3846			return;
3847		}
3848
3849		// If there are functions bound, to execute
3850		readyList.resolveWith( document, [ jQuery ] );
3851
3852		// Trigger any bound ready events
3853		if ( jQuery.fn.triggerHandler ) {
3854			jQuery( document ).triggerHandler( "ready" );
3855			jQuery( document ).off( "ready" );
3856		}
3857	}
3858} );
3859
3860/**
3861 * The ready event handler and self cleanup method
3862 */
3863function completed() {
3864	document.removeEventListener( "DOMContentLoaded", completed );
3865	window.removeEventListener( "load", completed );
3866	jQuery.ready();
3867}
3868
3869jQuery.ready.promise = function( obj ) {
3870	if ( !readyList ) {
3871
3872		readyList = jQuery.Deferred();
3873
3874		// Catch cases where $(document).ready() is called
3875		// after the browser event has already occurred.
3876		// Support: IE9-10 only
3877		// Older IE sometimes signals "interactive" too soon
3878		if ( document.readyState === "complete" ||
3879			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3880
3881			// Handle it asynchronously to allow scripts the opportunity to delay ready
3882			window.setTimeout( jQuery.ready );
3883
3884		} else {
3885
3886			// Use the handy event callback
3887			document.addEventListener( "DOMContentLoaded", completed );
3888
3889			// A fallback to window.onload, that will always work
3890			window.addEventListener( "load", completed );
3891		}
3892	}
3893	return readyList.promise( obj );
3894};
3895
3896// Kick off the DOM ready check even if the user does not
3897jQuery.ready.promise();
3898
3899
3900
3901
3902// Multifunctional method to get and set values of a collection
3903// The value/s can optionally be executed if it's a function
3904var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3905	var i = 0,
3906		len = elems.length,
3907		bulk = key == null;
3908
3909	// Sets many values
3910	if ( jQuery.type( key ) === "object" ) {
3911		chainable = true;
3912		for ( i in key ) {
3913			access( elems, fn, i, key[ i ], true, emptyGet, raw );
3914		}
3915
3916	// Sets one value
3917	} else if ( value !== undefined ) {
3918		chainable = true;
3919
3920		if ( !jQuery.isFunction( value ) ) {
3921			raw = true;
3922		}
3923
3924		if ( bulk ) {
3925
3926			// Bulk operations run against the entire set
3927			if ( raw ) {
3928				fn.call( elems, value );
3929				fn = null;
3930
3931			// ...except when executing function values
3932			} else {
3933				bulk = fn;
3934				fn = function( elem, key, value ) {
3935					return bulk.call( jQuery( elem ), value );
3936				};
3937			}
3938		}
3939
3940		if ( fn ) {
3941			for ( ; i < len; i++ ) {
3942				fn(
3943					elems[ i ], key, raw ?
3944					value :
3945					value.call( elems[ i ], i, fn( elems[ i ], key ) )
3946				);
3947			}
3948		}
3949	}
3950
3951	return chainable ?
3952		elems :
3953
3954		// Gets
3955		bulk ?
3956			fn.call( elems ) :
3957			len ? fn( elems[ 0 ], key ) : emptyGet;
3958};
3959var acceptData = function( owner ) {
3960
3961	// Accepts only:
3962	//  - Node
3963	//    - Node.ELEMENT_NODE
3964	//    - Node.DOCUMENT_NODE
3965	//  - Object
3966	//    - Any
3967	/* jshint -W018 */
3968	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3969};
3970
3971
3972
3973
3974function Data() {
3975	this.expando = jQuery.expando + Data.uid++;
3976}
3977
3978Data.uid = 1;
3979
3980Data.prototype = {
3981
3982	register: function( owner, initial ) {
3983		var value = initial || {};
3984
3985		// If it is a node unlikely to be stringify-ed or looped over
3986		// use plain assignment
3987		if ( owner.nodeType ) {
3988			owner[ this.expando ] = value;
3989
3990		// Otherwise secure it in a non-enumerable, non-writable property
3991		// configurability must be true to allow the property to be
3992		// deleted with the delete operator
3993		} else {
3994			Object.defineProperty( owner, this.expando, {
3995				value: value,
3996				writable: true,
3997				configurable: true
3998			} );
3999		}
4000		return owner[ this.expando ];
4001	},
4002	cache: function( owner ) {
4003
4004		// We can accept data for non-element nodes in modern browsers,
4005		// but we should not, see #8335.
4006		// Always return an empty object.
4007		if ( !acceptData( owner ) ) {
4008			return {};
4009		}
4010
4011		// Check if the owner object already has a cache
4012		var value = owner[ this.expando ];
4013
4014		// If not, create one
4015		if ( !value ) {
4016			value = {};
4017
4018			// We can accept data for non-element nodes in modern browsers,
4019			// but we should not, see #8335.
4020			// Always return an empty object.
4021			if ( acceptData( owner ) ) {
4022
4023				// If it is a node unlikely to be stringify-ed or looped over
4024				// use plain assignment
4025				if ( owner.nodeType ) {
4026					owner[ this.expando ] = value;
4027
4028				// Otherwise secure it in a non-enumerable property
4029				// configurable must be true to allow the property to be
4030				// deleted when data is removed
4031				} else {
4032					Object.defineProperty( owner, this.expando, {
4033						value: value,
4034						configurable: true
4035					} );
4036				}
4037			}
4038		}
4039
4040		return value;
4041	},
4042	set: function( owner, data, value ) {
4043		var prop,
4044			cache = this.cache( owner );
4045
4046		// Handle: [ owner, key, value ] args
4047		if ( typeof data === "string" ) {
4048			cache[ data ] = value;
4049
4050		// Handle: [ owner, { properties } ] args
4051		} else {
4052
4053			// Copy the properties one-by-one to the cache object
4054			for ( prop in data ) {
4055				cache[ prop ] = data[ prop ];
4056			}
4057		}
4058		return cache;
4059	},
4060	get: function( owner, key ) {
4061		return key === undefined ?
4062			this.cache( owner ) :
4063			owner[ this.expando ] && owner[ this.expando ][ key ];
4064	},
4065	access: function( owner, key, value ) {
4066		var stored;
4067
4068		// In cases where either:
4069		//
4070		//   1. No key was specified
4071		//   2. A string key was specified, but no value provided
4072		//
4073		// Take the "read" path and allow the get method to determine
4074		// which value to return, respectively either:
4075		//
4076		//   1. The entire cache object
4077		//   2. The data stored at the key
4078		//
4079		if ( key === undefined ||
4080				( ( key && typeof key === "string" ) && value === undefined ) ) {
4081
4082			stored = this.get( owner, key );
4083
4084			return stored !== undefined ?
4085				stored : this.get( owner, jQuery.camelCase( key ) );
4086		}
4087
4088		// When the key is not a string, or both a key and value
4089		// are specified, set or extend (existing objects) with either:
4090		//
4091		//   1. An object of properties
4092		//   2. A key and value
4093		//
4094		this.set( owner, key, value );
4095
4096		// Since the "set" path can have two possible entry points
4097		// return the expected data based on which path was taken[*]
4098		return value !== undefined ? value : key;
4099	},
4100	remove: function( owner, key ) {
4101		var i, name, camel,
4102			cache = owner[ this.expando ];
4103
4104		if ( cache === undefined ) {
4105			return;
4106		}
4107
4108		if ( key === undefined ) {
4109			this.register( owner );
4110
4111		} else {
4112
4113			// Support array or space separated string of keys
4114			if ( jQuery.isArray( key ) ) {
4115
4116				// If "name" is an array of keys...
4117				// When data is initially created, via ("key", "val") signature,
4118				// keys will be converted to camelCase.
4119				// Since there is no way to tell _how_ a key was added, remove
4120				// both plain key and camelCase key. #12786
4121				// This will only penalize the array argument path.
4122				name = key.concat( key.map( jQuery.camelCase ) );
4123			} else {
4124				camel = jQuery.camelCase( key );
4125
4126				// Try the string as a key before any manipulation
4127				if ( key in cache ) {
4128					name = [ key, camel ];
4129				} else {
4130
4131					// If a key with the spaces exists, use it.
4132					// Otherwise, create an array by matching non-whitespace
4133					name = camel;
4134					name = name in cache ?
4135						[ name ] : ( name.match( rnotwhite ) || [] );
4136				}
4137			}
4138
4139			i = name.length;
4140
4141			while ( i-- ) {
4142				delete cache[ name[ i ] ];
4143			}
4144		}
4145
4146		// Remove the expando if there's no more data
4147		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4148
4149			// Support: Chrome <= 35-45+
4150			// Webkit & Blink performance suffers when deleting properties
4151			// from DOM nodes, so set to undefined instead
4152			// https://code.google.com/p/chromium/issues/detail?id=378607
4153			if ( owner.nodeType ) {
4154				owner[ this.expando ] = undefined;
4155			} else {
4156				delete owner[ this.expando ];
4157			}
4158		}
4159	},
4160	hasData: function( owner ) {
4161		var cache = owner[ this.expando ];
4162		return cache !== undefined && !jQuery.isEmptyObject( cache );
4163	}
4164};
4165var dataPriv = new Data();
4166
4167var dataUser = new Data();
4168
4169
4170
4171//	Implementation Summary
4172//
4173//	1. Enforce API surface and semantic compatibility with 1.9.x branch
4174//	2. Improve the module's maintainability by reducing the storage
4175//		paths to a single mechanism.
4176//	3. Use the same single mechanism to support "private" and "user" data.
4177//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4178//	5. Avoid exposing implementation details on user objects (eg. expando properties)
4179//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
4180
4181var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4182	rmultiDash = /[A-Z]/g;
4183
4184function dataAttr( elem, key, data ) {
4185	var name;
4186
4187	// If nothing was found internally, try to fetch any
4188	// data from the HTML5 data-* attribute
4189	if ( data === undefined && elem.nodeType === 1 ) {
4190		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4191		data = elem.getAttribute( name );
4192
4193		if ( typeof data === "string" ) {
4194			try {
4195				data = data === "true" ? true :
4196					data === "false" ? false :
4197					data === "null" ? null :
4198
4199					// Only convert to a number if it doesn't change the string
4200					+data + "" === data ? +data :
4201					rbrace.test( data ) ? jQuery.parseJSON( data ) :
4202					data;
4203			} catch ( e ) {}
4204
4205			// Make sure we set the data so it isn't changed later
4206			dataUser.set( elem, key, data );
4207		} else {
4208			data = undefined;
4209		}
4210	}
4211	return data;
4212}
4213
4214jQuery.extend( {
4215	hasData: function( elem ) {
4216		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4217	},
4218
4219	data: function( elem, name, data ) {
4220		return dataUser.access( elem, name, data );
4221	},
4222
4223	removeData: function( elem, name ) {
4224		dataUser.remove( elem, name );
4225	},
4226
4227	// TODO: Now that all calls to _data and _removeData have been replaced
4228	// with direct calls to dataPriv methods, these can be deprecated.
4229	_data: function( elem, name, data ) {
4230		return dataPriv.access( elem, name, data );
4231	},
4232
4233	_removeData: function( elem, name ) {
4234		dataPriv.remove( elem, name );
4235	}
4236} );
4237
4238jQuery.fn.extend( {
4239	data: function( key, value ) {
4240		var i, name, data,
4241			elem = this[ 0 ],
4242			attrs = elem && elem.attributes;
4243
4244		// Gets all values
4245		if ( key === undefined ) {
4246			if ( this.length ) {
4247				data = dataUser.get( elem );
4248
4249				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4250					i = attrs.length;
4251					while ( i-- ) {
4252
4253						// Support: IE11+
4254						// The attrs elements can be null (#14894)
4255						if ( attrs[ i ] ) {
4256							name = attrs[ i ].name;
4257							if ( name.indexOf( "data-" ) === 0 ) {
4258								name = jQuery.camelCase( name.slice( 5 ) );
4259								dataAttr( elem, name, data[ name ] );
4260							}
4261						}
4262					}
4263					dataPriv.set( elem, "hasDataAttrs", true );
4264				}
4265			}
4266
4267			return data;
4268		}
4269
4270		// Sets multiple values
4271		if ( typeof key === "object" ) {
4272			return this.each( function() {
4273				dataUser.set( this, key );
4274			} );
4275		}
4276
4277		return access( this, function( value ) {
4278			var data, camelKey;
4279
4280			// The calling jQuery object (element matches) is not empty
4281			// (and therefore has an element appears at this[ 0 ]) and the
4282			// `value` parameter was not undefined. An empty jQuery object
4283			// will result in `undefined` for elem = this[ 0 ] which will
4284			// throw an exception if an attempt to read a data cache is made.
4285			if ( elem && value === undefined ) {
4286
4287				// Attempt to get data from the cache
4288				// with the key as-is
4289				data = dataUser.get( elem, key ) ||
4290
4291					// Try to find dashed key if it exists (gh-2779)
4292					// This is for 2.2.x only
4293					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
4294
4295				if ( data !== undefined ) {
4296					return data;
4297				}
4298
4299				camelKey = jQuery.camelCase( key );
4300
4301				// Attempt to get data from the cache
4302				// with the key camelized
4303				data = dataUser.get( elem, camelKey );
4304				if ( data !== undefined ) {
4305					return data;
4306				}
4307
4308				// Attempt to "discover" the data in
4309				// HTML5 custom data-* attrs
4310				data = dataAttr( elem, camelKey, undefined );
4311				if ( data !== undefined ) {
4312					return data;
4313				}
4314
4315				// We tried really hard, but the data doesn't exist.
4316				return;
4317			}
4318
4319			// Set the data...
4320			camelKey = jQuery.camelCase( key );
4321			this.each( function() {
4322
4323				// First, attempt to store a copy or reference of any
4324				// data that might've been store with a camelCased key.
4325				var data = dataUser.get( this, camelKey );
4326
4327				// For HTML5 data-* attribute interop, we have to
4328				// store property names with dashes in a camelCase form.
4329				// This might not apply to all properties...*
4330				dataUser.set( this, camelKey, value );
4331
4332				// *... In the case of properties that might _actually_
4333				// have dashes, we need to also store a copy of that
4334				// unchanged property.
4335				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
4336					dataUser.set( this, key, value );
4337				}
4338			} );
4339		}, null, value, arguments.length > 1, null, true );
4340	},
4341
4342	removeData: function( key ) {
4343		return this.each( function() {
4344			dataUser.remove( this, key );
4345		} );
4346	}
4347} );
4348
4349
4350jQuery.extend( {
4351	queue: function( elem, type, data ) {
4352		var queue;
4353
4354		if ( elem ) {
4355			type = ( type || "fx" ) + "queue";
4356			queue = dataPriv.get( elem, type );
4357
4358			// Speed up dequeue by getting out quickly if this is just a lookup
4359			if ( data ) {
4360				if ( !queue || jQuery.isArray( data ) ) {
4361					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4362				} else {
4363					queue.push( data );
4364				}
4365			}
4366			return queue || [];
4367		}
4368	},
4369
4370	dequeue: function( elem, type ) {
4371		type = type || "fx";
4372
4373		var queue = jQuery.queue( elem, type ),
4374			startLength = queue.length,
4375			fn = queue.shift(),
4376			hooks = jQuery._queueHooks( elem, type ),
4377			next = function() {
4378				jQuery.dequeue( elem, type );
4379			};
4380
4381		// If the fx queue is dequeued, always remove the progress sentinel
4382		if ( fn === "inprogress" ) {
4383			fn = queue.shift();
4384			startLength--;
4385		}
4386
4387		if ( fn ) {
4388
4389			// Add a progress sentinel to prevent the fx queue from being
4390			// automatically dequeued
4391			if ( type === "fx" ) {
4392				queue.unshift( "inprogress" );
4393			}
4394
4395			// Clear up the last queue stop function
4396			delete hooks.stop;
4397			fn.call( elem, next, hooks );
4398		}
4399
4400		if ( !startLength && hooks ) {
4401			hooks.empty.fire();
4402		}
4403	},
4404
4405	// Not public - generate a queueHooks object, or return the current one
4406	_queueHooks: function( elem, type ) {
4407		var key = type + "queueHooks";
4408		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4409			empty: jQuery.Callbacks( "once memory" ).add( function() {
4410				dataPriv.remove( elem, [ type + "queue", key ] );
4411			} )
4412		} );
4413	}
4414} );
4415
4416jQuery.fn.extend( {
4417	queue: function( type, data ) {
4418		var setter = 2;
4419
4420		if ( typeof type !== "string" ) {
4421			data = type;
4422			type = "fx";
4423			setter--;
4424		}
4425
4426		if ( arguments.length < setter ) {
4427			return jQuery.queue( this[ 0 ], type );
4428		}
4429
4430		return data === undefined ?
4431			this :
4432			this.each( function() {
4433				var queue = jQuery.queue( this, type, data );
4434
4435				// Ensure a hooks for this queue
4436				jQuery._queueHooks( this, type );
4437
4438				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4439					jQuery.dequeue( this, type );
4440				}
4441			} );
4442	},
4443	dequeue: function( type ) {
4444		return this.each( function() {
4445			jQuery.dequeue( this, type );
4446		} );
4447	},
4448	clearQueue: function( type ) {
4449		return this.queue( type || "fx", [] );
4450	},
4451
4452	// Get a promise resolved when queues of a certain type
4453	// are emptied (fx is the type by default)
4454	promise: function( type, obj ) {
4455		var tmp,
4456			count = 1,
4457			defer = jQuery.Deferred(),
4458			elements = this,
4459			i = this.length,
4460			resolve = function() {
4461				if ( !( --count ) ) {
4462					defer.resolveWith( elements, [ elements ] );
4463				}
4464			};
4465
4466		if ( typeof type !== "string" ) {
4467			obj = type;
4468			type = undefined;
4469		}
4470		type = type || "fx";
4471
4472		while ( i-- ) {
4473			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4474			if ( tmp && tmp.empty ) {
4475				count++;
4476				tmp.empty.add( resolve );
4477			}
4478		}
4479		resolve();
4480		return defer.promise( obj );
4481	}
4482} );
4483var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4484
4485var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4486
4487
4488var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4489
4490var isHidden = function( elem, el ) {
4491
4492		// isHidden might be called from jQuery#filter function;
4493		// in that case, element will be second argument
4494		elem = el || elem;
4495		return jQuery.css( elem, "display" ) === "none" ||
4496			!jQuery.contains( elem.ownerDocument, elem );
4497	};
4498
4499
4500
4501function adjustCSS( elem, prop, valueParts, tween ) {
4502	var adjusted,
4503		scale = 1,
4504		maxIterations = 20,
4505		currentValue = tween ?
4506			function() { return tween.cur(); } :
4507			function() { return jQuery.css( elem, prop, "" ); },
4508		initial = currentValue(),
4509		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4510
4511		// Starting value computation is required for potential unit mismatches
4512		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4513			rcssNum.exec( jQuery.css( elem, prop ) );
4514
4515	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4516
4517		// Trust units reported by jQuery.css
4518		unit = unit || initialInUnit[ 3 ];
4519
4520		// Make sure we update the tween properties later on
4521		valueParts = valueParts || [];
4522
4523		// Iteratively approximate from a nonzero starting point
4524		initialInUnit = +initial || 1;
4525
4526		do {
4527
4528			// If previous iteration zeroed out, double until we get *something*.
4529			// Use string for doubling so we don't accidentally see scale as unchanged below
4530			scale = scale || ".5";
4531
4532			// Adjust and apply
4533			initialInUnit = initialInUnit / scale;
4534			jQuery.style( elem, prop, initialInUnit + unit );
4535
4536		// Update scale, tolerating zero or NaN from tween.cur()
4537		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4538		} while (
4539			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4540		);
4541	}
4542
4543	if ( valueParts ) {
4544		initialInUnit = +initialInUnit || +initial || 0;
4545
4546		// Apply relative offset (+=/-=) if specified
4547		adjusted = valueParts[ 1 ] ?
4548			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4549			+valueParts[ 2 ];
4550		if ( tween ) {
4551			tween.unit = unit;
4552			tween.start = initialInUnit;
4553			tween.end = adjusted;
4554		}
4555	}
4556	return adjusted;
4557}
4558var rcheckableType = ( /^(?:checkbox|radio)$/i );
4559
4560var rtagName = ( /<([\w:-]+)/ );
4561
4562var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4563
4564
4565
4566// We have to close these tags to support XHTML (#13200)
4567var wrapMap = {
4568
4569	// Support: IE9
4570	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4571
4572	// XHTML parsers do not magically insert elements in the
4573	// same way that tag soup parsers do. So we cannot shorten
4574	// this by omitting <tbody> or other required elements.
4575	thead: [ 1, "<table>", "</table>" ],
4576	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4577	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4578	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4579
4580	_default: [ 0, "", "" ]
4581};
4582
4583// Support: IE9
4584wrapMap.optgroup = wrapMap.option;
4585
4586wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4587wrapMap.th = wrapMap.td;
4588
4589
4590function getAll( context, tag ) {
4591
4592	// Support: IE9-11+
4593	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
4594	var ret = typeof context.getElementsByTagName !== "undefined" ?
4595			context.getElementsByTagName( tag || "*" ) :
4596			typeof context.querySelectorAll !== "undefined" ?
4597				context.querySelectorAll( tag || "*" ) :
4598			[];
4599
4600	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4601		jQuery.merge( [ context ], ret ) :
4602		ret;
4603}
4604
4605
4606// Mark scripts as having already been evaluated
4607function setGlobalEval( elems, refElements ) {
4608	var i = 0,
4609		l = elems.length;
4610
4611	for ( ; i < l; i++ ) {
4612		dataPriv.set(
4613			elems[ i ],
4614			"globalEval",
4615			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
4616		);
4617	}
4618}
4619
4620
4621var rhtml = /<|&#?\w+;/;
4622
4623function buildFragment( elems, context, scripts, selection, ignored ) {
4624	var elem, tmp, tag, wrap, contains, j,
4625		fragment = context.createDocumentFragment(),
4626		nodes = [],
4627		i = 0,
4628		l = elems.length;
4629
4630	for ( ; i < l; i++ ) {
4631		elem = elems[ i ];
4632
4633		if ( elem || elem === 0 ) {
4634
4635			// Add nodes directly
4636			if ( jQuery.type( elem ) === "object" ) {
4637
4638				// Support: Android<4.1, PhantomJS<2
4639				// push.apply(_, arraylike) throws on ancient WebKit
4640				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4641
4642			// Convert non-html into a text node
4643			} else if ( !rhtml.test( elem ) ) {
4644				nodes.push( context.createTextNode( elem ) );
4645
4646			// Convert html into DOM nodes
4647			} else {
4648				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4649
4650				// Deserialize a standard representation
4651				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4652				wrap = wrapMap[ tag ] || wrapMap._default;
4653				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4654
4655				// Descend through wrappers to the right content
4656				j = wrap[ 0 ];
4657				while ( j-- ) {
4658					tmp = tmp.lastChild;
4659				}
4660
4661				// Support: Android<4.1, PhantomJS<2
4662				// push.apply(_, arraylike) throws on ancient WebKit
4663				jQuery.merge( nodes, tmp.childNodes );
4664
4665				// Remember the top-level container
4666				tmp = fragment.firstChild;
4667
4668				// Ensure the created nodes are orphaned (#12392)
4669				tmp.textContent = "";
4670			}
4671		}
4672	}
4673
4674	// Remove wrapper from fragment
4675	fragment.textContent = "";
4676
4677	i = 0;
4678	while ( ( elem = nodes[ i++ ] ) ) {
4679
4680		// Skip elements already in the context collection (trac-4087)
4681		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4682			if ( ignored ) {
4683				ignored.push( elem );
4684			}
4685			continue;
4686		}
4687
4688		contains = jQuery.contains( elem.ownerDocument, elem );
4689
4690		// Append to fragment
4691		tmp = getAll( fragment.appendChild( elem ), "script" );
4692
4693		// Preserve script evaluation history
4694		if ( contains ) {
4695			setGlobalEval( tmp );
4696		}
4697
4698		// Capture executables
4699		if ( scripts ) {
4700			j = 0;
4701			while ( ( elem = tmp[ j++ ] ) ) {
4702				if ( rscriptType.test( elem.type || "" ) ) {
4703					scripts.push( elem );
4704				}
4705			}
4706		}
4707	}
4708
4709	return fragment;
4710}
4711
4712
4713( function() {
4714	var fragment = document.createDocumentFragment(),
4715		div = fragment.appendChild( document.createElement( "div" ) ),
4716		input = document.createElement( "input" );
4717
4718	// Support: Android 4.0-4.3, Safari<=5.1
4719	// Check state lost if the name is set (#11217)
4720	// Support: Windows Web Apps (WWA)
4721	// `name` and `type` must use .setAttribute for WWA (#14901)
4722	input.setAttribute( "type", "radio" );
4723	input.setAttribute( "checked", "checked" );
4724	input.setAttribute( "name", "t" );
4725
4726	div.appendChild( input );
4727
4728	// Support: Safari<=5.1, Android<4.2
4729	// Older WebKit doesn't clone checked state correctly in fragments
4730	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4731
4732	// Support: IE<=11+
4733	// Make sure textarea (and checkbox) defaultValue is properly cloned
4734	div.innerHTML = "<textarea>x</textarea>";
4735	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4736} )();
4737
4738
4739var
4740	rkeyEvent = /^key/,
4741	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4742	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4743
4744function returnTrue() {
4745	return true;
4746}
4747
4748function returnFalse() {
4749	return false;
4750}
4751
4752// Support: IE9
4753// See #13393 for more info
4754function safeActiveElement() {
4755	try {
4756		return document.activeElement;
4757	} catch ( err ) { }
4758}
4759
4760function on( elem, types, selector, data, fn, one ) {
4761	var origFn, type;
4762
4763	// Types can be a map of types/handlers
4764	if ( typeof types === "object" ) {
4765
4766		// ( types-Object, selector, data )
4767		if ( typeof selector !== "string" ) {
4768
4769			// ( types-Object, data )
4770			data = data || selector;
4771			selector = undefined;
4772		}
4773		for ( type in types ) {
4774			on( elem, type, selector, data, types[ type ], one );
4775		}
4776		return elem;
4777	}
4778
4779	if ( data == null && fn == null ) {
4780
4781		// ( types, fn )
4782		fn = selector;
4783		data = selector = undefined;
4784	} else if ( fn == null ) {
4785		if ( typeof selector === "string" ) {
4786
4787			// ( types, selector, fn )
4788			fn = data;
4789			data = undefined;
4790		} else {
4791
4792			// ( types, data, fn )
4793			fn = data;
4794			data = selector;
4795			selector = undefined;
4796		}
4797	}
4798	if ( fn === false ) {
4799		fn = returnFalse;
4800	} else if ( !fn ) {
4801		return elem;
4802	}
4803
4804	if ( one === 1 ) {
4805		origFn = fn;
4806		fn = function( event ) {
4807
4808			// Can use an empty set, since event contains the info
4809			jQuery().off( event );
4810			return origFn.apply( this, arguments );
4811		};
4812
4813		// Use same guid so caller can remove using origFn
4814		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4815	}
4816	return elem.each( function() {
4817		jQuery.event.add( this, types, fn, data, selector );
4818	} );
4819}
4820
4821/*
4822 * Helper functions for managing events -- not part of the public interface.
4823 * Props to Dean Edwards' addEvent library for many of the ideas.
4824 */
4825jQuery.event = {
4826
4827	global: {},
4828
4829	add: function( elem, types, handler, data, selector ) {
4830
4831		var handleObjIn, eventHandle, tmp,
4832			events, t, handleObj,
4833			special, handlers, type, namespaces, origType,
4834			elemData = dataPriv.get( elem );
4835
4836		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4837		if ( !elemData ) {
4838			return;
4839		}
4840
4841		// Caller can pass in an object of custom data in lieu of the handler
4842		if ( handler.handler ) {
4843			handleObjIn = handler;
4844			handler = handleObjIn.handler;
4845			selector = handleObjIn.selector;
4846		}
4847
4848		// Make sure that the handler has a unique ID, used to find/remove it later
4849		if ( !handler.guid ) {
4850			handler.guid = jQuery.guid++;
4851		}
4852
4853		// Init the element's event structure and main handler, if this is the first
4854		if ( !( events = elemData.events ) ) {
4855			events = elemData.events = {};
4856		}
4857		if ( !( eventHandle = elemData.handle ) ) {
4858			eventHandle = elemData.handle = function( e ) {
4859
4860				// Discard the second event of a jQuery.event.trigger() and
4861				// when an event is called after a page has unloaded
4862				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4863					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4864			};
4865		}
4866
4867		// Handle multiple events separated by a space
4868		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4869		t = types.length;
4870		while ( t-- ) {
4871			tmp = rtypenamespace.exec( types[ t ] ) || [];
4872			type = origType = tmp[ 1 ];
4873			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4874
4875			// There *must* be a type, no attaching namespace-only handlers
4876			if ( !type ) {
4877				continue;
4878			}
4879
4880			// If event changes its type, use the special event handlers for the changed type
4881			special = jQuery.event.special[ type ] || {};
4882
4883			// If selector defined, determine special event api type, otherwise given type
4884			type = ( selector ? special.delegateType : special.bindType ) || type;
4885
4886			// Update special based on newly reset type
4887			special = jQuery.event.special[ type ] || {};
4888
4889			// handleObj is passed to all event handlers
4890			handleObj = jQuery.extend( {
4891				type: type,
4892				origType: origType,
4893				data: data,
4894				handler: handler,
4895				guid: handler.guid,
4896				selector: selector,
4897				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4898				namespace: namespaces.join( "." )
4899			}, handleObjIn );
4900
4901			// Init the event handler queue if we're the first
4902			if ( !( handlers = events[ type ] ) ) {
4903				handlers = events[ type ] = [];
4904				handlers.delegateCount = 0;
4905
4906				// Only use addEventListener if the special events handler returns false
4907				if ( !special.setup ||
4908					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4909
4910					if ( elem.addEventListener ) {
4911						elem.addEventListener( type, eventHandle );
4912					}
4913				}
4914			}
4915
4916			if ( special.add ) {
4917				special.add.call( elem, handleObj );
4918
4919				if ( !handleObj.handler.guid ) {
4920					handleObj.handler.guid = handler.guid;
4921				}
4922			}
4923
4924			// Add to the element's handler list, delegates in front
4925			if ( selector ) {
4926				handlers.splice( handlers.delegateCount++, 0, handleObj );
4927			} else {
4928				handlers.push( handleObj );
4929			}
4930
4931			// Keep track of which events have ever been used, for event optimization
4932			jQuery.event.global[ type ] = true;
4933		}
4934
4935	},
4936
4937	// Detach an event or set of events from an element
4938	remove: function( elem, types, handler, selector, mappedTypes ) {
4939
4940		var j, origCount, tmp,
4941			events, t, handleObj,
4942			special, handlers, type, namespaces, origType,
4943			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
4944
4945		if ( !elemData || !( events = elemData.events ) ) {
4946			return;
4947		}
4948
4949		// Once for each type.namespace in types; type may be omitted
4950		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4951		t = types.length;
4952		while ( t-- ) {
4953			tmp = rtypenamespace.exec( types[ t ] ) || [];
4954			type = origType = tmp[ 1 ];
4955			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4956
4957			// Unbind all events (on this namespace, if provided) for the element
4958			if ( !type ) {
4959				for ( type in events ) {
4960					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4961				}
4962				continue;
4963			}
4964
4965			special = jQuery.event.special[ type ] || {};
4966			type = ( selector ? special.delegateType : special.bindType ) || type;
4967			handlers = events[ type ] || [];
4968			tmp = tmp[ 2 ] &&
4969				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4970
4971			// Remove matching events
4972			origCount = j = handlers.length;
4973			while ( j-- ) {
4974				handleObj = handlers[ j ];
4975
4976				if ( ( mappedTypes || origType === handleObj.origType ) &&
4977					( !handler || handler.guid === handleObj.guid ) &&
4978					( !tmp || tmp.test( handleObj.namespace ) ) &&
4979					( !selector || selector === handleObj.selector ||
4980						selector === "**" && handleObj.selector ) ) {
4981					handlers.splice( j, 1 );
4982
4983					if ( handleObj.selector ) {
4984						handlers.delegateCount--;
4985					}
4986					if ( special.remove ) {
4987						special.remove.call( elem, handleObj );
4988					}
4989				}
4990			}
4991
4992			// Remove generic event handler if we removed something and no more handlers exist
4993			// (avoids potential for endless recursion during removal of special event handlers)
4994			if ( origCount && !handlers.length ) {
4995				if ( !special.teardown ||
4996					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4997
4998					jQuery.removeEvent( elem, type, elemData.handle );
4999				}
5000
5001				delete events[ type ];
5002			}
5003		}
5004
5005		// Remove data and the expando if it's no longer used
5006		if ( jQuery.isEmptyObject( events ) ) {
5007			dataPriv.remove( elem, "handle events" );
5008		}
5009	},
5010
5011	dispatch: function( event ) {
5012
5013		// Make a writable jQuery.Event from the native event object
5014		event = jQuery.event.fix( event );
5015
5016		var i, j, ret, matched, handleObj,
5017			handlerQueue = [],
5018			args = slice.call( arguments ),
5019			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
5020			special = jQuery.event.special[ event.type ] || {};
5021
5022		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5023		args[ 0 ] = event;
5024		event.delegateTarget = this;
5025
5026		// Call the preDispatch hook for the mapped type, and let it bail if desired
5027		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5028			return;
5029		}
5030
5031		// Determine handlers
5032		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5033
5034		// Run delegates first; they may want to stop propagation beneath us
5035		i = 0;
5036		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5037			event.currentTarget = matched.elem;
5038
5039			j = 0;
5040			while ( ( handleObj = matched.handlers[ j++ ] ) &&
5041				!event.isImmediatePropagationStopped() ) {
5042
5043				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
5044				// a subset or equal to those in the bound event (both can have no namespace).
5045				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5046
5047					event.handleObj = handleObj;
5048					event.data = handleObj.data;
5049
5050					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5051						handleObj.handler ).apply( matched.elem, args );
5052
5053					if ( ret !== undefined ) {
5054						if ( ( event.result = ret ) === false ) {
5055							event.preventDefault();
5056							event.stopPropagation();
5057						}
5058					}
5059				}
5060			}
5061		}
5062
5063		// Call the postDispatch hook for the mapped type
5064		if ( special.postDispatch ) {
5065			special.postDispatch.call( this, event );
5066		}
5067
5068		return event.result;
5069	},
5070
5071	handlers: function( event, handlers ) {
5072		var i, matches, sel, handleObj,
5073			handlerQueue = [],
5074			delegateCount = handlers.delegateCount,
5075			cur = event.target;
5076
5077		// Support (at least): Chrome, IE9
5078		// Find delegate handlers
5079		// Black-hole SVG <use> instance trees (#13180)
5080		//
5081		// Support: Firefox<=42+
5082		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5083		if ( delegateCount && cur.nodeType &&
5084			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
5085
5086			for ( ; cur !== this; cur = cur.parentNode || this ) {
5087
5088				// Don't check non-elements (#13208)
5089				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5090				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
5091					matches = [];
5092					for ( i = 0; i < delegateCount; i++ ) {
5093						handleObj = handlers[ i ];
5094
5095						// Don't conflict with Object.prototype properties (#13203)
5096						sel = handleObj.selector + " ";
5097
5098						if ( matches[ sel ] === undefined ) {
5099							matches[ sel ] = handleObj.needsContext ?
5100								jQuery( sel, this ).index( cur ) > -1 :
5101								jQuery.find( sel, this, null, [ cur ] ).length;
5102						}
5103						if ( matches[ sel ] ) {
5104							matches.push( handleObj );
5105						}
5106					}
5107					if ( matches.length ) {
5108						handlerQueue.push( { elem: cur, handlers: matches } );
5109					}
5110				}
5111			}
5112		}
5113
5114		// Add the remaining (directly-bound) handlers
5115		if ( delegateCount < handlers.length ) {
5116			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
5117		}
5118
5119		return handlerQueue;
5120	},
5121
5122	// Includes some event props shared by KeyEvent and MouseEvent
5123	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
5124		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
5125
5126	fixHooks: {},
5127
5128	keyHooks: {
5129		props: "char charCode key keyCode".split( " " ),
5130		filter: function( event, original ) {
5131
5132			// Add which for key events
5133			if ( event.which == null ) {
5134				event.which = original.charCode != null ? original.charCode : original.keyCode;
5135			}
5136
5137			return event;
5138		}
5139	},
5140
5141	mouseHooks: {
5142		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
5143			"screenX screenY toElement" ).split( " " ),
5144		filter: function( event, original ) {
5145			var eventDoc, doc, body,
5146				button = original.button;
5147
5148			// Calculate pageX/Y if missing and clientX/Y available
5149			if ( event.pageX == null && original.clientX != null ) {
5150				eventDoc = event.target.ownerDocument || document;
5151				doc = eventDoc.documentElement;
5152				body = eventDoc.body;
5153
5154				event.pageX = original.clientX +
5155					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
5156					( doc && doc.clientLeft || body && body.clientLeft || 0 );
5157				event.pageY = original.clientY +
5158					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
5159					( doc && doc.clientTop  || body && body.clientTop  || 0 );
5160			}
5161
5162			// Add which for click: 1 === left; 2 === middle; 3 === right
5163			// Note: button is not normalized, so don't use it
5164			if ( !event.which && button !== undefined ) {
5165				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
5166			}
5167
5168			return event;
5169		}
5170	},
5171
5172	fix: function( event ) {
5173		if ( event[ jQuery.expando ] ) {
5174			return event;
5175		}
5176
5177		// Create a writable copy of the event object and normalize some properties
5178		var i, prop, copy,
5179			type = event.type,
5180			originalEvent = event,
5181			fixHook = this.fixHooks[ type ];
5182
5183		if ( !fixHook ) {
5184			this.fixHooks[ type ] = fixHook =
5185				rmouseEvent.test( type ) ? this.mouseHooks :
5186				rkeyEvent.test( type ) ? this.keyHooks :
5187				{};
5188		}
5189		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
5190
5191		event = new jQuery.Event( originalEvent );
5192
5193		i = copy.length;
5194		while ( i-- ) {
5195			prop = copy[ i ];
5196			event[ prop ] = originalEvent[ prop ];
5197		}
5198
5199		// Support: Cordova 2.5 (WebKit) (#13255)
5200		// All events should have a target; Cordova deviceready doesn't
5201		if ( !event.target ) {
5202			event.target = document;
5203		}
5204
5205		// Support: Safari 6.0+, Chrome<28
5206		// Target should not be a text node (#504, #13143)
5207		if ( event.target.nodeType === 3 ) {
5208			event.target = event.target.parentNode;
5209		}
5210
5211		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
5212	},
5213
5214	special: {
5215		load: {
5216
5217			// Prevent triggered image.load events from bubbling to window.load
5218			noBubble: true
5219		},
5220		focus: {
5221
5222			// Fire native event if possible so blur/focus sequence is correct
5223			trigger: function() {
5224				if ( this !== safeActiveElement() && this.focus ) {
5225					this.focus();
5226					return false;
5227				}
5228			},
5229			delegateType: "focusin"
5230		},
5231		blur: {
5232			trigger: function() {
5233				if ( this === safeActiveElement() && this.blur ) {
5234					this.blur();
5235					return false;
5236				}
5237			},
5238			delegateType: "focusout"
5239		},
5240		click: {
5241
5242			// For checkbox, fire native event so checked state will be right
5243			trigger: function() {
5244				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
5245					this.click();
5246					return false;
5247				}
5248			},
5249
5250			// For cross-browser consistency, don't fire native .click() on links
5251			_default: function( event ) {
5252				return jQuery.nodeName( event.target, "a" );
5253			}
5254		},
5255
5256		beforeunload: {
5257			postDispatch: function( event ) {
5258
5259				// Support: Firefox 20+
5260				// Firefox doesn't alert if the returnValue field is not set.
5261				if ( event.result !== undefined && event.originalEvent ) {
5262					event.originalEvent.returnValue = event.result;
5263				}
5264			}
5265		}
5266	}
5267};
5268
5269jQuery.removeEvent = function( elem, type, handle ) {
5270
5271	// This "if" is needed for plain objects
5272	if ( elem.removeEventListener ) {
5273		elem.removeEventListener( type, handle );
5274	}
5275};
5276
5277jQuery.Event = function( src, props ) {
5278
5279	// Allow instantiation without the 'new' keyword
5280	if ( !( this instanceof jQuery.Event ) ) {
5281		return new jQuery.Event( src, props );
5282	}
5283
5284	// Event object
5285	if ( src && src.type ) {
5286		this.originalEvent = src;
5287		this.type = src.type;
5288
5289		// Events bubbling up the document may have been marked as prevented
5290		// by a handler lower down the tree; reflect the correct value.
5291		this.isDefaultPrevented = src.defaultPrevented ||
5292				src.defaultPrevented === undefined &&
5293
5294				// Support: Android<4.0
5295				src.returnValue === false ?
5296			returnTrue :
5297			returnFalse;
5298
5299	// Event type
5300	} else {
5301		this.type = src;
5302	}
5303
5304	// Put explicitly provided properties onto the event object
5305	if ( props ) {
5306		jQuery.extend( this, props );
5307	}
5308
5309	// Create a timestamp if incoming event doesn't have one
5310	this.timeStamp = src && src.timeStamp || jQuery.now();
5311
5312	// Mark it as fixed
5313	this[ jQuery.expando ] = true;
5314};
5315
5316// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5317// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5318jQuery.Event.prototype = {
5319	constructor: jQuery.Event,
5320	isDefaultPrevented: returnFalse,
5321	isPropagationStopped: returnFalse,
5322	isImmediatePropagationStopped: returnFalse,
5323	isSimulated: false,
5324
5325	preventDefault: function() {
5326		var e = this.originalEvent;
5327
5328		this.isDefaultPrevented = returnTrue;
5329
5330		if ( e && !this.isSimulated ) {
5331			e.preventDefault();
5332		}
5333	},
5334	stopPropagation: function() {
5335		var e = this.originalEvent;
5336
5337		this.isPropagationStopped = returnTrue;
5338
5339		if ( e && !this.isSimulated ) {
5340			e.stopPropagation();
5341		}
5342	},
5343	stopImmediatePropagation: function() {
5344		var e = this.originalEvent;
5345
5346		this.isImmediatePropagationStopped = returnTrue;
5347
5348		if ( e && !this.isSimulated ) {
5349			e.stopImmediatePropagation();
5350		}
5351
5352		this.stopPropagation();
5353	}
5354};
5355
5356// Create mouseenter/leave events using mouseover/out and event-time checks
5357// so that event delegation works in jQuery.
5358// Do the same for pointerenter/pointerleave and pointerover/pointerout
5359//
5360// Support: Safari 7 only
5361// Safari sends mouseenter too often; see:
5362// https://code.google.com/p/chromium/issues/detail?id=470258
5363// for the description of the bug (it existed in older Chrome versions as well).
5364jQuery.each( {
5365	mouseenter: "mouseover",
5366	mouseleave: "mouseout",
5367	pointerenter: "pointerover",
5368	pointerleave: "pointerout"
5369}, function( orig, fix ) {
5370	jQuery.event.special[ orig ] = {
5371		delegateType: fix,
5372		bindType: fix,
5373
5374		handle: function( event ) {
5375			var ret,
5376				target = this,
5377				related = event.relatedTarget,
5378				handleObj = event.handleObj;
5379
5380			// For mouseenter/leave call the handler if related is outside the target.
5381			// NB: No relatedTarget if the mouse left/entered the browser window
5382			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5383				event.type = handleObj.origType;
5384				ret = handleObj.handler.apply( this, arguments );
5385				event.type = fix;
5386			}
5387			return ret;
5388		}
5389	};
5390} );
5391
5392jQuery.fn.extend( {
5393	on: function( types, selector, data, fn ) {
5394		return on( this, types, selector, data, fn );
5395	},
5396	one: function( types, selector, data, fn ) {
5397		return on( this, types, selector, data, fn, 1 );
5398	},
5399	off: function( types, selector, fn ) {
5400		var handleObj, type;
5401		if ( types && types.preventDefault && types.handleObj ) {
5402
5403			// ( event )  dispatched jQuery.Event
5404			handleObj = types.handleObj;
5405			jQuery( types.delegateTarget ).off(
5406				handleObj.namespace ?
5407					handleObj.origType + "." + handleObj.namespace :
5408					handleObj.origType,
5409				handleObj.selector,
5410				handleObj.handler
5411			);
5412			return this;
5413		}
5414		if ( typeof types === "object" ) {
5415
5416			// ( types-object [, selector] )
5417			for ( type in types ) {
5418				this.off( type, selector, types[ type ] );
5419			}
5420			return this;
5421		}
5422		if ( selector === false || typeof selector === "function" ) {
5423
5424			// ( types [, fn] )
5425			fn = selector;
5426			selector = undefined;
5427		}
5428		if ( fn === false ) {
5429			fn = returnFalse;
5430		}
5431		return this.each( function() {
5432			jQuery.event.remove( this, types, fn, selector );
5433		} );
5434	}
5435} );
5436
5437
5438var
5439	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5440
5441	// Support: IE 10-11, Edge 10240+
5442	// In IE/Edge using regex groups here causes severe slowdowns.
5443	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5444	rnoInnerhtml = /<script|<style|<link/i,
5445
5446	// checked="checked" or checked
5447	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5448	rscriptTypeMasked = /^true\/(.*)/,
5449	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5450
5451// Manipulating tables requires a tbody
5452function manipulationTarget( elem, content ) {
5453	return jQuery.nodeName( elem, "table" ) &&
5454		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5455
5456		elem.getElementsByTagName( "tbody" )[ 0 ] ||
5457			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5458		elem;
5459}
5460
5461// Replace/restore the type attribute of script elements for safe DOM manipulation
5462function disableScript( elem ) {
5463	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5464	return elem;
5465}
5466function restoreScript( elem ) {
5467	var match = rscriptTypeMasked.exec( elem.type );
5468
5469	if ( match ) {
5470		elem.type = match[ 1 ];
5471	} else {
5472		elem.removeAttribute( "type" );
5473	}
5474
5475	return elem;
5476}
5477
5478function cloneCopyEvent( src, dest ) {
5479	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5480
5481	if ( dest.nodeType !== 1 ) {
5482		return;
5483	}
5484
5485	// 1. Copy private data: events, handlers, etc.
5486	if ( dataPriv.hasData( src ) ) {
5487		pdataOld = dataPriv.access( src );
5488		pdataCur = dataPriv.set( dest, pdataOld );
5489		events = pdataOld.events;
5490
5491		if ( events ) {
5492			delete pdataCur.handle;
5493			pdataCur.events = {};
5494
5495			for ( type in events ) {
5496				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5497					jQuery.event.add( dest, type, events[ type ][ i ] );
5498				}
5499			}
5500		}
5501	}
5502
5503	// 2. Copy user data
5504	if ( dataUser.hasData( src ) ) {
5505		udataOld = dataUser.access( src );
5506		udataCur = jQuery.extend( {}, udataOld );
5507
5508		dataUser.set( dest, udataCur );
5509	}
5510}
5511
5512// Fix IE bugs, see support tests
5513function fixInput( src, dest ) {
5514	var nodeName = dest.nodeName.toLowerCase();
5515
5516	// Fails to persist the checked state of a cloned checkbox or radio button.
5517	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5518		dest.checked = src.checked;
5519
5520	// Fails to return the selected option to the default selected state when cloning options
5521	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5522		dest.defaultValue = src.defaultValue;
5523	}
5524}
5525
5526function domManip( collection, args, callback, ignored ) {
5527
5528	// Flatten any nested arrays
5529	args = concat.apply( [], args );
5530
5531	var fragment, first, scripts, hasScripts, node, doc,
5532		i = 0,
5533		l = collection.length,
5534		iNoClone = l - 1,
5535		value = args[ 0 ],
5536		isFunction = jQuery.isFunction( value );
5537
5538	// We can't cloneNode fragments that contain checked, in WebKit
5539	if ( isFunction ||
5540			( l > 1 && typeof value === "string" &&
5541				!support.checkClone && rchecked.test( value ) ) ) {
5542		return collection.each( function( index ) {
5543			var self = collection.eq( index );
5544			if ( isFunction ) {
5545				args[ 0 ] = value.call( this, index, self.html() );
5546			}
5547			domManip( self, args, callback, ignored );
5548		} );
5549	}
5550
5551	if ( l ) {
5552		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5553		first = fragment.firstChild;
5554
5555		if ( fragment.childNodes.length === 1 ) {
5556			fragment = first;
5557		}
5558
5559		// Require either new content or an interest in ignored elements to invoke the callback
5560		if ( first || ignored ) {
5561			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5562			hasScripts = scripts.length;
5563
5564			// Use the original fragment for the last item
5565			// instead of the first because it can end up
5566			// being emptied incorrectly in certain situations (#8070).
5567			for ( ; i < l; i++ ) {
5568				node = fragment;
5569
5570				if ( i !== iNoClone ) {
5571					node = jQuery.clone( node, true, true );
5572
5573					// Keep references to cloned scripts for later restoration
5574					if ( hasScripts ) {
5575
5576						// Support: Android<4.1, PhantomJS<2
5577						// push.apply(_, arraylike) throws on ancient WebKit
5578						jQuery.merge( scripts, getAll( node, "script" ) );
5579					}
5580				}
5581
5582				callback.call( collection[ i ], node, i );
5583			}
5584
5585			if ( hasScripts ) {
5586				doc = scripts[ scripts.length - 1 ].ownerDocument;
5587
5588				// Reenable scripts
5589				jQuery.map( scripts, restoreScript );
5590
5591				// Evaluate executable scripts on first document insertion
5592				for ( i = 0; i < hasScripts; i++ ) {
5593					node = scripts[ i ];
5594					if ( rscriptType.test( node.type || "" ) &&
5595						!dataPriv.access( node, "globalEval" ) &&
5596						jQuery.contains( doc, node ) ) {
5597
5598						if ( node.src ) {
5599
5600							// Optional AJAX dependency, but won't run scripts if not present
5601							if ( jQuery._evalUrl ) {
5602								jQuery._evalUrl( node.src );
5603							}
5604						} else {
5605							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5606						}
5607					}
5608				}
5609			}
5610		}
5611	}
5612
5613	return collection;
5614}
5615
5616function remove( elem, selector, keepData ) {
5617	var node,
5618		nodes = selector ? jQuery.filter( selector, elem ) : elem,
5619		i = 0;
5620
5621	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5622		if ( !keepData && node.nodeType === 1 ) {
5623			jQuery.cleanData( getAll( node ) );
5624		}
5625
5626		if ( node.parentNode ) {
5627			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5628				setGlobalEval( getAll( node, "script" ) );
5629			}
5630			node.parentNode.removeChild( node );
5631		}
5632	}
5633
5634	return elem;
5635}
5636
5637jQuery.extend( {
5638	htmlPrefilter: function( html ) {
5639		return html.replace( rxhtmlTag, "<$1></$2>" );
5640	},
5641
5642	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5643		var i, l, srcElements, destElements,
5644			clone = elem.cloneNode( true ),
5645			inPage = jQuery.contains( elem.ownerDocument, elem );
5646
5647		// Fix IE cloning issues
5648		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5649				!jQuery.isXMLDoc( elem ) ) {
5650
5651			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5652			destElements = getAll( clone );
5653			srcElements = getAll( elem );
5654
5655			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5656				fixInput( srcElements[ i ], destElements[ i ] );
5657			}
5658		}
5659
5660		// Copy the events from the original to the clone
5661		if ( dataAndEvents ) {
5662			if ( deepDataAndEvents ) {
5663				srcElements = srcElements || getAll( elem );
5664				destElements = destElements || getAll( clone );
5665
5666				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5667					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5668				}
5669			} else {
5670				cloneCopyEvent( elem, clone );
5671			}
5672		}
5673
5674		// Preserve script evaluation history
5675		destElements = getAll( clone, "script" );
5676		if ( destElements.length > 0 ) {
5677			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5678		}
5679
5680		// Return the cloned set
5681		return clone;
5682	},
5683
5684	cleanData: function( elems ) {
5685		var data, elem, type,
5686			special = jQuery.event.special,
5687			i = 0;
5688
5689		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5690			if ( acceptData( elem ) ) {
5691				if ( ( data = elem[ dataPriv.expando ] ) ) {
5692					if ( data.events ) {
5693						for ( type in data.events ) {
5694							if ( special[ type ] ) {
5695								jQuery.event.remove( elem, type );
5696
5697							// This is a shortcut to avoid jQuery.event.remove's overhead
5698							} else {
5699								jQuery.removeEvent( elem, type, data.handle );
5700							}
5701						}
5702					}
5703
5704					// Support: Chrome <= 35-45+
5705					// Assign undefined instead of using delete, see Data#remove
5706					elem[ dataPriv.expando ] = undefined;
5707				}
5708				if ( elem[ dataUser.expando ] ) {
5709
5710					// Support: Chrome <= 35-45+
5711					// Assign undefined instead of using delete, see Data#remove
5712					elem[ dataUser.expando ] = undefined;
5713				}
5714			}
5715		}
5716	}
5717} );
5718
5719jQuery.fn.extend( {
5720
5721	// Keep domManip exposed until 3.0 (gh-2225)
5722	domManip: domManip,
5723
5724	detach: function( selector ) {
5725		return remove( this, selector, true );
5726	},
5727
5728	remove: function( selector ) {
5729		return remove( this, selector );
5730	},
5731
5732	text: function( value ) {
5733		return access( this, function( value ) {
5734			return value === undefined ?
5735				jQuery.text( this ) :
5736				this.empty().each( function() {
5737					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5738						this.textContent = value;
5739					}
5740				} );
5741		}, null, value, arguments.length );
5742	},
5743
5744	append: function() {
5745		return domManip( this, arguments, function( elem ) {
5746			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5747				var target = manipulationTarget( this, elem );
5748				target.appendChild( elem );
5749			}
5750		} );
5751	},
5752
5753	prepend: function() {
5754		return domManip( this, arguments, function( elem ) {
5755			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5756				var target = manipulationTarget( this, elem );
5757				target.insertBefore( elem, target.firstChild );
5758			}
5759		} );
5760	},
5761
5762	before: function() {
5763		return domManip( this, arguments, function( elem ) {
5764			if ( this.parentNode ) {
5765				this.parentNode.insertBefore( elem, this );
5766			}
5767		} );
5768	},
5769
5770	after: function() {
5771		return domManip( this, arguments, function( elem ) {
5772			if ( this.parentNode ) {
5773				this.parentNode.insertBefore( elem, this.nextSibling );
5774			}
5775		} );
5776	},
5777
5778	empty: function() {
5779		var elem,
5780			i = 0;
5781
5782		for ( ; ( elem = this[ i ] ) != null; i++ ) {
5783			if ( elem.nodeType === 1 ) {
5784
5785				// Prevent memory leaks
5786				jQuery.cleanData( getAll( elem, false ) );
5787
5788				// Remove any remaining nodes
5789				elem.textContent = "";
5790			}
5791		}
5792
5793		return this;
5794	},
5795
5796	clone: function( dataAndEvents, deepDataAndEvents ) {
5797		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5798		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5799
5800		return this.map( function() {
5801			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5802		} );
5803	},
5804
5805	html: function( value ) {
5806		return access( this, function( value ) {
5807			var elem = this[ 0 ] || {},
5808				i = 0,
5809				l = this.length;
5810
5811			if ( value === undefined && elem.nodeType === 1 ) {
5812				return elem.innerHTML;
5813			}
5814
5815			// See if we can take a shortcut and just use innerHTML
5816			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5817				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5818
5819				value = jQuery.htmlPrefilter( value );
5820
5821				try {
5822					for ( ; i < l; i++ ) {
5823						elem = this[ i ] || {};
5824
5825						// Remove element nodes and prevent memory leaks
5826						if ( elem.nodeType === 1 ) {
5827							jQuery.cleanData( getAll( elem, false ) );
5828							elem.innerHTML = value;
5829						}
5830					}
5831
5832					elem = 0;
5833
5834				// If using innerHTML throws an exception, use the fallback method
5835				} catch ( e ) {}
5836			}
5837
5838			if ( elem ) {
5839				this.empty().append( value );
5840			}
5841		}, null, value, arguments.length );
5842	},
5843
5844	replaceWith: function() {
5845		var ignored = [];
5846
5847		// Make the changes, replacing each non-ignored context element with the new content
5848		return domManip( this, arguments, function( elem ) {
5849			var parent = this.parentNode;
5850
5851			if ( jQuery.inArray( this, ignored ) < 0 ) {
5852				jQuery.cleanData( getAll( this ) );
5853				if ( parent ) {
5854					parent.replaceChild( elem, this );
5855				}
5856			}
5857
5858		// Force callback invocation
5859		}, ignored );
5860	}
5861} );
5862
5863jQuery.each( {
5864	appendTo: "append",
5865	prependTo: "prepend",
5866	insertBefore: "before",
5867	insertAfter: "after",
5868	replaceAll: "replaceWith"
5869}, function( name, original ) {
5870	jQuery.fn[ name ] = function( selector ) {
5871		var elems,
5872			ret = [],
5873			insert = jQuery( selector ),
5874			last = insert.length - 1,
5875			i = 0;
5876
5877		for ( ; i <= last; i++ ) {
5878			elems = i === last ? this : this.clone( true );
5879			jQuery( insert[ i ] )[ original ]( elems );
5880
5881			// Support: QtWebKit
5882			// .get() because push.apply(_, arraylike) throws
5883			push.apply( ret, elems.get() );
5884		}
5885
5886		return this.pushStack( ret );
5887	};
5888} );
5889
5890
5891var iframe,
5892	elemdisplay = {
5893
5894		// Support: Firefox
5895		// We have to pre-define these values for FF (#10227)
5896		HTML: "block",
5897		BODY: "block"
5898	};
5899
5900/**
5901 * Retrieve the actual display of a element
5902 * @param {String} name nodeName of the element
5903 * @param {Object} doc Document object
5904 */
5905
5906// Called only from within defaultDisplay
5907function actualDisplay( name, doc ) {
5908	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5909
5910		display = jQuery.css( elem[ 0 ], "display" );
5911
5912	// We don't have any data stored on the element,
5913	// so use "detach" method as fast way to get rid of the element
5914	elem.detach();
5915
5916	return display;
5917}
5918
5919/**
5920 * Try to determine the default display value of an element
5921 * @param {String} nodeName
5922 */
5923function defaultDisplay( nodeName ) {
5924	var doc = document,
5925		display = elemdisplay[ nodeName ];
5926
5927	if ( !display ) {
5928		display = actualDisplay( nodeName, doc );
5929
5930		// If the simple way fails, read from inside an iframe
5931		if ( display === "none" || !display ) {
5932
5933			// Use the already-created iframe if possible
5934			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
5935				.appendTo( doc.documentElement );
5936
5937			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5938			doc = iframe[ 0 ].contentDocument;
5939
5940			// Support: IE
5941			doc.write();
5942			doc.close();
5943
5944			display = actualDisplay( nodeName, doc );
5945			iframe.detach();
5946		}
5947
5948		// Store the correct default display
5949		elemdisplay[ nodeName ] = display;
5950	}
5951
5952	return display;
5953}
5954var rmargin = ( /^margin/ );
5955
5956var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5957
5958var getStyles = function( elem ) {
5959
5960		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5961		// IE throws on elements created in popups
5962		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5963		var view = elem.ownerDocument.defaultView;
5964
5965		if ( !view || !view.opener ) {
5966			view = window;
5967		}
5968
5969		return view.getComputedStyle( elem );
5970	};
5971
5972var swap = function( elem, options, callback, args ) {
5973	var ret, name,
5974		old = {};
5975
5976	// Remember the old values, and insert the new ones
5977	for ( name in options ) {
5978		old[ name ] = elem.style[ name ];
5979		elem.style[ name ] = options[ name ];
5980	}
5981
5982	ret = callback.apply( elem, args || [] );
5983
5984	// Revert the old values
5985	for ( name in options ) {
5986		elem.style[ name ] = old[ name ];
5987	}
5988
5989	return ret;
5990};
5991
5992
5993var documentElement = document.documentElement;
5994
5995
5996
5997( function() {
5998	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
5999		container = document.createElement( "div" ),
6000		div = document.createElement( "div" );
6001
6002	// Finish early in limited (non-browser) environments
6003	if ( !div.style ) {
6004		return;
6005	}
6006
6007	// Support: IE9-11+
6008	// Style of cloned element affects source element cloned (#8908)
6009	div.style.backgroundClip = "content-box";
6010	div.cloneNode( true ).style.backgroundClip = "";
6011	support.clearCloneStyle = div.style.backgroundClip === "content-box";
6012
6013	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6014		"padding:0;margin-top:1px;position:absolute";
6015	container.appendChild( div );
6016
6017	// Executing both pixelPosition & boxSizingReliable tests require only one layout
6018	// so they're executed at the same time to save the second computation.
6019	function computeStyleTests() {
6020		div.style.cssText =
6021
6022			// Support: Firefox<29, Android 2.3
6023			// Vendor-prefix box-sizing
6024			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
6025			"position:relative;display:block;" +
6026			"margin:auto;border:1px;padding:1px;" +
6027			"top:1%;width:50%";
6028		div.innerHTML = "";
6029		documentElement.appendChild( container );
6030
6031		var divStyle = window.getComputedStyle( div );
6032		pixelPositionVal = divStyle.top !== "1%";
6033		reliableMarginLeftVal = divStyle.marginLeft === "2px";
6034		boxSizingReliableVal = divStyle.width === "4px";
6035
6036		// Support: Android 4.0 - 4.3 only
6037		// Some styles come back with percentage values, even though they shouldn't
6038		div.style.marginRight = "50%";
6039		pixelMarginRightVal = divStyle.marginRight === "4px";
6040
6041		documentElement.removeChild( container );
6042	}
6043
6044	jQuery.extend( support, {
6045		pixelPosition: function() {
6046
6047			// This test is executed only once but we still do memoizing
6048			// since we can use the boxSizingReliable pre-computing.
6049			// No need to check if the test was already performed, though.
6050			computeStyleTests();
6051			return pixelPositionVal;
6052		},
6053		boxSizingReliable: function() {
6054			if ( boxSizingReliableVal == null ) {
6055				computeStyleTests();
6056			}
6057			return boxSizingReliableVal;
6058		},
6059		pixelMarginRight: function() {
6060
6061			// Support: Android 4.0-4.3
6062			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
6063			// since that compresses better and they're computed together anyway.
6064			if ( boxSizingReliableVal == null ) {
6065				computeStyleTests();
6066			}
6067			return pixelMarginRightVal;
6068		},
6069		reliableMarginLeft: function() {
6070
6071			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6072			if ( boxSizingReliableVal == null ) {
6073				computeStyleTests();
6074			}
6075			return reliableMarginLeftVal;
6076		},
6077		reliableMarginRight: function() {
6078
6079			// Support: Android 2.3
6080			// Check if div with explicit width and no margin-right incorrectly
6081			// gets computed margin-right based on width of container. (#3333)
6082			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6083			// This support function is only executed once so no memoizing is needed.
6084			var ret,
6085				marginDiv = div.appendChild( document.createElement( "div" ) );
6086
6087			// Reset CSS: box-sizing; display; margin; border; padding
6088			marginDiv.style.cssText = div.style.cssText =
6089
6090				// Support: Android 2.3
6091				// Vendor-prefix box-sizing
6092				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
6093				"display:block;margin:0;border:0;padding:0";
6094			marginDiv.style.marginRight = marginDiv.style.width = "0";
6095			div.style.width = "1px";
6096			documentElement.appendChild( container );
6097
6098			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
6099
6100			documentElement.removeChild( container );
6101			div.removeChild( marginDiv );
6102
6103			return ret;
6104		}
6105	} );
6106} )();
6107
6108
6109function curCSS( elem, name, computed ) {
6110	var width, minWidth, maxWidth, ret,
6111		style = elem.style;
6112
6113	computed = computed || getStyles( elem );
6114	ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6115
6116	// Support: Opera 12.1x only
6117	// Fall back to style even without computed
6118	// computed is undefined for elems on document fragments
6119	if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
6120		ret = jQuery.style( elem, name );
6121	}
6122
6123	// Support: IE9
6124	// getPropertyValue is only needed for .css('filter') (#12537)
6125	if ( computed ) {
6126
6127		// A tribute to the "awesome hack by Dean Edwards"
6128		// Android Browser returns percentage for some values,
6129		// but width seems to be reliably pixels.
6130		// This is against the CSSOM draft spec:
6131		// http://dev.w3.org/csswg/cssom/#resolved-values
6132		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6133
6134			// Remember the original values
6135			width = style.width;
6136			minWidth = style.minWidth;
6137			maxWidth = style.maxWidth;
6138
6139			// Put in the new values to get a computed value out
6140			style.minWidth = style.maxWidth = style.width = ret;
6141			ret = computed.width;
6142
6143			// Revert the changed values
6144			style.width = width;
6145			style.minWidth = minWidth;
6146			style.maxWidth = maxWidth;
6147		}
6148	}
6149
6150	return ret !== undefined ?
6151
6152		// Support: IE9-11+
6153		// IE returns zIndex value as an integer.
6154		ret + "" :
6155		ret;
6156}
6157
6158
6159function addGetHookIf( conditionFn, hookFn ) {
6160
6161	// Define the hook, we'll check on the first run if it's really needed.
6162	return {
6163		get: function() {
6164			if ( conditionFn() ) {
6165
6166				// Hook not needed (or it's not possible to use it due
6167				// to missing dependency), remove it.
6168				delete this.get;
6169				return;
6170			}
6171
6172			// Hook needed; redefine it so that the support test is not executed again.
6173			return ( this.get = hookFn ).apply( this, arguments );
6174		}
6175	};
6176}
6177
6178
6179var
6180
6181	// Swappable if display is none or starts with table
6182	// except "table", "table-cell", or "table-caption"
6183	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6184	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6185
6186	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6187	cssNormalTransform = {
6188		letterSpacing: "0",
6189		fontWeight: "400"
6190	},
6191
6192	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6193	emptyStyle = document.createElement( "div" ).style;
6194
6195// Return a css property mapped to a potentially vendor prefixed property
6196function vendorPropName( name ) {
6197
6198	// Shortcut for names that are not vendor prefixed
6199	if ( name in emptyStyle ) {
6200		return name;
6201	}
6202
6203	// Check for vendor prefixed names
6204	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6205		i = cssPrefixes.length;
6206
6207	while ( i-- ) {
6208		name = cssPrefixes[ i ] + capName;
6209		if ( name in emptyStyle ) {
6210			return name;
6211		}
6212	}
6213}
6214
6215function setPositiveNumber( elem, value, subtract ) {
6216
6217	// Any relative (+/-) values have already been
6218	// normalized at this point
6219	var matches = rcssNum.exec( value );
6220	return matches ?
6221
6222		// Guard against undefined "subtract", e.g., when used as in cssHooks
6223		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6224		value;
6225}
6226
6227function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6228	var i = extra === ( isBorderBox ? "border" : "content" ) ?
6229
6230		// If we already have the right measurement, avoid augmentation
6231		4 :
6232
6233		// Otherwise initialize for horizontal or vertical properties
6234		name === "width" ? 1 : 0,
6235
6236		val = 0;
6237
6238	for ( ; i < 4; i += 2 ) {
6239
6240		// Both box models exclude margin, so add it if we want it
6241		if ( extra === "margin" ) {
6242			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6243		}
6244
6245		if ( isBorderBox ) {
6246
6247			// border-box includes padding, so remove it if we want content
6248			if ( extra === "content" ) {
6249				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6250			}
6251
6252			// At this point, extra isn't border nor margin, so remove border
6253			if ( extra !== "margin" ) {
6254				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6255			}
6256		} else {
6257
6258			// At this point, extra isn't content, so add padding
6259			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6260
6261			// At this point, extra isn't content nor padding, so add border
6262			if ( extra !== "padding" ) {
6263				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6264			}
6265		}
6266	}
6267
6268	return val;
6269}
6270
6271function getWidthOrHeight( elem, name, extra ) {
6272
6273	// Start with offset property, which is equivalent to the border-box value
6274	var valueIsBorderBox = true,
6275		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6276		styles = getStyles( elem ),
6277		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6278
6279	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
6280	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6281	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6282	if ( val <= 0 || val == null ) {
6283
6284		// Fall back to computed then uncomputed css if necessary
6285		val = curCSS( elem, name, styles );
6286		if ( val < 0 || val == null ) {
6287			val = elem.style[ name ];
6288		}
6289
6290		// Computed unit is not pixels. Stop here and return.
6291		if ( rnumnonpx.test( val ) ) {
6292			return val;
6293		}
6294
6295		// Check for style in case a browser which returns unreliable values
6296		// for getComputedStyle silently falls back to the reliable elem.style
6297		valueIsBorderBox = isBorderBox &&
6298			( support.boxSizingReliable() || val === elem.style[ name ] );
6299
6300		// Normalize "", auto, and prepare for extra
6301		val = parseFloat( val ) || 0;
6302	}
6303
6304	// Use the active box-sizing model to add/subtract irrelevant styles
6305	return ( val +
6306		augmentWidthOrHeight(
6307			elem,
6308			name,
6309			extra || ( isBorderBox ? "border" : "content" ),
6310			valueIsBorderBox,
6311			styles
6312		)
6313	) + "px";
6314}
6315
6316function showHide( elements, show ) {
6317	var display, elem, hidden,
6318		values = [],
6319		index = 0,
6320		length = elements.length;
6321
6322	for ( ; index < length; index++ ) {
6323		elem = elements[ index ];
6324		if ( !elem.style ) {
6325			continue;
6326		}
6327
6328		values[ index ] = dataPriv.get( elem, "olddisplay" );
6329		display = elem.style.display;
6330		if ( show ) {
6331
6332			// Reset the inline display of this element to learn if it is
6333			// being hidden by cascaded rules or not
6334			if ( !values[ index ] && display === "none" ) {
6335				elem.style.display = "";
6336			}
6337
6338			// Set elements which have been overridden with display: none
6339			// in a stylesheet to whatever the default browser style is
6340			// for such an element
6341			if ( elem.style.display === "" && isHidden( elem ) ) {
6342				values[ index ] = dataPriv.access(
6343					elem,
6344					"olddisplay",
6345					defaultDisplay( elem.nodeName )
6346				);
6347			}
6348		} else {
6349			hidden = isHidden( elem );
6350
6351			if ( display !== "none" || !hidden ) {
6352				dataPriv.set(
6353					elem,
6354					"olddisplay",
6355					hidden ? display : jQuery.css( elem, "display" )
6356				);
6357			}
6358		}
6359	}
6360
6361	// Set the display of most of the elements in a second loop
6362	// to avoid the constant reflow
6363	for ( index = 0; index < length; index++ ) {
6364		elem = elements[ index ];
6365		if ( !elem.style ) {
6366			continue;
6367		}
6368		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6369			elem.style.display = show ? values[ index ] || "" : "none";
6370		}
6371	}
6372
6373	return elements;
6374}
6375
6376jQuery.extend( {
6377
6378	// Add in style property hooks for overriding the default
6379	// behavior of getting and setting a style property
6380	cssHooks: {
6381		opacity: {
6382			get: function( elem, computed ) {
6383				if ( computed ) {
6384
6385					// We should always get a number back from opacity
6386					var ret = curCSS( elem, "opacity" );
6387					return ret === "" ? "1" : ret;
6388				}
6389			}
6390		}
6391	},
6392
6393	// Don't automatically add "px" to these possibly-unitless properties
6394	cssNumber: {
6395		"animationIterationCount": true,
6396		"columnCount": true,
6397		"fillOpacity": true,
6398		"flexGrow": true,
6399		"flexShrink": true,
6400		"fontWeight": true,
6401		"lineHeight": true,
6402		"opacity": true,
6403		"order": true,
6404		"orphans": true,
6405		"widows": true,
6406		"zIndex": true,
6407		"zoom": true
6408	},
6409
6410	// Add in properties whose names you wish to fix before
6411	// setting or getting the value
6412	cssProps: {
6413		"float": "cssFloat"
6414	},
6415
6416	// Get and set the style property on a DOM Node
6417	style: function( elem, name, value, extra ) {
6418
6419		// Don't set styles on text and comment nodes
6420		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6421			return;
6422		}
6423
6424		// Make sure that we're working with the right name
6425		var ret, type, hooks,
6426			origName = jQuery.camelCase( name ),
6427			style = elem.style;
6428
6429		name = jQuery.cssProps[ origName ] ||
6430			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6431
6432		// Gets hook for the prefixed version, then unprefixed version
6433		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6434
6435		// Check if we're setting a value
6436		if ( value !== undefined ) {
6437			type = typeof value;
6438
6439			// Convert "+=" or "-=" to relative numbers (#7345)
6440			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6441				value = adjustCSS( elem, name, ret );
6442
6443				// Fixes bug #9237
6444				type = "number";
6445			}
6446
6447			// Make sure that null and NaN values aren't set (#7116)
6448			if ( value == null || value !== value ) {
6449				return;
6450			}
6451
6452			// If a number was passed in, add the unit (except for certain CSS properties)
6453			if ( type === "number" ) {
6454				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6455			}
6456
6457			// Support: IE9-11+
6458			// background-* props affect original clone's values
6459			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6460				style[ name ] = "inherit";
6461			}
6462
6463			// If a hook was provided, use that value, otherwise just set the specified value
6464			if ( !hooks || !( "set" in hooks ) ||
6465				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6466
6467				style[ name ] = value;
6468			}
6469
6470		} else {
6471
6472			// If a hook was provided get the non-computed value from there
6473			if ( hooks && "get" in hooks &&
6474				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6475
6476				return ret;
6477			}
6478
6479			// Otherwise just get the value from the style object
6480			return style[ name ];
6481		}
6482	},
6483
6484	css: function( elem, name, extra, styles ) {
6485		var val, num, hooks,
6486			origName = jQuery.camelCase( name );
6487
6488		// Make sure that we're working with the right name
6489		name = jQuery.cssProps[ origName ] ||
6490			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6491
6492		// Try prefixed name followed by the unprefixed name
6493		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6494
6495		// If a hook was provided get the computed value from there
6496		if ( hooks && "get" in hooks ) {
6497			val = hooks.get( elem, true, extra );
6498		}
6499
6500		// Otherwise, if a way to get the computed value exists, use that
6501		if ( val === undefined ) {
6502			val = curCSS( elem, name, styles );
6503		}
6504
6505		// Convert "normal" to computed value
6506		if ( val === "normal" && name in cssNormalTransform ) {
6507			val = cssNormalTransform[ name ];
6508		}
6509
6510		// Make numeric if forced or a qualifier was provided and val looks numeric
6511		if ( extra === "" || extra ) {
6512			num = parseFloat( val );
6513			return extra === true || isFinite( num ) ? num || 0 : val;
6514		}
6515		return val;
6516	}
6517} );
6518
6519jQuery.each( [ "height", "width" ], function( i, name ) {
6520	jQuery.cssHooks[ name ] = {
6521		get: function( elem, computed, extra ) {
6522			if ( computed ) {
6523
6524				// Certain elements can have dimension info if we invisibly show them
6525				// but it must have a current display style that would benefit
6526				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6527					elem.offsetWidth === 0 ?
6528						swap( elem, cssShow, function() {
6529							return getWidthOrHeight( elem, name, extra );
6530						} ) :
6531						getWidthOrHeight( elem, name, extra );
6532			}
6533		},
6534
6535		set: function( elem, value, extra ) {
6536			var matches,
6537				styles = extra && getStyles( elem ),
6538				subtract = extra && augmentWidthOrHeight(
6539					elem,
6540					name,
6541					extra,
6542					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6543					styles
6544				);
6545
6546			// Convert to pixels if value adjustment is needed
6547			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6548				( matches[ 3 ] || "px" ) !== "px" ) {
6549
6550				elem.style[ name ] = value;
6551				value = jQuery.css( elem, name );
6552			}
6553
6554			return setPositiveNumber( elem, value, subtract );
6555		}
6556	};
6557} );
6558
6559jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6560	function( elem, computed ) {
6561		if ( computed ) {
6562			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6563				elem.getBoundingClientRect().left -
6564					swap( elem, { marginLeft: 0 }, function() {
6565						return elem.getBoundingClientRect().left;
6566					} )
6567				) + "px";
6568		}
6569	}
6570);
6571
6572// Support: Android 2.3
6573jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6574	function( elem, computed ) {
6575		if ( computed ) {
6576			return swap( elem, { "display": "inline-block" },
6577				curCSS, [ elem, "marginRight" ] );
6578		}
6579	}
6580);
6581
6582// These hooks are used by animate to expand properties
6583jQuery.each( {
6584	margin: "",
6585	padding: "",
6586	border: "Width"
6587}, function( prefix, suffix ) {
6588	jQuery.cssHooks[ prefix + suffix ] = {
6589		expand: function( value ) {
6590			var i = 0,
6591				expanded = {},
6592
6593				// Assumes a single number if not a string
6594				parts = typeof value === "string" ? value.split( " " ) : [ value ];
6595
6596			for ( ; i < 4; i++ ) {
6597				expanded[ prefix + cssExpand[ i ] + suffix ] =
6598					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6599			}
6600
6601			return expanded;
6602		}
6603	};
6604
6605	if ( !rmargin.test( prefix ) ) {
6606		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6607	}
6608} );
6609
6610jQuery.fn.extend( {
6611	css: function( name, value ) {
6612		return access( this, function( elem, name, value ) {
6613			var styles, len,
6614				map = {},
6615				i = 0;
6616
6617			if ( jQuery.isArray( name ) ) {
6618				styles = getStyles( elem );
6619				len = name.length;
6620
6621				for ( ; i < len; i++ ) {
6622					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6623				}
6624
6625				return map;
6626			}
6627
6628			return value !== undefined ?
6629				jQuery.style( elem, name, value ) :
6630				jQuery.css( elem, name );
6631		}, name, value, arguments.length > 1 );
6632	},
6633	show: function() {
6634		return showHide( this, true );
6635	},
6636	hide: function() {
6637		return showHide( this );
6638	},
6639	toggle: function( state ) {
6640		if ( typeof state === "boolean" ) {
6641			return state ? this.show() : this.hide();
6642		}
6643
6644		return this.each( function() {
6645			if ( isHidden( this ) ) {
6646				jQuery( this ).show();
6647			} else {
6648				jQuery( this ).hide();
6649			}
6650		} );
6651	}
6652} );
6653
6654
6655function Tween( elem, options, prop, end, easing ) {
6656	return new Tween.prototype.init( elem, options, prop, end, easing );
6657}
6658jQuery.Tween = Tween;
6659
6660Tween.prototype = {
6661	constructor: Tween,
6662	init: function( elem, options, prop, end, easing, unit ) {
6663		this.elem = elem;
6664		this.prop = prop;
6665		this.easing = easing || jQuery.easing._default;
6666		this.options = options;
6667		this.start = this.now = this.cur();
6668		this.end = end;
6669		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6670	},
6671	cur: function() {
6672		var hooks = Tween.propHooks[ this.prop ];
6673
6674		return hooks && hooks.get ?
6675			hooks.get( this ) :
6676			Tween.propHooks._default.get( this );
6677	},
6678	run: function( percent ) {
6679		var eased,
6680			hooks = Tween.propHooks[ this.prop ];
6681
6682		if ( this.options.duration ) {
6683			this.pos = eased = jQuery.easing[ this.easing ](
6684				percent, this.options.duration * percent, 0, 1, this.options.duration
6685			);
6686		} else {
6687			this.pos = eased = percent;
6688		}
6689		this.now = ( this.end - this.start ) * eased + this.start;
6690
6691		if ( this.options.step ) {
6692			this.options.step.call( this.elem, this.now, this );
6693		}
6694
6695		if ( hooks && hooks.set ) {
6696			hooks.set( this );
6697		} else {
6698			Tween.propHooks._default.set( this );
6699		}
6700		return this;
6701	}
6702};
6703
6704Tween.prototype.init.prototype = Tween.prototype;
6705
6706Tween.propHooks = {
6707	_default: {
6708		get: function( tween ) {
6709			var result;
6710
6711			// Use a property on the element directly when it is not a DOM element,
6712			// or when there is no matching style property that exists.
6713			if ( tween.elem.nodeType !== 1 ||
6714				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6715				return tween.elem[ tween.prop ];
6716			}
6717
6718			// Passing an empty string as a 3rd parameter to .css will automatically
6719			// attempt a parseFloat and fallback to a string if the parse fails.
6720			// Simple values such as "10px" are parsed to Float;
6721			// complex values such as "rotate(1rad)" are returned as-is.
6722			result = jQuery.css( tween.elem, tween.prop, "" );
6723
6724			// Empty strings, null, undefined and "auto" are converted to 0.
6725			return !result || result === "auto" ? 0 : result;
6726		},
6727		set: function( tween ) {
6728
6729			// Use step hook for back compat.
6730			// Use cssHook if its there.
6731			// Use .style if available and use plain properties where available.
6732			if ( jQuery.fx.step[ tween.prop ] ) {
6733				jQuery.fx.step[ tween.prop ]( tween );
6734			} else if ( tween.elem.nodeType === 1 &&
6735				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6736					jQuery.cssHooks[ tween.prop ] ) ) {
6737				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6738			} else {
6739				tween.elem[ tween.prop ] = tween.now;
6740			}
6741		}
6742	}
6743};
6744
6745// Support: IE9
6746// Panic based approach to setting things on disconnected nodes
6747Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6748	set: function( tween ) {
6749		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6750			tween.elem[ tween.prop ] = tween.now;
6751		}
6752	}
6753};
6754
6755jQuery.easing = {
6756	linear: function( p ) {
6757		return p;
6758	},
6759	swing: function( p ) {
6760		return 0.5 - Math.cos( p * Math.PI ) / 2;
6761	},
6762	_default: "swing"
6763};
6764
6765jQuery.fx = Tween.prototype.init;
6766
6767// Back Compat <1.8 extension point
6768jQuery.fx.step = {};
6769
6770
6771
6772
6773var
6774	fxNow, timerId,
6775	rfxtypes = /^(?:toggle|show|hide)$/,
6776	rrun = /queueHooks$/;
6777
6778// Animations created synchronously will run synchronously
6779function createFxNow() {
6780	window.setTimeout( function() {
6781		fxNow = undefined;
6782	} );
6783	return ( fxNow = jQuery.now() );
6784}
6785
6786// Generate parameters to create a standard animation
6787function genFx( type, includeWidth ) {
6788	var which,
6789		i = 0,
6790		attrs = { height: type };
6791
6792	// If we include width, step value is 1 to do all cssExpand values,
6793	// otherwise step value is 2 to skip over Left and Right
6794	includeWidth = includeWidth ? 1 : 0;
6795	for ( ; i < 4 ; i += 2 - includeWidth ) {
6796		which = cssExpand[ i ];
6797		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6798	}
6799
6800	if ( includeWidth ) {
6801		attrs.opacity = attrs.width = type;
6802	}
6803
6804	return attrs;
6805}
6806
6807function createTween( value, prop, animation ) {
6808	var tween,
6809		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6810		index = 0,
6811		length = collection.length;
6812	for ( ; index < length; index++ ) {
6813		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6814
6815			// We're done with this property
6816			return tween;
6817		}
6818	}
6819}
6820
6821function defaultPrefilter( elem, props, opts ) {
6822	/* jshint validthis: true */
6823	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6824		anim = this,
6825		orig = {},
6826		style = elem.style,
6827		hidden = elem.nodeType && isHidden( elem ),
6828		dataShow = dataPriv.get( elem, "fxshow" );
6829
6830	// Handle queue: false promises
6831	if ( !opts.queue ) {
6832		hooks = jQuery._queueHooks( elem, "fx" );
6833		if ( hooks.unqueued == null ) {
6834			hooks.unqueued = 0;
6835			oldfire = hooks.empty.fire;
6836			hooks.empty.fire = function() {
6837				if ( !hooks.unqueued ) {
6838					oldfire();
6839				}
6840			};
6841		}
6842		hooks.unqueued++;
6843
6844		anim.always( function() {
6845
6846			// Ensure the complete handler is called before this completes
6847			anim.always( function() {
6848				hooks.unqueued--;
6849				if ( !jQuery.queue( elem, "fx" ).length ) {
6850					hooks.empty.fire();
6851				}
6852			} );
6853		} );
6854	}
6855
6856	// Height/width overflow pass
6857	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6858
6859		// Make sure that nothing sneaks out
6860		// Record all 3 overflow attributes because IE9-10 do not
6861		// change the overflow attribute when overflowX and
6862		// overflowY are set to the same value
6863		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6864
6865		// Set display property to inline-block for height/width
6866		// animations on inline elements that are having width/height animated
6867		display = jQuery.css( elem, "display" );
6868
6869		// Test default display if display is currently "none"
6870		checkDisplay = display === "none" ?
6871			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6872
6873		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6874			style.display = "inline-block";
6875		}
6876	}
6877
6878	if ( opts.overflow ) {
6879		style.overflow = "hidden";
6880		anim.always( function() {
6881			style.overflow = opts.overflow[ 0 ];
6882			style.overflowX = opts.overflow[ 1 ];
6883			style.overflowY = opts.overflow[ 2 ];
6884		} );
6885	}
6886
6887	// show/hide pass
6888	for ( prop in props ) {
6889		value = props[ prop ];
6890		if ( rfxtypes.exec( value ) ) {
6891			delete props[ prop ];
6892			toggle = toggle || value === "toggle";
6893			if ( value === ( hidden ? "hide" : "show" ) ) {
6894
6895				// If there is dataShow left over from a stopped hide or show
6896				// and we are going to proceed with show, we should pretend to be hidden
6897				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6898					hidden = true;
6899				} else {
6900					continue;
6901				}
6902			}
6903			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6904
6905		// Any non-fx value stops us from restoring the original display value
6906		} else {
6907			display = undefined;
6908		}
6909	}
6910
6911	if ( !jQuery.isEmptyObject( orig ) ) {
6912		if ( dataShow ) {
6913			if ( "hidden" in dataShow ) {
6914				hidden = dataShow.hidden;
6915			}
6916		} else {
6917			dataShow = dataPriv.access( elem, "fxshow", {} );
6918		}
6919
6920		// Store state if its toggle - enables .stop().toggle() to "reverse"
6921		if ( toggle ) {
6922			dataShow.hidden = !hidden;
6923		}
6924		if ( hidden ) {
6925			jQuery( elem ).show();
6926		} else {
6927			anim.done( function() {
6928				jQuery( elem ).hide();
6929			} );
6930		}
6931		anim.done( function() {
6932			var prop;
6933
6934			dataPriv.remove( elem, "fxshow" );
6935			for ( prop in orig ) {
6936				jQuery.style( elem, prop, orig[ prop ] );
6937			}
6938		} );
6939		for ( prop in orig ) {
6940			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6941
6942			if ( !( prop in dataShow ) ) {
6943				dataShow[ prop ] = tween.start;
6944				if ( hidden ) {
6945					tween.end = tween.start;
6946					tween.start = prop === "width" || prop === "height" ? 1 : 0;
6947				}
6948			}
6949		}
6950
6951	// If this is a noop like .hide().hide(), restore an overwritten display value
6952	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
6953		style.display = display;
6954	}
6955}
6956
6957function propFilter( props, specialEasing ) {
6958	var index, name, easing, value, hooks;
6959
6960	// camelCase, specialEasing and expand cssHook pass
6961	for ( index in props ) {
6962		name = jQuery.camelCase( index );
6963		easing = specialEasing[ name ];
6964		value = props[ index ];
6965		if ( jQuery.isArray( value ) ) {
6966			easing = value[ 1 ];
6967			value = props[ index ] = value[ 0 ];
6968		}
6969
6970		if ( index !== name ) {
6971			props[ name ] = value;
6972			delete props[ index ];
6973		}
6974
6975		hooks = jQuery.cssHooks[ name ];
6976		if ( hooks && "expand" in hooks ) {
6977			value = hooks.expand( value );
6978			delete props[ name ];
6979
6980			// Not quite $.extend, this won't overwrite existing keys.
6981			// Reusing 'index' because we have the correct "name"
6982			for ( index in value ) {
6983				if ( !( index in props ) ) {
6984					props[ index ] = value[ index ];
6985					specialEasing[ index ] = easing;
6986				}
6987			}
6988		} else {
6989			specialEasing[ name ] = easing;
6990		}
6991	}
6992}
6993
6994function Animation( elem, properties, options ) {
6995	var result,
6996		stopped,
6997		index = 0,
6998		length = Animation.prefilters.length,
6999		deferred = jQuery.Deferred().always( function() {
7000
7001			// Don't match elem in the :animated selector
7002			delete tick.elem;
7003		} ),
7004		tick = function() {
7005			if ( stopped ) {
7006				return false;
7007			}
7008			var currentTime = fxNow || createFxNow(),
7009				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7010
7011				// Support: Android 2.3
7012				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7013				temp = remaining / animation.duration || 0,
7014				percent = 1 - temp,
7015				index = 0,
7016				length = animation.tweens.length;
7017
7018			for ( ; index < length ; index++ ) {
7019				animation.tweens[ index ].run( percent );
7020			}
7021
7022			deferred.notifyWith( elem, [ animation, percent, remaining ] );
7023
7024			if ( percent < 1 && length ) {
7025				return remaining;
7026			} else {
7027				deferred.resolveWith( elem, [ animation ] );
7028				return false;
7029			}
7030		},
7031		animation = deferred.promise( {
7032			elem: elem,
7033			props: jQuery.extend( {}, properties ),
7034			opts: jQuery.extend( true, {
7035				specialEasing: {},
7036				easing: jQuery.easing._default
7037			}, options ),
7038			originalProperties: properties,
7039			originalOptions: options,
7040			startTime: fxNow || createFxNow(),
7041			duration: options.duration,
7042			tweens: [],
7043			createTween: function( prop, end ) {
7044				var tween = jQuery.Tween( elem, animation.opts, prop, end,
7045						animation.opts.specialEasing[ prop ] || animation.opts.easing );
7046				animation.tweens.push( tween );
7047				return tween;
7048			},
7049			stop: function( gotoEnd ) {
7050				var index = 0,
7051
7052					// If we are going to the end, we want to run all the tweens
7053					// otherwise we skip this part
7054					length = gotoEnd ? animation.tweens.length : 0;
7055				if ( stopped ) {
7056					return this;
7057				}
7058				stopped = true;
7059				for ( ; index < length ; index++ ) {
7060					animation.tweens[ index ].run( 1 );
7061				}
7062
7063				// Resolve when we played the last frame; otherwise, reject
7064				if ( gotoEnd ) {
7065					deferred.notifyWith( elem, [ animation, 1, 0 ] );
7066					deferred.resolveWith( elem, [ animation, gotoEnd ] );
7067				} else {
7068					deferred.rejectWith( elem, [ animation, gotoEnd ] );
7069				}
7070				return this;
7071			}
7072		} ),
7073		props = animation.props;
7074
7075	propFilter( props, animation.opts.specialEasing );
7076
7077	for ( ; index < length ; index++ ) {
7078		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7079		if ( result ) {
7080			if ( jQuery.isFunction( result.stop ) ) {
7081				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7082					jQuery.proxy( result.stop, result );
7083			}
7084			return result;
7085		}
7086	}
7087
7088	jQuery.map( props, createTween, animation );
7089
7090	if ( jQuery.isFunction( animation.opts.start ) ) {
7091		animation.opts.start.call( elem, animation );
7092	}
7093
7094	jQuery.fx.timer(
7095		jQuery.extend( tick, {
7096			elem: elem,
7097			anim: animation,
7098			queue: animation.opts.queue
7099		} )
7100	);
7101
7102	// attach callbacks from options
7103	return animation.progress( animation.opts.progress )
7104		.done( animation.opts.done, animation.opts.complete )
7105		.fail( animation.opts.fail )
7106		.always( animation.opts.always );
7107}
7108
7109jQuery.Animation = jQuery.extend( Animation, {
7110	tweeners: {
7111		"*": [ function( prop, value ) {
7112			var tween = this.createTween( prop, value );
7113			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7114			return tween;
7115		} ]
7116	},
7117
7118	tweener: function( props, callback ) {
7119		if ( jQuery.isFunction( props ) ) {
7120			callback = props;
7121			props = [ "*" ];
7122		} else {
7123			props = props.match( rnotwhite );
7124		}
7125
7126		var prop,
7127			index = 0,
7128			length = props.length;
7129
7130		for ( ; index < length ; index++ ) {
7131			prop = props[ index ];
7132			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7133			Animation.tweeners[ prop ].unshift( callback );
7134		}
7135	},
7136
7137	prefilters: [ defaultPrefilter ],
7138
7139	prefilter: function( callback, prepend ) {
7140		if ( prepend ) {
7141			Animation.prefilters.unshift( callback );
7142		} else {
7143			Animation.prefilters.push( callback );
7144		}
7145	}
7146} );
7147
7148jQuery.speed = function( speed, easing, fn ) {
7149	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7150		complete: fn || !fn && easing ||
7151			jQuery.isFunction( speed ) && speed,
7152		duration: speed,
7153		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7154	};
7155
7156	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
7157		opt.duration : opt.duration in jQuery.fx.speeds ?
7158			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7159
7160	// Normalize opt.queue - true/undefined/null -> "fx"
7161	if ( opt.queue == null || opt.queue === true ) {
7162		opt.queue = "fx";
7163	}
7164
7165	// Queueing
7166	opt.old = opt.complete;
7167
7168	opt.complete = function() {
7169		if ( jQuery.isFunction( opt.old ) ) {
7170			opt.old.call( this );
7171		}
7172
7173		if ( opt.queue ) {
7174			jQuery.dequeue( this, opt.queue );
7175		}
7176	};
7177
7178	return opt;
7179};
7180
7181jQuery.fn.extend( {
7182	fadeTo: function( speed, to, easing, callback ) {
7183
7184		// Show any hidden elements after setting opacity to 0
7185		return this.filter( isHidden ).css( "opacity", 0 ).show()
7186
7187			// Animate to the value specified
7188			.end().animate( { opacity: to }, speed, easing, callback );
7189	},
7190	animate: function( prop, speed, easing, callback ) {
7191		var empty = jQuery.isEmptyObject( prop ),
7192			optall = jQuery.speed( speed, easing, callback ),
7193			doAnimation = function() {
7194
7195				// Operate on a copy of prop so per-property easing won't be lost
7196				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7197
7198				// Empty animations, or finishing resolves immediately
7199				if ( empty || dataPriv.get( this, "finish" ) ) {
7200					anim.stop( true );
7201				}
7202			};
7203			doAnimation.finish = doAnimation;
7204
7205		return empty || optall.queue === false ?
7206			this.each( doAnimation ) :
7207			this.queue( optall.queue, doAnimation );
7208	},
7209	stop: function( type, clearQueue, gotoEnd ) {
7210		var stopQueue = function( hooks ) {
7211			var stop = hooks.stop;
7212			delete hooks.stop;
7213			stop( gotoEnd );
7214		};
7215
7216		if ( typeof type !== "string" ) {
7217			gotoEnd = clearQueue;
7218			clearQueue = type;
7219			type = undefined;
7220		}
7221		if ( clearQueue && type !== false ) {
7222			this.queue( type || "fx", [] );
7223		}
7224
7225		return this.each( function() {
7226			var dequeue = true,
7227				index = type != null && type + "queueHooks",
7228				timers = jQuery.timers,
7229				data = dataPriv.get( this );
7230
7231			if ( index ) {
7232				if ( data[ index ] && data[ index ].stop ) {
7233					stopQueue( data[ index ] );
7234				}
7235			} else {
7236				for ( index in data ) {
7237					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7238						stopQueue( data[ index ] );
7239					}
7240				}
7241			}
7242
7243			for ( index = timers.length; index--; ) {
7244				if ( timers[ index ].elem === this &&
7245					( type == null || timers[ index ].queue === type ) ) {
7246
7247					timers[ index ].anim.stop( gotoEnd );
7248					dequeue = false;
7249					timers.splice( index, 1 );
7250				}
7251			}
7252
7253			// Start the next in the queue if the last step wasn't forced.
7254			// Timers currently will call their complete callbacks, which
7255			// will dequeue but only if they were gotoEnd.
7256			if ( dequeue || !gotoEnd ) {
7257				jQuery.dequeue( this, type );
7258			}
7259		} );
7260	},
7261	finish: function( type ) {
7262		if ( type !== false ) {
7263			type = type || "fx";
7264		}
7265		return this.each( function() {
7266			var index,
7267				data = dataPriv.get( this ),
7268				queue = data[ type + "queue" ],
7269				hooks = data[ type + "queueHooks" ],
7270				timers = jQuery.timers,
7271				length = queue ? queue.length : 0;
7272
7273			// Enable finishing flag on private data
7274			data.finish = true;
7275
7276			// Empty the queue first
7277			jQuery.queue( this, type, [] );
7278
7279			if ( hooks && hooks.stop ) {
7280				hooks.stop.call( this, true );
7281			}
7282
7283			// Look for any active animations, and finish them
7284			for ( index = timers.length; index--; ) {
7285				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7286					timers[ index ].anim.stop( true );
7287					timers.splice( index, 1 );
7288				}
7289			}
7290
7291			// Look for any animations in the old queue and finish them
7292			for ( index = 0; index < length; index++ ) {
7293				if ( queue[ index ] && queue[ index ].finish ) {
7294					queue[ index ].finish.call( this );
7295				}
7296			}
7297
7298			// Turn off finishing flag
7299			delete data.finish;
7300		} );
7301	}
7302} );
7303
7304jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
7305	var cssFn = jQuery.fn[ name ];
7306	jQuery.fn[ name ] = function( speed, easing, callback ) {
7307		return speed == null || typeof speed === "boolean" ?
7308			cssFn.apply( this, arguments ) :
7309			this.animate( genFx( name, true ), speed, easing, callback );
7310	};
7311} );
7312
7313// Generate shortcuts for custom animations
7314jQuery.each( {
7315	slideDown: genFx( "show" ),
7316	slideUp: genFx( "hide" ),
7317	slideToggle: genFx( "toggle" ),
7318	fadeIn: { opacity: "show" },
7319	fadeOut: { opacity: "hide" },
7320	fadeToggle: { opacity: "toggle" }
7321}, function( name, props ) {
7322	jQuery.fn[ name ] = function( speed, easing, callback ) {
7323		return this.animate( props, speed, easing, callback );
7324	};
7325} );
7326
7327jQuery.timers = [];
7328jQuery.fx.tick = function() {
7329	var timer,
7330		i = 0,
7331		timers = jQuery.timers;
7332
7333	fxNow = jQuery.now();
7334
7335	for ( ; i < timers.length; i++ ) {
7336		timer = timers[ i ];
7337
7338		// Checks the timer has not already been removed
7339		if ( !timer() && timers[ i ] === timer ) {
7340			timers.splice( i--, 1 );
7341		}
7342	}
7343
7344	if ( !timers.length ) {
7345		jQuery.fx.stop();
7346	}
7347	fxNow = undefined;
7348};
7349
7350jQuery.fx.timer = function( timer ) {
7351	jQuery.timers.push( timer );
7352	if ( timer() ) {
7353		jQuery.fx.start();
7354	} else {
7355		jQuery.timers.pop();
7356	}
7357};
7358
7359jQuery.fx.interval = 13;
7360jQuery.fx.start = function() {
7361	if ( !timerId ) {
7362		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
7363	}
7364};
7365
7366jQuery.fx.stop = function() {
7367	window.clearInterval( timerId );
7368
7369	timerId = null;
7370};
7371
7372jQuery.fx.speeds = {
7373	slow: 600,
7374	fast: 200,
7375
7376	// Default speed
7377	_default: 400
7378};
7379
7380
7381// Based off of the plugin by Clint Helfers, with permission.
7382// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7383jQuery.fn.delay = function( time, type ) {
7384	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7385	type = type || "fx";
7386
7387	return this.queue( type, function( next, hooks ) {
7388		var timeout = window.setTimeout( next, time );
7389		hooks.stop = function() {
7390			window.clearTimeout( timeout );
7391		};
7392	} );
7393};
7394
7395
7396( function() {
7397	var input = document.createElement( "input" ),
7398		select = document.createElement( "select" ),
7399		opt = select.appendChild( document.createElement( "option" ) );
7400
7401	input.type = "checkbox";
7402
7403	// Support: iOS<=5.1, Android<=4.2+
7404	// Default value for a checkbox should be "on"
7405	support.checkOn = input.value !== "";
7406
7407	// Support: IE<=11+
7408	// Must access selectedIndex to make default options select
7409	support.optSelected = opt.selected;
7410
7411	// Support: Android<=2.3
7412	// Options inside disabled selects are incorrectly marked as disabled
7413	select.disabled = true;
7414	support.optDisabled = !opt.disabled;
7415
7416	// Support: IE<=11+
7417	// An input loses its value after becoming a radio
7418	input = document.createElement( "input" );
7419	input.value = "t";
7420	input.type = "radio";
7421	support.radioValue = input.value === "t";
7422} )();
7423
7424
7425var boolHook,
7426	attrHandle = jQuery.expr.attrHandle;
7427
7428jQuery.fn.extend( {
7429	attr: function( name, value ) {
7430		return access( this, jQuery.attr, name, value, arguments.length > 1 );
7431	},
7432
7433	removeAttr: function( name ) {
7434		return this.each( function() {
7435			jQuery.removeAttr( this, name );
7436		} );
7437	}
7438} );
7439
7440jQuery.extend( {
7441	attr: function( elem, name, value ) {
7442		var ret, hooks,
7443			nType = elem.nodeType;
7444
7445		// Don't get/set attributes on text, comment and attribute nodes
7446		if ( nType === 3 || nType === 8 || nType === 2 ) {
7447			return;
7448		}
7449
7450		// Fallback to prop when attributes are not supported
7451		if ( typeof elem.getAttribute === "undefined" ) {
7452			return jQuery.prop( elem, name, value );
7453		}
7454
7455		// All attributes are lowercase
7456		// Grab necessary hook if one is defined
7457		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7458			name = name.toLowerCase();
7459			hooks = jQuery.attrHooks[ name ] ||
7460				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7461		}
7462
7463		if ( value !== undefined ) {
7464			if ( value === null ) {
7465				jQuery.removeAttr( elem, name );
7466				return;
7467			}
7468
7469			if ( hooks && "set" in hooks &&
7470				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7471				return ret;
7472			}
7473
7474			elem.setAttribute( name, value + "" );
7475			return value;
7476		}
7477
7478		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7479			return ret;
7480		}
7481
7482		ret = jQuery.find.attr( elem, name );
7483
7484		// Non-existent attributes return null, we normalize to undefined
7485		return ret == null ? undefined : ret;
7486	},
7487
7488	attrHooks: {
7489		type: {
7490			set: function( elem, value ) {
7491				if ( !support.radioValue && value === "radio" &&
7492					jQuery.nodeName( elem, "input" ) ) {
7493					var val = elem.value;
7494					elem.setAttribute( "type", value );
7495					if ( val ) {
7496						elem.value = val;
7497					}
7498					return value;
7499				}
7500			}
7501		}
7502	},
7503
7504	removeAttr: function( elem, value ) {
7505		var name, propName,
7506			i = 0,
7507			attrNames = value && value.match( rnotwhite );
7508
7509		if ( attrNames && elem.nodeType === 1 ) {
7510			while ( ( name = attrNames[ i++ ] ) ) {
7511				propName = jQuery.propFix[ name ] || name;
7512
7513				// Boolean attributes get special treatment (#10870)
7514				if ( jQuery.expr.match.bool.test( name ) ) {
7515
7516					// Set corresponding property to false
7517					elem[ propName ] = false;
7518				}
7519
7520				elem.removeAttribute( name );
7521			}
7522		}
7523	}
7524} );
7525
7526// Hooks for boolean attributes
7527boolHook = {
7528	set: function( elem, value, name ) {
7529		if ( value === false ) {
7530
7531			// Remove boolean attributes when set to false
7532			jQuery.removeAttr( elem, name );
7533		} else {
7534			elem.setAttribute( name, name );
7535		}
7536		return name;
7537	}
7538};
7539jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7540	var getter = attrHandle[ name ] || jQuery.find.attr;
7541
7542	attrHandle[ name ] = function( elem, name, isXML ) {
7543		var ret, handle;
7544		if ( !isXML ) {
7545
7546			// Avoid an infinite loop by temporarily removing this function from the getter
7547			handle = attrHandle[ name ];
7548			attrHandle[ name ] = ret;
7549			ret = getter( elem, name, isXML ) != null ?
7550				name.toLowerCase() :
7551				null;
7552			attrHandle[ name ] = handle;
7553		}
7554		return ret;
7555	};
7556} );
7557
7558
7559
7560
7561var rfocusable = /^(?:input|select|textarea|button)$/i,
7562	rclickable = /^(?:a|area)$/i;
7563
7564jQuery.fn.extend( {
7565	prop: function( name, value ) {
7566		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7567	},
7568
7569	removeProp: function( name ) {
7570		return this.each( function() {
7571			delete this[ jQuery.propFix[ name ] || name ];
7572		} );
7573	}
7574} );
7575
7576jQuery.extend( {
7577	prop: function( elem, name, value ) {
7578		var ret, hooks,
7579			nType = elem.nodeType;
7580
7581		// Don't get/set properties on text, comment and attribute nodes
7582		if ( nType === 3 || nType === 8 || nType === 2 ) {
7583			return;
7584		}
7585
7586		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7587
7588			// Fix name and attach hooks
7589			name = jQuery.propFix[ name ] || name;
7590			hooks = jQuery.propHooks[ name ];
7591		}
7592
7593		if ( value !== undefined ) {
7594			if ( hooks && "set" in hooks &&
7595				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7596				return ret;
7597			}
7598
7599			return ( elem[ name ] = value );
7600		}
7601
7602		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7603			return ret;
7604		}
7605
7606		return elem[ name ];
7607	},
7608
7609	propHooks: {
7610		tabIndex: {
7611			get: function( elem ) {
7612
7613				// elem.tabIndex doesn't always return the
7614				// correct value when it hasn't been explicitly set
7615				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7616				// Use proper attribute retrieval(#12072)
7617				var tabindex = jQuery.find.attr( elem, "tabindex" );
7618
7619				return tabindex ?
7620					parseInt( tabindex, 10 ) :
7621					rfocusable.test( elem.nodeName ) ||
7622						rclickable.test( elem.nodeName ) && elem.href ?
7623							0 :
7624							-1;
7625			}
7626		}
7627	},
7628
7629	propFix: {
7630		"for": "htmlFor",
7631		"class": "className"
7632	}
7633} );
7634
7635// Support: IE <=11 only
7636// Accessing the selectedIndex property
7637// forces the browser to respect setting selected
7638// on the option
7639// The getter ensures a default option is selected
7640// when in an optgroup
7641if ( !support.optSelected ) {
7642	jQuery.propHooks.selected = {
7643		get: function( elem ) {
7644			var parent = elem.parentNode;
7645			if ( parent && parent.parentNode ) {
7646				parent.parentNode.selectedIndex;
7647			}
7648			return null;
7649		},
7650		set: function( elem ) {
7651			var parent = elem.parentNode;
7652			if ( parent ) {
7653				parent.selectedIndex;
7654
7655				if ( parent.parentNode ) {
7656					parent.parentNode.selectedIndex;
7657				}
7658			}
7659		}
7660	};
7661}
7662
7663jQuery.each( [
7664	"tabIndex",
7665	"readOnly",
7666	"maxLength",
7667	"cellSpacing",
7668	"cellPadding",
7669	"rowSpan",
7670	"colSpan",
7671	"useMap",
7672	"frameBorder",
7673	"contentEditable"
7674], function() {
7675	jQuery.propFix[ this.toLowerCase() ] = this;
7676} );
7677
7678
7679
7680
7681var rclass = /[\t\r\n\f]/g;
7682
7683function getClass( elem ) {
7684	return elem.getAttribute && elem.getAttribute( "class" ) || "";
7685}
7686
7687jQuery.fn.extend( {
7688	addClass: function( value ) {
7689		var classes, elem, cur, curValue, clazz, j, finalValue,
7690			i = 0;
7691
7692		if ( jQuery.isFunction( value ) ) {
7693			return this.each( function( j ) {
7694				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7695			} );
7696		}
7697
7698		if ( typeof value === "string" && value ) {
7699			classes = value.match( rnotwhite ) || [];
7700
7701			while ( ( elem = this[ i++ ] ) ) {
7702				curValue = getClass( elem );
7703				cur = elem.nodeType === 1 &&
7704					( " " + curValue + " " ).replace( rclass, " " );
7705
7706				if ( cur ) {
7707					j = 0;
7708					while ( ( clazz = classes[ j++ ] ) ) {
7709						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7710							cur += clazz + " ";
7711						}
7712					}
7713
7714					// Only assign if different to avoid unneeded rendering.
7715					finalValue = jQuery.trim( cur );
7716					if ( curValue !== finalValue ) {
7717						elem.setAttribute( "class", finalValue );
7718					}
7719				}
7720			}
7721		}
7722
7723		return this;
7724	},
7725
7726	removeClass: function( value ) {
7727		var classes, elem, cur, curValue, clazz, j, finalValue,
7728			i = 0;
7729
7730		if ( jQuery.isFunction( value ) ) {
7731			return this.each( function( j ) {
7732				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7733			} );
7734		}
7735
7736		if ( !arguments.length ) {
7737			return this.attr( "class", "" );
7738		}
7739
7740		if ( typeof value === "string" && value ) {
7741			classes = value.match( rnotwhite ) || [];
7742
7743			while ( ( elem = this[ i++ ] ) ) {
7744				curValue = getClass( elem );
7745
7746				// This expression is here for better compressibility (see addClass)
7747				cur = elem.nodeType === 1 &&
7748					( " " + curValue + " " ).replace( rclass, " " );
7749
7750				if ( cur ) {
7751					j = 0;
7752					while ( ( clazz = classes[ j++ ] ) ) {
7753
7754						// Remove *all* instances
7755						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7756							cur = cur.replace( " " + clazz + " ", " " );
7757						}
7758					}
7759
7760					// Only assign if different to avoid unneeded rendering.
7761					finalValue = jQuery.trim( cur );
7762					if ( curValue !== finalValue ) {
7763						elem.setAttribute( "class", finalValue );
7764					}
7765				}
7766			}
7767		}
7768
7769		return this;
7770	},
7771
7772	toggleClass: function( value, stateVal ) {
7773		var type = typeof value;
7774
7775		if ( typeof stateVal === "boolean" && type === "string" ) {
7776			return stateVal ? this.addClass( value ) : this.removeClass( value );
7777		}
7778
7779		if ( jQuery.isFunction( value ) ) {
7780			return this.each( function( i ) {
7781				jQuery( this ).toggleClass(
7782					value.call( this, i, getClass( this ), stateVal ),
7783					stateVal
7784				);
7785			} );
7786		}
7787
7788		return this.each( function() {
7789			var className, i, self, classNames;
7790
7791			if ( type === "string" ) {
7792
7793				// Toggle individual class names
7794				i = 0;
7795				self = jQuery( this );
7796				classNames = value.match( rnotwhite ) || [];
7797
7798				while ( ( className = classNames[ i++ ] ) ) {
7799
7800					// Check each className given, space separated list
7801					if ( self.hasClass( className ) ) {
7802						self.removeClass( className );
7803					} else {
7804						self.addClass( className );
7805					}
7806				}
7807
7808			// Toggle whole class name
7809			} else if ( value === undefined || type === "boolean" ) {
7810				className = getClass( this );
7811				if ( className ) {
7812
7813					// Store className if set
7814					dataPriv.set( this, "__className__", className );
7815				}
7816
7817				// If the element has a class name or if we're passed `false`,
7818				// then remove the whole classname (if there was one, the above saved it).
7819				// Otherwise bring back whatever was previously saved (if anything),
7820				// falling back to the empty string if nothing was stored.
7821				if ( this.setAttribute ) {
7822					this.setAttribute( "class",
7823						className || value === false ?
7824						"" :
7825						dataPriv.get( this, "__className__" ) || ""
7826					);
7827				}
7828			}
7829		} );
7830	},
7831
7832	hasClass: function( selector ) {
7833		var className, elem,
7834			i = 0;
7835
7836		className = " " + selector + " ";
7837		while ( ( elem = this[ i++ ] ) ) {
7838			if ( elem.nodeType === 1 &&
7839				( " " + getClass( elem ) + " " ).replace( rclass, " " )
7840					.indexOf( className ) > -1
7841			) {
7842				return true;
7843			}
7844		}
7845
7846		return false;
7847	}
7848} );
7849
7850
7851
7852
7853var rreturn = /\r/g,
7854	rspaces = /[\x20\t\r\n\f]+/g;
7855
7856jQuery.fn.extend( {
7857	val: function( value ) {
7858		var hooks, ret, isFunction,
7859			elem = this[ 0 ];
7860
7861		if ( !arguments.length ) {
7862			if ( elem ) {
7863				hooks = jQuery.valHooks[ elem.type ] ||
7864					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7865
7866				if ( hooks &&
7867					"get" in hooks &&
7868					( ret = hooks.get( elem, "value" ) ) !== undefined
7869				) {
7870					return ret;
7871				}
7872
7873				ret = elem.value;
7874
7875				return typeof ret === "string" ?
7876
7877					// Handle most common string cases
7878					ret.replace( rreturn, "" ) :
7879
7880					// Handle cases where value is null/undef or number
7881					ret == null ? "" : ret;
7882			}
7883
7884			return;
7885		}
7886
7887		isFunction = jQuery.isFunction( value );
7888
7889		return this.each( function( i ) {
7890			var val;
7891
7892			if ( this.nodeType !== 1 ) {
7893				return;
7894			}
7895
7896			if ( isFunction ) {
7897				val = value.call( this, i, jQuery( this ).val() );
7898			} else {
7899				val = value;
7900			}
7901
7902			// Treat null/undefined as ""; convert numbers to string
7903			if ( val == null ) {
7904				val = "";
7905
7906			} else if ( typeof val === "number" ) {
7907				val += "";
7908
7909			} else if ( jQuery.isArray( val ) ) {
7910				val = jQuery.map( val, function( value ) {
7911					return value == null ? "" : value + "";
7912				} );
7913			}
7914
7915			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7916
7917			// If set returns undefined, fall back to normal setting
7918			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
7919				this.value = val;
7920			}
7921		} );
7922	}
7923} );
7924
7925jQuery.extend( {
7926	valHooks: {
7927		option: {
7928			get: function( elem ) {
7929
7930				var val = jQuery.find.attr( elem, "value" );
7931				return val != null ?
7932					val :
7933
7934					// Support: IE10-11+
7935					// option.text throws exceptions (#14686, #14858)
7936					// Strip and collapse whitespace
7937					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
7938					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
7939			}
7940		},
7941		select: {
7942			get: function( elem ) {
7943				var value, option,
7944					options = elem.options,
7945					index = elem.selectedIndex,
7946					one = elem.type === "select-one" || index < 0,
7947					values = one ? null : [],
7948					max = one ? index + 1 : options.length,
7949					i = index < 0 ?
7950						max :
7951						one ? index : 0;
7952
7953				// Loop through all the selected options
7954				for ( ; i < max; i++ ) {
7955					option = options[ i ];
7956
7957					// IE8-9 doesn't update selected after form reset (#2551)
7958					if ( ( option.selected || i === index ) &&
7959
7960							// Don't return options that are disabled or in a disabled optgroup
7961							( support.optDisabled ?
7962								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
7963							( !option.parentNode.disabled ||
7964								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7965
7966						// Get the specific value for the option
7967						value = jQuery( option ).val();
7968
7969						// We don't need an array for one selects
7970						if ( one ) {
7971							return value;
7972						}
7973
7974						// Multi-Selects return an array
7975						values.push( value );
7976					}
7977				}
7978
7979				return values;
7980			},
7981
7982			set: function( elem, value ) {
7983				var optionSet, option,
7984					options = elem.options,
7985					values = jQuery.makeArray( value ),
7986					i = options.length;
7987
7988				while ( i-- ) {
7989					option = options[ i ];
7990					if ( option.selected =
7991						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
7992					) {
7993						optionSet = true;
7994					}
7995				}
7996
7997				// Force browsers to behave consistently when non-matching value is set
7998				if ( !optionSet ) {
7999					elem.selectedIndex = -1;
8000				}
8001				return values;
8002			}
8003		}
8004	}
8005} );
8006
8007// Radios and checkboxes getter/setter
8008jQuery.each( [ "radio", "checkbox" ], function() {
8009	jQuery.valHooks[ this ] = {
8010		set: function( elem, value ) {
8011			if ( jQuery.isArray( value ) ) {
8012				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8013			}
8014		}
8015	};
8016	if ( !support.checkOn ) {
8017		jQuery.valHooks[ this ].get = function( elem ) {
8018			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8019		};
8020	}
8021} );
8022
8023
8024
8025
8026// Return jQuery for attributes-only inclusion
8027
8028
8029var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
8030
8031jQuery.extend( jQuery.event, {
8032
8033	trigger: function( event, data, elem, onlyHandlers ) {
8034
8035		var i, cur, tmp, bubbleType, ontype, handle, special,
8036			eventPath = [ elem || document ],
8037			type = hasOwn.call( event, "type" ) ? event.type : event,
8038			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8039
8040		cur = tmp = elem = elem || document;
8041
8042		// Don't do events on text and comment nodes
8043		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8044			return;
8045		}
8046
8047		// focus/blur morphs to focusin/out; ensure we're not firing them right now
8048		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8049			return;
8050		}
8051
8052		if ( type.indexOf( "." ) > -1 ) {
8053
8054			// Namespaced trigger; create a regexp to match event type in handle()
8055			namespaces = type.split( "." );
8056			type = namespaces.shift();
8057			namespaces.sort();
8058		}
8059		ontype = type.indexOf( ":" ) < 0 && "on" + type;
8060
8061		// Caller can pass in a jQuery.Event object, Object, or just an event type string
8062		event = event[ jQuery.expando ] ?
8063			event :
8064			new jQuery.Event( type, typeof event === "object" && event );
8065
8066		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8067		event.isTrigger = onlyHandlers ? 2 : 3;
8068		event.namespace = namespaces.join( "." );
8069		event.rnamespace = event.namespace ?
8070			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8071			null;
8072
8073		// Clean up the event in case it is being reused
8074		event.result = undefined;
8075		if ( !event.target ) {
8076			event.target = elem;
8077		}
8078
8079		// Clone any incoming data and prepend the event, creating the handler arg list
8080		data = data == null ?
8081			[ event ] :
8082			jQuery.makeArray( data, [ event ] );
8083
8084		// Allow special events to draw outside the lines
8085		special = jQuery.event.special[ type ] || {};
8086		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8087			return;
8088		}
8089
8090		// Determine event propagation path in advance, per W3C events spec (#9951)
8091		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8092		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
8093
8094			bubbleType = special.delegateType || type;
8095			if ( !rfocusMorph.test( bubbleType + type ) ) {
8096				cur = cur.parentNode;
8097			}
8098			for ( ; cur; cur = cur.parentNode ) {
8099				eventPath.push( cur );
8100				tmp = cur;
8101			}
8102
8103			// Only add window if we got to document (e.g., not plain obj or detached DOM)
8104			if ( tmp === ( elem.ownerDocument || document ) ) {
8105				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8106			}
8107		}
8108
8109		// Fire handlers on the event path
8110		i = 0;
8111		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8112
8113			event.type = i > 1 ?
8114				bubbleType :
8115				special.bindType || type;
8116
8117			// jQuery handler
8118			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
8119				dataPriv.get( cur, "handle" );
8120			if ( handle ) {
8121				handle.apply( cur, data );
8122			}
8123
8124			// Native handler
8125			handle = ontype && cur[ ontype ];
8126			if ( handle && handle.apply && acceptData( cur ) ) {
8127				event.result = handle.apply( cur, data );
8128				if ( event.result === false ) {
8129					event.preventDefault();
8130				}
8131			}
8132		}
8133		event.type = type;
8134
8135		// If nobody prevented the default action, do it now
8136		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8137
8138			if ( ( !special._default ||
8139				special._default.apply( eventPath.pop(), data ) === false ) &&
8140				acceptData( elem ) ) {
8141
8142				// Call a native DOM method on the target with the same name name as the event.
8143				// Don't do default actions on window, that's where global variables be (#6170)
8144				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
8145
8146					// Don't re-trigger an onFOO event when we call its FOO() method
8147					tmp = elem[ ontype ];
8148
8149					if ( tmp ) {
8150						elem[ ontype ] = null;
8151					}
8152
8153					// Prevent re-triggering of the same event, since we already bubbled it above
8154					jQuery.event.triggered = type;
8155					elem[ type ]();
8156					jQuery.event.triggered = undefined;
8157
8158					if ( tmp ) {
8159						elem[ ontype ] = tmp;
8160					}
8161				}
8162			}
8163		}
8164
8165		return event.result;
8166	},
8167
8168	// Piggyback on a donor event to simulate a different one
8169	// Used only for `focus(in | out)` events
8170	simulate: function( type, elem, event ) {
8171		var e = jQuery.extend(
8172			new jQuery.Event(),
8173			event,
8174			{
8175				type: type,
8176				isSimulated: true
8177			}
8178		);
8179
8180		jQuery.event.trigger( e, null, elem );
8181	}
8182
8183} );
8184
8185jQuery.fn.extend( {
8186
8187	trigger: function( type, data ) {
8188		return this.each( function() {
8189			jQuery.event.trigger( type, data, this );
8190		} );
8191	},
8192	triggerHandler: function( type, data ) {
8193		var elem = this[ 0 ];
8194		if ( elem ) {
8195			return jQuery.event.trigger( type, data, elem, true );
8196		}
8197	}
8198} );
8199
8200
8201jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
8202	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8203	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
8204	function( i, name ) {
8205
8206	// Handle event binding
8207	jQuery.fn[ name ] = function( data, fn ) {
8208		return arguments.length > 0 ?
8209			this.on( name, null, data, fn ) :
8210			this.trigger( name );
8211	};
8212} );
8213
8214jQuery.fn.extend( {
8215	hover: function( fnOver, fnOut ) {
8216		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8217	}
8218} );
8219
8220
8221
8222
8223support.focusin = "onfocusin" in window;
8224
8225
8226// Support: Firefox
8227// Firefox doesn't have focus(in | out) events
8228// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8229//
8230// Support: Chrome, Safari
8231// focus(in | out) events fire after focus & blur events,
8232// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8233// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
8234if ( !support.focusin ) {
8235	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8236
8237		// Attach a single capturing handler on the document while someone wants focusin/focusout
8238		var handler = function( event ) {
8239			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8240		};
8241
8242		jQuery.event.special[ fix ] = {
8243			setup: function() {
8244				var doc = this.ownerDocument || this,
8245					attaches = dataPriv.access( doc, fix );
8246
8247				if ( !attaches ) {
8248					doc.addEventListener( orig, handler, true );
8249				}
8250				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8251			},
8252			teardown: function() {
8253				var doc = this.ownerDocument || this,
8254					attaches = dataPriv.access( doc, fix ) - 1;
8255
8256				if ( !attaches ) {
8257					doc.removeEventListener( orig, handler, true );
8258					dataPriv.remove( doc, fix );
8259
8260				} else {
8261					dataPriv.access( doc, fix, attaches );
8262				}
8263			}
8264		};
8265	} );
8266}
8267var location = window.location;
8268
8269var nonce = jQuery.now();
8270
8271var rquery = ( /\?/ );
8272
8273
8274
8275// Support: Android 2.3
8276// Workaround failure to string-cast null input
8277jQuery.parseJSON = function( data ) {
8278	return JSON.parse( data + "" );
8279};
8280
8281
8282// Cross-browser xml parsing
8283jQuery.parseXML = function( data ) {
8284	var xml;
8285	if ( !data || typeof data !== "string" ) {
8286		return null;
8287	}
8288
8289	// Support: IE9
8290	try {
8291		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8292	} catch ( e ) {
8293		xml = undefined;
8294	}
8295
8296	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
8297		jQuery.error( "Invalid XML: " + data );
8298	}
8299	return xml;
8300};
8301
8302
8303var
8304	rhash = /#.*$/,
8305	rts = /([?&])_=[^&]*/,
8306	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8307
8308	// #7653, #8125, #8152: local protocol detection
8309	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8310	rnoContent = /^(?:GET|HEAD)$/,
8311	rprotocol = /^\/\//,
8312
8313	/* Prefilters
8314	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8315	 * 2) These are called:
8316	 *    - BEFORE asking for a transport
8317	 *    - AFTER param serialization (s.data is a string if s.processData is true)
8318	 * 3) key is the dataType
8319	 * 4) the catchall symbol "*" can be used
8320	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8321	 */
8322	prefilters = {},
8323
8324	/* Transports bindings
8325	 * 1) key is the dataType
8326	 * 2) the catchall symbol "*" can be used
8327	 * 3) selection will start with transport dataType and THEN go to "*" if needed
8328	 */
8329	transports = {},
8330
8331	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8332	allTypes = "*/".concat( "*" ),
8333
8334	// Anchor tag for parsing the document origin
8335	originAnchor = document.createElement( "a" );
8336	originAnchor.href = location.href;
8337
8338// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8339function addToPrefiltersOrTransports( structure ) {
8340
8341	// dataTypeExpression is optional and defaults to "*"
8342	return function( dataTypeExpression, func ) {
8343
8344		if ( typeof dataTypeExpression !== "string" ) {
8345			func = dataTypeExpression;
8346			dataTypeExpression = "*";
8347		}
8348
8349		var dataType,
8350			i = 0,
8351			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8352
8353		if ( jQuery.isFunction( func ) ) {
8354
8355			// For each dataType in the dataTypeExpression
8356			while ( ( dataType = dataTypes[ i++ ] ) ) {
8357
8358				// Prepend if requested
8359				if ( dataType[ 0 ] === "+" ) {
8360					dataType = dataType.slice( 1 ) || "*";
8361					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8362
8363				// Otherwise append
8364				} else {
8365					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8366				}
8367			}
8368		}
8369	};
8370}
8371
8372// Base inspection function for prefilters and transports
8373function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8374
8375	var inspected = {},
8376		seekingTransport = ( structure === transports );
8377
8378	function inspect( dataType ) {
8379		var selected;
8380		inspected[ dataType ] = true;
8381		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8382			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8383			if ( typeof dataTypeOrTransport === "string" &&
8384				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8385
8386				options.dataTypes.unshift( dataTypeOrTransport );
8387				inspect( dataTypeOrTransport );
8388				return false;
8389			} else if ( seekingTransport ) {
8390				return !( selected = dataTypeOrTransport );
8391			}
8392		} );
8393		return selected;
8394	}
8395
8396	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8397}
8398
8399// A special extend for ajax options
8400// that takes "flat" options (not to be deep extended)
8401// Fixes #9887
8402function ajaxExtend( target, src ) {
8403	var key, deep,
8404		flatOptions = jQuery.ajaxSettings.flatOptions || {};
8405
8406	for ( key in src ) {
8407		if ( src[ key ] !== undefined ) {
8408			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8409		}
8410	}
8411	if ( deep ) {
8412		jQuery.extend( true, target, deep );
8413	}
8414
8415	return target;
8416}
8417
8418/* Handles responses to an ajax request:
8419 * - finds the right dataType (mediates between content-type and expected dataType)
8420 * - returns the corresponding response
8421 */
8422function ajaxHandleResponses( s, jqXHR, responses ) {
8423
8424	var ct, type, finalDataType, firstDataType,
8425		contents = s.contents,
8426		dataTypes = s.dataTypes;
8427
8428	// Remove auto dataType and get content-type in the process
8429	while ( dataTypes[ 0 ] === "*" ) {
8430		dataTypes.shift();
8431		if ( ct === undefined ) {
8432			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8433		}
8434	}
8435
8436	// Check if we're dealing with a known content-type
8437	if ( ct ) {
8438		for ( type in contents ) {
8439			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8440				dataTypes.unshift( type );
8441				break;
8442			}
8443		}
8444	}
8445
8446	// Check to see if we have a response for the expected dataType
8447	if ( dataTypes[ 0 ] in responses ) {
8448		finalDataType = dataTypes[ 0 ];
8449	} else {
8450
8451		// Try convertible dataTypes
8452		for ( type in responses ) {
8453			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8454				finalDataType = type;
8455				break;
8456			}
8457			if ( !firstDataType ) {
8458				firstDataType = type;
8459			}
8460		}
8461
8462		// Or just use first one
8463		finalDataType = finalDataType || firstDataType;
8464	}
8465
8466	// If we found a dataType
8467	// We add the dataType to the list if needed
8468	// and return the corresponding response
8469	if ( finalDataType ) {
8470		if ( finalDataType !== dataTypes[ 0 ] ) {
8471			dataTypes.unshift( finalDataType );
8472		}
8473		return responses[ finalDataType ];
8474	}
8475}
8476
8477/* Chain conversions given the request and the original response
8478 * Also sets the responseXXX fields on the jqXHR instance
8479 */
8480function ajaxConvert( s, response, jqXHR, isSuccess ) {
8481	var conv2, current, conv, tmp, prev,
8482		converters = {},
8483
8484		// Work with a copy of dataTypes in case we need to modify it for conversion
8485		dataTypes = s.dataTypes.slice();
8486
8487	// Create converters map with lowercased keys
8488	if ( dataTypes[ 1 ] ) {
8489		for ( conv in s.converters ) {
8490			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8491		}
8492	}
8493
8494	current = dataTypes.shift();
8495
8496	// Convert to each sequential dataType
8497	while ( current ) {
8498
8499		if ( s.responseFields[ current ] ) {
8500			jqXHR[ s.responseFields[ current ] ] = response;
8501		}
8502
8503		// Apply the dataFilter if provided
8504		if ( !prev && isSuccess && s.dataFilter ) {
8505			response = s.dataFilter( response, s.dataType );
8506		}
8507
8508		prev = current;
8509		current = dataTypes.shift();
8510
8511		if ( current ) {
8512
8513		// There's only work to do if current dataType is non-auto
8514			if ( current === "*" ) {
8515
8516				current = prev;
8517
8518			// Convert response if prev dataType is non-auto and differs from current
8519			} else if ( prev !== "*" && prev !== current ) {
8520
8521				// Seek a direct converter
8522				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8523
8524				// If none found, seek a pair
8525				if ( !conv ) {
8526					for ( conv2 in converters ) {
8527
8528						// If conv2 outputs current
8529						tmp = conv2.split( " " );
8530						if ( tmp[ 1 ] === current ) {
8531
8532							// If prev can be converted to accepted input
8533							conv = converters[ prev + " " + tmp[ 0 ] ] ||
8534								converters[ "* " + tmp[ 0 ] ];
8535							if ( conv ) {
8536
8537								// Condense equivalence converters
8538								if ( conv === true ) {
8539									conv = converters[ conv2 ];
8540
8541								// Otherwise, insert the intermediate dataType
8542								} else if ( converters[ conv2 ] !== true ) {
8543									current = tmp[ 0 ];
8544									dataTypes.unshift( tmp[ 1 ] );
8545								}
8546								break;
8547							}
8548						}
8549					}
8550				}
8551
8552				// Apply converter (if not an equivalence)
8553				if ( conv !== true ) {
8554
8555					// Unless errors are allowed to bubble, catch and return them
8556					if ( conv && s.throws ) {
8557						response = conv( response );
8558					} else {
8559						try {
8560							response = conv( response );
8561						} catch ( e ) {
8562							return {
8563								state: "parsererror",
8564								error: conv ? e : "No conversion from " + prev + " to " + current
8565							};
8566						}
8567					}
8568				}
8569			}
8570		}
8571	}
8572
8573	return { state: "success", data: response };
8574}
8575
8576jQuery.extend( {
8577
8578	// Counter for holding the number of active queries
8579	active: 0,
8580
8581	// Last-Modified header cache for next request
8582	lastModified: {},
8583	etag: {},
8584
8585	ajaxSettings: {
8586		url: location.href,
8587		type: "GET",
8588		isLocal: rlocalProtocol.test( location.protocol ),
8589		global: true,
8590		processData: true,
8591		async: true,
8592		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8593		/*
8594		timeout: 0,
8595		data: null,
8596		dataType: null,
8597		username: null,
8598		password: null,
8599		cache: null,
8600		throws: false,
8601		traditional: false,
8602		headers: {},
8603		*/
8604
8605		accepts: {
8606			"*": allTypes,
8607			text: "text/plain",
8608			html: "text/html",
8609			xml: "application/xml, text/xml",
8610			json: "application/json, text/javascript"
8611		},
8612
8613		contents: {
8614			xml: /\bxml\b/,
8615			html: /\bhtml/,
8616			json: /\bjson\b/
8617		},
8618
8619		responseFields: {
8620			xml: "responseXML",
8621			text: "responseText",
8622			json: "responseJSON"
8623		},
8624
8625		// Data converters
8626		// Keys separate source (or catchall "*") and destination types with a single space
8627		converters: {
8628
8629			// Convert anything to text
8630			"* text": String,
8631
8632			// Text to html (true = no transformation)
8633			"text html": true,
8634
8635			// Evaluate text as a json expression
8636			"text json": jQuery.parseJSON,
8637
8638			// Parse text as xml
8639			"text xml": jQuery.parseXML
8640		},
8641
8642		// For options that shouldn't be deep extended:
8643		// you can add your own custom options here if
8644		// and when you create one that shouldn't be
8645		// deep extended (see ajaxExtend)
8646		flatOptions: {
8647			url: true,
8648			context: true
8649		}
8650	},
8651
8652	// Creates a full fledged settings object into target
8653	// with both ajaxSettings and settings fields.
8654	// If target is omitted, writes into ajaxSettings.
8655	ajaxSetup: function( target, settings ) {
8656		return settings ?
8657
8658			// Building a settings object
8659			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8660
8661			// Extending ajaxSettings
8662			ajaxExtend( jQuery.ajaxSettings, target );
8663	},
8664
8665	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8666	ajaxTransport: addToPrefiltersOrTransports( transports ),
8667
8668	// Main method
8669	ajax: function( url, options ) {
8670
8671		// If url is an object, simulate pre-1.5 signature
8672		if ( typeof url === "object" ) {
8673			options = url;
8674			url = undefined;
8675		}
8676
8677		// Force options to be an object
8678		options = options || {};
8679
8680		var transport,
8681
8682			// URL without anti-cache param
8683			cacheURL,
8684
8685			// Response headers
8686			responseHeadersString,
8687			responseHeaders,
8688
8689			// timeout handle
8690			timeoutTimer,
8691
8692			// Url cleanup var
8693			urlAnchor,
8694
8695			// To know if global events are to be dispatched
8696			fireGlobals,
8697
8698			// Loop variable
8699			i,
8700
8701			// Create the final options object
8702			s = jQuery.ajaxSetup( {}, options ),
8703
8704			// Callbacks context
8705			callbackContext = s.context || s,
8706
8707			// Context for global events is callbackContext if it is a DOM node or jQuery collection
8708			globalEventContext = s.context &&
8709				( callbackContext.nodeType || callbackContext.jquery ) ?
8710					jQuery( callbackContext ) :
8711					jQuery.event,
8712
8713			// Deferreds
8714			deferred = jQuery.Deferred(),
8715			completeDeferred = jQuery.Callbacks( "once memory" ),
8716
8717			// Status-dependent callbacks
8718			statusCode = s.statusCode || {},
8719
8720			// Headers (they are sent all at once)
8721			requestHeaders = {},
8722			requestHeadersNames = {},
8723
8724			// The jqXHR state
8725			state = 0,
8726
8727			// Default abort message
8728			strAbort = "canceled",
8729
8730			// Fake xhr
8731			jqXHR = {
8732				readyState: 0,
8733
8734				// Builds headers hashtable if needed
8735				getResponseHeader: function( key ) {
8736					var match;
8737					if ( state === 2 ) {
8738						if ( !responseHeaders ) {
8739							responseHeaders = {};
8740							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8741								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8742							}
8743						}
8744						match = responseHeaders[ key.toLowerCase() ];
8745					}
8746					return match == null ? null : match;
8747				},
8748
8749				// Raw string
8750				getAllResponseHeaders: function() {
8751					return state === 2 ? responseHeadersString : null;
8752				},
8753
8754				// Caches the header
8755				setRequestHeader: function( name, value ) {
8756					var lname = name.toLowerCase();
8757					if ( !state ) {
8758						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
8759						requestHeaders[ name ] = value;
8760					}
8761					return this;
8762				},
8763
8764				// Overrides response content-type header
8765				overrideMimeType: function( type ) {
8766					if ( !state ) {
8767						s.mimeType = type;
8768					}
8769					return this;
8770				},
8771
8772				// Status-dependent callbacks
8773				statusCode: function( map ) {
8774					var code;
8775					if ( map ) {
8776						if ( state < 2 ) {
8777							for ( code in map ) {
8778
8779								// Lazy-add the new callback in a way that preserves old ones
8780								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8781							}
8782						} else {
8783
8784							// Execute the appropriate callbacks
8785							jqXHR.always( map[ jqXHR.status ] );
8786						}
8787					}
8788					return this;
8789				},
8790
8791				// Cancel the request
8792				abort: function( statusText ) {
8793					var finalText = statusText || strAbort;
8794					if ( transport ) {
8795						transport.abort( finalText );
8796					}
8797					done( 0, finalText );
8798					return this;
8799				}
8800			};
8801
8802		// Attach deferreds
8803		deferred.promise( jqXHR ).complete = completeDeferred.add;
8804		jqXHR.success = jqXHR.done;
8805		jqXHR.error = jqXHR.fail;
8806
8807		// Remove hash character (#7531: and string promotion)
8808		// Add protocol if not provided (prefilters might expect it)
8809		// Handle falsy url in the settings object (#10093: consistency with old signature)
8810		// We also use the url parameter if available
8811		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
8812			.replace( rprotocol, location.protocol + "//" );
8813
8814		// Alias method option to type as per ticket #12004
8815		s.type = options.method || options.type || s.method || s.type;
8816
8817		// Extract dataTypes list
8818		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8819
8820		// A cross-domain request is in order when the origin doesn't match the current origin.
8821		if ( s.crossDomain == null ) {
8822			urlAnchor = document.createElement( "a" );
8823
8824			// Support: IE8-11+
8825			// IE throws exception if url is malformed, e.g. http://example.com:80x/
8826			try {
8827				urlAnchor.href = s.url;
8828
8829				// Support: IE8-11+
8830				// Anchor's host property isn't correctly set when s.url is relative
8831				urlAnchor.href = urlAnchor.href;
8832				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
8833					urlAnchor.protocol + "//" + urlAnchor.host;
8834			} catch ( e ) {
8835
8836				// If there is an error parsing the URL, assume it is crossDomain,
8837				// it can be rejected by the transport if it is invalid
8838				s.crossDomain = true;
8839			}
8840		}
8841
8842		// Convert data if not already a string
8843		if ( s.data && s.processData && typeof s.data !== "string" ) {
8844			s.data = jQuery.param( s.data, s.traditional );
8845		}
8846
8847		// Apply prefilters
8848		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8849
8850		// If request was aborted inside a prefilter, stop there
8851		if ( state === 2 ) {
8852			return jqXHR;
8853		}
8854
8855		// We can fire global events as of now if asked to
8856		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8857		fireGlobals = jQuery.event && s.global;
8858
8859		// Watch for a new set of requests
8860		if ( fireGlobals && jQuery.active++ === 0 ) {
8861			jQuery.event.trigger( "ajaxStart" );
8862		}
8863
8864		// Uppercase the type
8865		s.type = s.type.toUpperCase();
8866
8867		// Determine if request has content
8868		s.hasContent = !rnoContent.test( s.type );
8869
8870		// Save the URL in case we're toying with the If-Modified-Since
8871		// and/or If-None-Match header later on
8872		cacheURL = s.url;
8873
8874		// More options handling for requests with no content
8875		if ( !s.hasContent ) {
8876
8877			// If data is available, append data to url
8878			if ( s.data ) {
8879				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8880
8881				// #9682: remove data so that it's not used in an eventual retry
8882				delete s.data;
8883			}
8884
8885			// Add anti-cache in url if needed
8886			if ( s.cache === false ) {
8887				s.url = rts.test( cacheURL ) ?
8888
8889					// If there is already a '_' parameter, set its value
8890					cacheURL.replace( rts, "$1_=" + nonce++ ) :
8891
8892					// Otherwise add one to the end
8893					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8894			}
8895		}
8896
8897		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8898		if ( s.ifModified ) {
8899			if ( jQuery.lastModified[ cacheURL ] ) {
8900				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8901			}
8902			if ( jQuery.etag[ cacheURL ] ) {
8903				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8904			}
8905		}
8906
8907		// Set the correct header, if data is being sent
8908		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8909			jqXHR.setRequestHeader( "Content-Type", s.contentType );
8910		}
8911
8912		// Set the Accepts header for the server, depending on the dataType
8913		jqXHR.setRequestHeader(
8914			"Accept",
8915			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
8916				s.accepts[ s.dataTypes[ 0 ] ] +
8917					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8918				s.accepts[ "*" ]
8919		);
8920
8921		// Check for headers option
8922		for ( i in s.headers ) {
8923			jqXHR.setRequestHeader( i, s.headers[ i ] );
8924		}
8925
8926		// Allow custom headers/mimetypes and early abort
8927		if ( s.beforeSend &&
8928			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8929
8930			// Abort if not done already and return
8931			return jqXHR.abort();
8932		}
8933
8934		// Aborting is no longer a cancellation
8935		strAbort = "abort";
8936
8937		// Install callbacks on deferreds
8938		for ( i in { success: 1, error: 1, complete: 1 } ) {
8939			jqXHR[ i ]( s[ i ] );
8940		}
8941
8942		// Get transport
8943		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8944
8945		// If no transport, we auto-abort
8946		if ( !transport ) {
8947			done( -1, "No Transport" );
8948		} else {
8949			jqXHR.readyState = 1;
8950
8951			// Send global event
8952			if ( fireGlobals ) {
8953				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8954			}
8955
8956			// If request was aborted inside ajaxSend, stop there
8957			if ( state === 2 ) {
8958				return jqXHR;
8959			}
8960
8961			// Timeout
8962			if ( s.async && s.timeout > 0 ) {
8963				timeoutTimer = window.setTimeout( function() {
8964					jqXHR.abort( "timeout" );
8965				}, s.timeout );
8966			}
8967
8968			try {
8969				state = 1;
8970				transport.send( requestHeaders, done );
8971			} catch ( e ) {
8972
8973				// Propagate exception as error if not done
8974				if ( state < 2 ) {
8975					done( -1, e );
8976
8977				// Simply rethrow otherwise
8978				} else {
8979					throw e;
8980				}
8981			}
8982		}
8983
8984		// Callback for when everything is done
8985		function done( status, nativeStatusText, responses, headers ) {
8986			var isSuccess, success, error, response, modified,
8987				statusText = nativeStatusText;
8988
8989			// Called once
8990			if ( state === 2 ) {
8991				return;
8992			}
8993
8994			// State is "done" now
8995			state = 2;
8996
8997			// Clear timeout if it exists
8998			if ( timeoutTimer ) {
8999				window.clearTimeout( timeoutTimer );
9000			}
9001
9002			// Dereference transport for early garbage collection
9003			// (no matter how long the jqXHR object will be used)
9004			transport = undefined;
9005
9006			// Cache response headers
9007			responseHeadersString = headers || "";
9008
9009			// Set readyState
9010			jqXHR.readyState = status > 0 ? 4 : 0;
9011
9012			// Determine if successful
9013			isSuccess = status >= 200 && status < 300 || status === 304;
9014
9015			// Get response data
9016			if ( responses ) {
9017				response = ajaxHandleResponses( s, jqXHR, responses );
9018			}
9019
9020			// Convert no matter what (that way responseXXX fields are always set)
9021			response = ajaxConvert( s, response, jqXHR, isSuccess );
9022
9023			// If successful, handle type chaining
9024			if ( isSuccess ) {
9025
9026				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9027				if ( s.ifModified ) {
9028					modified = jqXHR.getResponseHeader( "Last-Modified" );
9029					if ( modified ) {
9030						jQuery.lastModified[ cacheURL ] = modified;
9031					}
9032					modified = jqXHR.getResponseHeader( "etag" );
9033					if ( modified ) {
9034						jQuery.etag[ cacheURL ] = modified;
9035					}
9036				}
9037
9038				// if no content
9039				if ( status === 204 || s.type === "HEAD" ) {
9040					statusText = "nocontent";
9041
9042				// if not modified
9043				} else if ( status === 304 ) {
9044					statusText = "notmodified";
9045
9046				// If we have data, let's convert it
9047				} else {
9048					statusText = response.state;
9049					success = response.data;
9050					error = response.error;
9051					isSuccess = !error;
9052				}
9053			} else {
9054
9055				// Extract error from statusText and normalize for non-aborts
9056				error = statusText;
9057				if ( status || !statusText ) {
9058					statusText = "error";
9059					if ( status < 0 ) {
9060						status = 0;
9061					}
9062				}
9063			}
9064
9065			// Set data for the fake xhr object
9066			jqXHR.status = status;
9067			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9068
9069			// Success/Error
9070			if ( isSuccess ) {
9071				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9072			} else {
9073				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9074			}
9075
9076			// Status-dependent callbacks
9077			jqXHR.statusCode( statusCode );
9078			statusCode = undefined;
9079
9080			if ( fireGlobals ) {
9081				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9082					[ jqXHR, s, isSuccess ? success : error ] );
9083			}
9084
9085			// Complete
9086			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9087
9088			if ( fireGlobals ) {
9089				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9090
9091				// Handle the global AJAX counter
9092				if ( !( --jQuery.active ) ) {
9093					jQuery.event.trigger( "ajaxStop" );
9094				}
9095			}
9096		}
9097
9098		return jqXHR;
9099	},
9100
9101	getJSON: function( url, data, callback ) {
9102		return jQuery.get( url, data, callback, "json" );
9103	},
9104
9105	getScript: function( url, callback ) {
9106		return jQuery.get( url, undefined, callback, "script" );
9107	}
9108} );
9109
9110jQuery.each( [ "get", "post" ], function( i, method ) {
9111	jQuery[ method ] = function( url, data, callback, type ) {
9112
9113		// Shift arguments if data argument was omitted
9114		if ( jQuery.isFunction( data ) ) {
9115			type = type || callback;
9116			callback = data;
9117			data = undefined;
9118		}
9119
9120		// The url can be an options object (which then must have .url)
9121		return jQuery.ajax( jQuery.extend( {
9122			url: url,
9123			type: method,
9124			dataType: type,
9125			data: data,
9126			success: callback
9127		}, jQuery.isPlainObject( url ) && url ) );
9128	};
9129} );
9130
9131
9132jQuery._evalUrl = function( url ) {
9133	return jQuery.ajax( {
9134		url: url,
9135
9136		// Make this explicit, since user can override this through ajaxSetup (#11264)
9137		type: "GET",
9138		dataType: "script",
9139		async: false,
9140		global: false,
9141		"throws": true
9142	} );
9143};
9144
9145
9146jQuery.fn.extend( {
9147	wrapAll: function( html ) {
9148		var wrap;
9149
9150		if ( jQuery.isFunction( html ) ) {
9151			return this.each( function( i ) {
9152				jQuery( this ).wrapAll( html.call( this, i ) );
9153			} );
9154		}
9155
9156		if ( this[ 0 ] ) {
9157
9158			// The elements to wrap the target around
9159			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9160
9161			if ( this[ 0 ].parentNode ) {
9162				wrap.insertBefore( this[ 0 ] );
9163			}
9164
9165			wrap.map( function() {
9166				var elem = this;
9167
9168				while ( elem.firstElementChild ) {
9169					elem = elem.firstElementChild;
9170				}
9171
9172				return elem;
9173			} ).append( this );
9174		}
9175
9176		return this;
9177	},
9178
9179	wrapInner: function( html ) {
9180		if ( jQuery.isFunction( html ) ) {
9181			return this.each( function( i ) {
9182				jQuery( this ).wrapInner( html.call( this, i ) );
9183			} );
9184		}
9185
9186		return this.each( function() {
9187			var self = jQuery( this ),
9188				contents = self.contents();
9189
9190			if ( contents.length ) {
9191				contents.wrapAll( html );
9192
9193			} else {
9194				self.append( html );
9195			}
9196		} );
9197	},
9198
9199	wrap: function( html ) {
9200		var isFunction = jQuery.isFunction( html );
9201
9202		return this.each( function( i ) {
9203			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9204		} );
9205	},
9206
9207	unwrap: function() {
9208		return this.parent().each( function() {
9209			if ( !jQuery.nodeName( this, "body" ) ) {
9210				jQuery( this ).replaceWith( this.childNodes );
9211			}
9212		} ).end();
9213	}
9214} );
9215
9216
9217jQuery.expr.filters.hidden = function( elem ) {
9218	return !jQuery.expr.filters.visible( elem );
9219};
9220jQuery.expr.filters.visible = function( elem ) {
9221
9222	// Support: Opera <= 12.12
9223	// Opera reports offsetWidths and offsetHeights less than zero on some elements
9224	// Use OR instead of AND as the element is not visible if either is true
9225	// See tickets #10406 and #13132
9226	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
9227};
9228
9229
9230
9231
9232var r20 = /%20/g,
9233	rbracket = /\[\]$/,
9234	rCRLF = /\r?\n/g,
9235	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9236	rsubmittable = /^(?:input|select|textarea|keygen)/i;
9237
9238function buildParams( prefix, obj, traditional, add ) {
9239	var name;
9240
9241	if ( jQuery.isArray( obj ) ) {
9242
9243		// Serialize array item.
9244		jQuery.each( obj, function( i, v ) {
9245			if ( traditional || rbracket.test( prefix ) ) {
9246
9247				// Treat each array item as a scalar.
9248				add( prefix, v );
9249
9250			} else {
9251
9252				// Item is non-scalar (array or object), encode its numeric index.
9253				buildParams(
9254					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
9255					v,
9256					traditional,
9257					add
9258				);
9259			}
9260		} );
9261
9262	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
9263
9264		// Serialize object item.
9265		for ( name in obj ) {
9266			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9267		}
9268
9269	} else {
9270
9271		// Serialize scalar item.
9272		add( prefix, obj );
9273	}
9274}
9275
9276// Serialize an array of form elements or a set of
9277// key/values into a query string
9278jQuery.param = function( a, traditional ) {
9279	var prefix,
9280		s = [],
9281		add = function( key, value ) {
9282
9283			// If value is a function, invoke it and return its value
9284			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
9285			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
9286		};
9287
9288	// Set traditional to true for jQuery <= 1.3.2 behavior.
9289	if ( traditional === undefined ) {
9290		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
9291	}
9292
9293	// If an array was passed in, assume that it is an array of form elements.
9294	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9295
9296		// Serialize the form elements
9297		jQuery.each( a, function() {
9298			add( this.name, this.value );
9299		} );
9300
9301	} else {
9302
9303		// If traditional, encode the "old" way (the way 1.3.2 or older
9304		// did it), otherwise encode params recursively.
9305		for ( prefix in a ) {
9306			buildParams( prefix, a[ prefix ], traditional, add );
9307		}
9308	}
9309
9310	// Return the resulting serialization
9311	return s.join( "&" ).replace( r20, "+" );
9312};
9313
9314jQuery.fn.extend( {
9315	serialize: function() {
9316		return jQuery.param( this.serializeArray() );
9317	},
9318	serializeArray: function() {
9319		return this.map( function() {
9320
9321			// Can add propHook for "elements" to filter or add form elements
9322			var elements = jQuery.prop( this, "elements" );
9323			return elements ? jQuery.makeArray( elements ) : this;
9324		} )
9325		.filter( function() {
9326			var type = this.type;
9327
9328			// Use .is( ":disabled" ) so that fieldset[disabled] works
9329			return this.name && !jQuery( this ).is( ":disabled" ) &&
9330				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9331				( this.checked || !rcheckableType.test( type ) );
9332		} )
9333		.map( function( i, elem ) {
9334			var val = jQuery( this ).val();
9335
9336			return val == null ?
9337				null :
9338				jQuery.isArray( val ) ?
9339					jQuery.map( val, function( val ) {
9340						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9341					} ) :
9342					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9343		} ).get();
9344	}
9345} );
9346
9347
9348jQuery.ajaxSettings.xhr = function() {
9349	try {
9350		return new window.XMLHttpRequest();
9351	} catch ( e ) {}
9352};
9353
9354var xhrSuccessStatus = {
9355
9356		// File protocol always yields status code 0, assume 200
9357		0: 200,
9358
9359		// Support: IE9
9360		// #1450: sometimes IE returns 1223 when it should be 204
9361		1223: 204
9362	},
9363	xhrSupported = jQuery.ajaxSettings.xhr();
9364
9365support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9366support.ajax = xhrSupported = !!xhrSupported;
9367
9368jQuery.ajaxTransport( function( options ) {
9369	var callback, errorCallback;
9370
9371	// Cross domain only allowed if supported through XMLHttpRequest
9372	if ( support.cors || xhrSupported && !options.crossDomain ) {
9373		return {
9374			send: function( headers, complete ) {
9375				var i,
9376					xhr = options.xhr();
9377
9378				xhr.open(
9379					options.type,
9380					options.url,
9381					options.async,
9382					options.username,
9383					options.password
9384				);
9385
9386				// Apply custom fields if provided
9387				if ( options.xhrFields ) {
9388					for ( i in options.xhrFields ) {
9389						xhr[ i ] = options.xhrFields[ i ];
9390					}
9391				}
9392
9393				// Override mime type if needed
9394				if ( options.mimeType && xhr.overrideMimeType ) {
9395					xhr.overrideMimeType( options.mimeType );
9396				}
9397
9398				// X-Requested-With header
9399				// For cross-domain requests, seeing as conditions for a preflight are
9400				// akin to a jigsaw puzzle, we simply never set it to be sure.
9401				// (it can always be set on a per-request basis or even using ajaxSetup)
9402				// For same-domain requests, won't change header if already provided.
9403				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9404					headers[ "X-Requested-With" ] = "XMLHttpRequest";
9405				}
9406
9407				// Set headers
9408				for ( i in headers ) {
9409					xhr.setRequestHeader( i, headers[ i ] );
9410				}
9411
9412				// Callback
9413				callback = function( type ) {
9414					return function() {
9415						if ( callback ) {
9416							callback = errorCallback = xhr.onload =
9417								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9418
9419							if ( type === "abort" ) {
9420								xhr.abort();
9421							} else if ( type === "error" ) {
9422
9423								// Support: IE9
9424								// On a manual native abort, IE9 throws
9425								// errors on any property access that is not readyState
9426								if ( typeof xhr.status !== "number" ) {
9427									complete( 0, "error" );
9428								} else {
9429									complete(
9430
9431										// File: protocol always yields status 0; see #8605, #14207
9432										xhr.status,
9433										xhr.statusText
9434									);
9435								}
9436							} else {
9437								complete(
9438									xhrSuccessStatus[ xhr.status ] || xhr.status,
9439									xhr.statusText,
9440
9441									// Support: IE9 only
9442									// IE9 has no XHR2 but throws on binary (trac-11426)
9443									// For XHR2 non-text, let the caller handle it (gh-2498)
9444									( xhr.responseType || "text" ) !== "text"  ||
9445									typeof xhr.responseText !== "string" ?
9446										{ binary: xhr.response } :
9447										{ text: xhr.responseText },
9448									xhr.getAllResponseHeaders()
9449								);
9450							}
9451						}
9452					};
9453				};
9454
9455				// Listen to events
9456				xhr.onload = callback();
9457				errorCallback = xhr.onerror = callback( "error" );
9458
9459				// Support: IE9
9460				// Use onreadystatechange to replace onabort
9461				// to handle uncaught aborts
9462				if ( xhr.onabort !== undefined ) {
9463					xhr.onabort = errorCallback;
9464				} else {
9465					xhr.onreadystatechange = function() {
9466
9467						// Check readyState before timeout as it changes
9468						if ( xhr.readyState === 4 ) {
9469
9470							// Allow onerror to be called first,
9471							// but that will not handle a native abort
9472							// Also, save errorCallback to a variable
9473							// as xhr.onerror cannot be accessed
9474							window.setTimeout( function() {
9475								if ( callback ) {
9476									errorCallback();
9477								}
9478							} );
9479						}
9480					};
9481				}
9482
9483				// Create the abort callback
9484				callback = callback( "abort" );
9485
9486				try {
9487
9488					// Do send the request (this may raise an exception)
9489					xhr.send( options.hasContent && options.data || null );
9490				} catch ( e ) {
9491
9492					// #14683: Only rethrow if this hasn't been notified as an error yet
9493					if ( callback ) {
9494						throw e;
9495					}
9496				}
9497			},
9498
9499			abort: function() {
9500				if ( callback ) {
9501					callback();
9502				}
9503			}
9504		};
9505	}
9506} );
9507
9508
9509
9510
9511// Install script dataType
9512jQuery.ajaxSetup( {
9513	accepts: {
9514		script: "text/javascript, application/javascript, " +
9515			"application/ecmascript, application/x-ecmascript"
9516	},
9517	contents: {
9518		script: /\b(?:java|ecma)script\b/
9519	},
9520	converters: {
9521		"text script": function( text ) {
9522			jQuery.globalEval( text );
9523			return text;
9524		}
9525	}
9526} );
9527
9528// Handle cache's special case and crossDomain
9529jQuery.ajaxPrefilter( "script", function( s ) {
9530	if ( s.cache === undefined ) {
9531		s.cache = false;
9532	}
9533	if ( s.crossDomain ) {
9534		s.type = "GET";
9535	}
9536} );
9537
9538// Bind script tag hack transport
9539jQuery.ajaxTransport( "script", function( s ) {
9540
9541	// This transport only deals with cross domain requests
9542	if ( s.crossDomain ) {
9543		var script, callback;
9544		return {
9545			send: function( _, complete ) {
9546				script = jQuery( "<script>" ).prop( {
9547					charset: s.scriptCharset,
9548					src: s.url
9549				} ).on(
9550					"load error",
9551					callback = function( evt ) {
9552						script.remove();
9553						callback = null;
9554						if ( evt ) {
9555							complete( evt.type === "error" ? 404 : 200, evt.type );
9556						}
9557					}
9558				);
9559
9560				// Use native DOM manipulation to avoid our domManip AJAX trickery
9561				document.head.appendChild( script[ 0 ] );
9562			},
9563			abort: function() {
9564				if ( callback ) {
9565					callback();
9566				}
9567			}
9568		};
9569	}
9570} );
9571
9572
9573
9574
9575var oldCallbacks = [],
9576	rjsonp = /(=)\?(?=&|$)|\?\?/;
9577
9578// Default jsonp settings
9579jQuery.ajaxSetup( {
9580	jsonp: "callback",
9581	jsonpCallback: function() {
9582		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9583		this[ callback ] = true;
9584		return callback;
9585	}
9586} );
9587
9588// Detect, normalize options and install callbacks for jsonp requests
9589jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9590
9591	var callbackName, overwritten, responseContainer,
9592		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9593			"url" :
9594			typeof s.data === "string" &&
9595				( s.contentType || "" )
9596					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9597				rjsonp.test( s.data ) && "data"
9598		);
9599
9600	// Handle iff the expected data type is "jsonp" or we have a parameter to set
9601	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9602
9603		// Get callback name, remembering preexisting value associated with it
9604		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9605			s.jsonpCallback() :
9606			s.jsonpCallback;
9607
9608		// Insert callback into url or form data
9609		if ( jsonProp ) {
9610			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9611		} else if ( s.jsonp !== false ) {
9612			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9613		}
9614
9615		// Use data converter to retrieve json after script execution
9616		s.converters[ "script json" ] = function() {
9617			if ( !responseContainer ) {
9618				jQuery.error( callbackName + " was not called" );
9619			}
9620			return responseContainer[ 0 ];
9621		};
9622
9623		// Force json dataType
9624		s.dataTypes[ 0 ] = "json";
9625
9626		// Install callback
9627		overwritten = window[ callbackName ];
9628		window[ callbackName ] = function() {
9629			responseContainer = arguments;
9630		};
9631
9632		// Clean-up function (fires after converters)
9633		jqXHR.always( function() {
9634
9635			// If previous value didn't exist - remove it
9636			if ( overwritten === undefined ) {
9637				jQuery( window ).removeProp( callbackName );
9638
9639			// Otherwise restore preexisting value
9640			} else {
9641				window[ callbackName ] = overwritten;
9642			}
9643
9644			// Save back as free
9645			if ( s[ callbackName ] ) {
9646
9647				// Make sure that re-using the options doesn't screw things around
9648				s.jsonpCallback = originalSettings.jsonpCallback;
9649
9650				// Save the callback name for future use
9651				oldCallbacks.push( callbackName );
9652			}
9653
9654			// Call if it was a function and we have a response
9655			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9656				overwritten( responseContainer[ 0 ] );
9657			}
9658
9659			responseContainer = overwritten = undefined;
9660		} );
9661
9662		// Delegate to script
9663		return "script";
9664	}
9665} );
9666
9667
9668
9669
9670// Argument "data" should be string of html
9671// context (optional): If specified, the fragment will be created in this context,
9672// defaults to document
9673// keepScripts (optional): If true, will include scripts passed in the html string
9674jQuery.parseHTML = function( data, context, keepScripts ) {
9675	if ( !data || typeof data !== "string" ) {
9676		return null;
9677	}
9678	if ( typeof context === "boolean" ) {
9679		keepScripts = context;
9680		context = false;
9681	}
9682	context = context || document;
9683
9684	var parsed = rsingleTag.exec( data ),
9685		scripts = !keepScripts && [];
9686
9687	// Single tag
9688	if ( parsed ) {
9689		return [ context.createElement( parsed[ 1 ] ) ];
9690	}
9691
9692	parsed = buildFragment( [ data ], context, scripts );
9693
9694	if ( scripts && scripts.length ) {
9695		jQuery( scripts ).remove();
9696	}
9697
9698	return jQuery.merge( [], parsed.childNodes );
9699};
9700
9701
9702// Keep a copy of the old load method
9703var _load = jQuery.fn.load;
9704
9705/**
9706 * Load a url into a page
9707 */
9708jQuery.fn.load = function( url, params, callback ) {
9709	if ( typeof url !== "string" && _load ) {
9710		return _load.apply( this, arguments );
9711	}
9712
9713	var selector, type, response,
9714		self = this,
9715		off = url.indexOf( " " );
9716
9717	if ( off > -1 ) {
9718		selector = jQuery.trim( url.slice( off ) );
9719		url = url.slice( 0, off );
9720	}
9721
9722	// If it's a function
9723	if ( jQuery.isFunction( params ) ) {
9724
9725		// We assume that it's the callback
9726		callback = params;
9727		params = undefined;
9728
9729	// Otherwise, build a param string
9730	} else if ( params && typeof params === "object" ) {
9731		type = "POST";
9732	}
9733
9734	// If we have elements to modify, make the request
9735	if ( self.length > 0 ) {
9736		jQuery.ajax( {
9737			url: url,
9738
9739			// If "type" variable is undefined, then "GET" method will be used.
9740			// Make value of this field explicit since
9741			// user can override it through ajaxSetup method
9742			type: type || "GET",
9743			dataType: "html",
9744			data: params
9745		} ).done( function( responseText ) {
9746
9747			// Save response for use in complete callback
9748			response = arguments;
9749
9750			self.html( selector ?
9751
9752				// If a selector was specified, locate the right elements in a dummy div
9753				// Exclude scripts to avoid IE 'Permission Denied' errors
9754				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9755
9756				// Otherwise use the full result
9757				responseText );
9758
9759		// If the request succeeds, this function gets "data", "status", "jqXHR"
9760		// but they are ignored because response was set above.
9761		// If it fails, this function gets "jqXHR", "status", "error"
9762		} ).always( callback && function( jqXHR, status ) {
9763			self.each( function() {
9764				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9765			} );
9766		} );
9767	}
9768
9769	return this;
9770};
9771
9772
9773
9774
9775// Attach a bunch of functions for handling common AJAX events
9776jQuery.each( [
9777	"ajaxStart",
9778	"ajaxStop",
9779	"ajaxComplete",
9780	"ajaxError",
9781	"ajaxSuccess",
9782	"ajaxSend"
9783], function( i, type ) {
9784	jQuery.fn[ type ] = function( fn ) {
9785		return this.on( type, fn );
9786	};
9787} );
9788
9789
9790
9791
9792jQuery.expr.filters.animated = function( elem ) {
9793	return jQuery.grep( jQuery.timers, function( fn ) {
9794		return elem === fn.elem;
9795	} ).length;
9796};
9797
9798
9799
9800
9801/**
9802 * Gets a window from an element
9803 */
9804function getWindow( elem ) {
9805	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
9806}
9807
9808jQuery.offset = {
9809	setOffset: function( elem, options, i ) {
9810		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9811			position = jQuery.css( elem, "position" ),
9812			curElem = jQuery( elem ),
9813			props = {};
9814
9815		// Set position first, in-case top/left are set even on static elem
9816		if ( position === "static" ) {
9817			elem.style.position = "relative";
9818		}
9819
9820		curOffset = curElem.offset();
9821		curCSSTop = jQuery.css( elem, "top" );
9822		curCSSLeft = jQuery.css( elem, "left" );
9823		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9824			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9825
9826		// Need to be able to calculate position if either
9827		// top or left is auto and position is either absolute or fixed
9828		if ( calculatePosition ) {
9829			curPosition = curElem.position();
9830			curTop = curPosition.top;
9831			curLeft = curPosition.left;
9832
9833		} else {
9834			curTop = parseFloat( curCSSTop ) || 0;
9835			curLeft = parseFloat( curCSSLeft ) || 0;
9836		}
9837
9838		if ( jQuery.isFunction( options ) ) {
9839
9840			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9841			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9842		}
9843
9844		if ( options.top != null ) {
9845			props.top = ( options.top - curOffset.top ) + curTop;
9846		}
9847		if ( options.left != null ) {
9848			props.left = ( options.left - curOffset.left ) + curLeft;
9849		}
9850
9851		if ( "using" in options ) {
9852			options.using.call( elem, props );
9853
9854		} else {
9855			curElem.css( props );
9856		}
9857	}
9858};
9859
9860jQuery.fn.extend( {
9861	offset: function( options ) {
9862		if ( arguments.length ) {
9863			return options === undefined ?
9864				this :
9865				this.each( function( i ) {
9866					jQuery.offset.setOffset( this, options, i );
9867				} );
9868		}
9869
9870		var docElem, win,
9871			elem = this[ 0 ],
9872			box = { top: 0, left: 0 },
9873			doc = elem && elem.ownerDocument;
9874
9875		if ( !doc ) {
9876			return;
9877		}
9878
9879		docElem = doc.documentElement;
9880
9881		// Make sure it's not a disconnected DOM node
9882		if ( !jQuery.contains( docElem, elem ) ) {
9883			return box;
9884		}
9885
9886		box = elem.getBoundingClientRect();
9887		win = getWindow( doc );
9888		return {
9889			top: box.top + win.pageYOffset - docElem.clientTop,
9890			left: box.left + win.pageXOffset - docElem.clientLeft
9891		};
9892	},
9893
9894	position: function() {
9895		if ( !this[ 0 ] ) {
9896			return;
9897		}
9898
9899		var offsetParent, offset,
9900			elem = this[ 0 ],
9901			parentOffset = { top: 0, left: 0 };
9902
9903		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9904		// because it is its only offset parent
9905		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9906
9907			// Assume getBoundingClientRect is there when computed position is fixed
9908			offset = elem.getBoundingClientRect();
9909
9910		} else {
9911
9912			// Get *real* offsetParent
9913			offsetParent = this.offsetParent();
9914
9915			// Get correct offsets
9916			offset = this.offset();
9917			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9918				parentOffset = offsetParent.offset();
9919			}
9920
9921			// Add offsetParent borders
9922			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9923			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9924		}
9925
9926		// Subtract parent offsets and element margins
9927		return {
9928			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9929			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9930		};
9931	},
9932
9933	// This method will return documentElement in the following cases:
9934	// 1) For the element inside the iframe without offsetParent, this method will return
9935	//    documentElement of the parent window
9936	// 2) For the hidden or detached element
9937	// 3) For body or html element, i.e. in case of the html node - it will return itself
9938	//
9939	// but those exceptions were never presented as a real life use-cases
9940	// and might be considered as more preferable results.
9941	//
9942	// This logic, however, is not guaranteed and can change at any point in the future
9943	offsetParent: function() {
9944		return this.map( function() {
9945			var offsetParent = this.offsetParent;
9946
9947			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
9948				offsetParent = offsetParent.offsetParent;
9949			}
9950
9951			return offsetParent || documentElement;
9952		} );
9953	}
9954} );
9955
9956// Create scrollLeft and scrollTop methods
9957jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9958	var top = "pageYOffset" === prop;
9959
9960	jQuery.fn[ method ] = function( val ) {
9961		return access( this, function( elem, method, val ) {
9962			var win = getWindow( elem );
9963
9964			if ( val === undefined ) {
9965				return win ? win[ prop ] : elem[ method ];
9966			}
9967
9968			if ( win ) {
9969				win.scrollTo(
9970					!top ? val : win.pageXOffset,
9971					top ? val : win.pageYOffset
9972				);
9973
9974			} else {
9975				elem[ method ] = val;
9976			}
9977		}, method, val, arguments.length );
9978	};
9979} );
9980
9981// Support: Safari<7-8+, Chrome<37-44+
9982// Add the top/left cssHooks using jQuery.fn.position
9983// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9984// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9985// getComputedStyle returns percent when specified for top/left/bottom/right;
9986// rather than make the css module depend on the offset module, just check for it here
9987jQuery.each( [ "top", "left" ], function( i, prop ) {
9988	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9989		function( elem, computed ) {
9990			if ( computed ) {
9991				computed = curCSS( elem, prop );
9992
9993				// If curCSS returns percentage, fallback to offset
9994				return rnumnonpx.test( computed ) ?
9995					jQuery( elem ).position()[ prop ] + "px" :
9996					computed;
9997			}
9998		}
9999	);
10000} );
10001
10002
10003// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10004jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10005	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10006		function( defaultExtra, funcName ) {
10007
10008		// Margin is only for outerHeight, outerWidth
10009		jQuery.fn[ funcName ] = function( margin, value ) {
10010			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10011				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10012
10013			return access( this, function( elem, type, value ) {
10014				var doc;
10015
10016				if ( jQuery.isWindow( elem ) ) {
10017
10018					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10019					// isn't a whole lot we can do. See pull request at this URL for discussion:
10020					// https://github.com/jquery/jquery/pull/764
10021					return elem.document.documentElement[ "client" + name ];
10022				}
10023
10024				// Get document width or height
10025				if ( elem.nodeType === 9 ) {
10026					doc = elem.documentElement;
10027
10028					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10029					// whichever is greatest
10030					return Math.max(
10031						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10032						elem.body[ "offset" + name ], doc[ "offset" + name ],
10033						doc[ "client" + name ]
10034					);
10035				}
10036
10037				return value === undefined ?
10038
10039					// Get width or height on the element, requesting but not forcing parseFloat
10040					jQuery.css( elem, type, extra ) :
10041
10042					// Set width or height on the element
10043					jQuery.style( elem, type, value, extra );
10044			}, type, chainable ? margin : undefined, chainable, null );
10045		};
10046	} );
10047} );
10048
10049
10050jQuery.fn.extend( {
10051
10052	bind: function( types, data, fn ) {
10053		return this.on( types, null, data, fn );
10054	},
10055	unbind: function( types, fn ) {
10056		return this.off( types, null, fn );
10057	},
10058
10059	delegate: function( selector, types, data, fn ) {
10060		return this.on( types, selector, data, fn );
10061	},
10062	undelegate: function( selector, types, fn ) {
10063
10064		// ( namespace ) or ( selector, types [, fn] )
10065		return arguments.length === 1 ?
10066			this.off( selector, "**" ) :
10067			this.off( types, selector || "**", fn );
10068	},
10069	size: function() {
10070		return this.length;
10071	}
10072} );
10073
10074jQuery.fn.andSelf = jQuery.fn.addBack;
10075
10076
10077
10078
10079// Register as a named AMD module, since jQuery can be concatenated with other
10080// files that may use define, but not via a proper concatenation script that
10081// understands anonymous AMD modules. A named AMD is safest and most robust
10082// way to register. Lowercase jquery is used because AMD module names are
10083// derived from file names, and jQuery is normally delivered in a lowercase
10084// file name. Do this after creating the global so that if an AMD module wants
10085// to call noConflict to hide this version of jQuery, it will work.
10086
10087// Note that for maximum portability, libraries that are not jQuery should
10088// declare themselves as anonymous modules, and avoid setting a global if an
10089// AMD loader is present. jQuery is a special case. For more information, see
10090// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10091
10092if ( typeof define === "function" && define.amd ) {
10093	define( "jquery", [], function() {
10094		return jQuery;
10095	} );
10096}
10097
10098
10099
10100var
10101
10102	// Map over jQuery in case of overwrite
10103	_jQuery = window.jQuery,
10104
10105	// Map over the $ in case of overwrite
10106	_$ = window.$;
10107
10108jQuery.noConflict = function( deep ) {
10109	if ( window.$ === jQuery ) {
10110		window.$ = _$;
10111	}
10112
10113	if ( deep && window.jQuery === jQuery ) {
10114		window.jQuery = _jQuery;
10115	}
10116
10117	return jQuery;
10118};
10119
10120// Expose jQuery and $ identifiers, even in AMD
10121// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10122// and CommonJS for browser emulators (#13566)
10123if ( !noGlobal ) {
10124	window.jQuery = window.$ = jQuery;
10125}
10126
10127return jQuery;
10128}));
10129
10130;;(function() {
10131/*!
10132 * @overview  Ember - JavaScript Application Framework
10133 * @copyright Copyright 2011-2016 Tilde Inc. and contributors
10134 *            Portions Copyright 2006-2011 Strobe Inc.
10135 *            Portions Copyright 2008-2011 Apple Inc. All rights reserved.
10136 * @license   Licensed under MIT license
10137 *            See https://raw.github.com/emberjs/ember.js/master/LICENSE
10138 * @version   2.5.1
10139 */
10140
10141var enifed, requireModule, require, requirejs, Ember;
10142var mainContext = this;
10143
10144(function() {
10145  var isNode = typeof window === 'undefined' &&
10146    typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
10147
10148  if (!isNode) {
10149    Ember = this.Ember = this.Ember || {};
10150  }
10151
10152  if (typeof Ember === 'undefined') { Ember = {}; };
10153
10154  if (typeof Ember.__loader === 'undefined') {
10155    var registry = {};
10156    var seen = {};
10157
10158    enifed = function(name, deps, callback) {
10159      var value = { };
10160
10161      if (!callback) {
10162        value.deps = [];
10163        value.callback = deps;
10164      } else {
10165        value.deps = deps;
10166        value.callback = callback;
10167      }
10168
10169      registry[name] = value;
10170    };
10171
10172    requirejs = require = requireModule = function(name) {
10173      return internalRequire(name, null);
10174    }
10175
10176    // setup `require` module
10177    require['default'] = require;
10178
10179    require.has = function registryHas(moduleName) {
10180      return !!registry[moduleName] || !!registry[moduleName + '/index'];
10181    };
10182
10183    function missingModule(name, referrerName) {
10184      if (referrerName) {
10185        throw new Error('Could not find module ' + name + ' required by: ' + referrerName);
10186      } else {
10187        throw new Error('Could not find module ' + name);
10188      }
10189    }
10190
10191    function internalRequire(_name, referrerName) {
10192      var name = _name;
10193      var mod = registry[name];
10194
10195      if (!mod) {
10196        name = name + '/index';
10197        mod = registry[name];
10198      }
10199
10200      var exports = seen[name];
10201
10202      if (exports !== undefined) {
10203        return exports;
10204      }
10205
10206      exports = seen[name] = {};
10207
10208      if (!mod) {
10209        missingModule(_name, referrerName);
10210      }
10211
10212      var deps = mod.deps;
10213      var callback = mod.callback;
10214      var length = deps.length;
10215      var reified = new Array(length);;
10216
10217      for (var i = 0; i < length; i++) {
10218        if (deps[i] === 'exports') {
10219          reified[i] = exports;
10220        } else if (deps[i] === 'require') {
10221          reified[i] = require;
10222        } else {
10223          reified[i] = internalRequire(deps[i], name);
10224        }
10225      }
10226
10227      callback.apply(this, reified);
10228
10229      return exports;
10230    };
10231
10232    requirejs._eak_seen = registry;
10233
10234    Ember.__loader = {
10235      define: enifed,
10236      require: require,
10237      registry: registry
10238    };
10239  } else {
10240    enifed = Ember.__loader.define;
10241    requirejs = require = requireModule = Ember.__loader.require;
10242  }
10243})();
10244
10245enifed("backburner/binary-search", ["exports"], function (exports) {
10246  "use strict";
10247
10248  exports.default = binarySearch;
10249
10250  function binarySearch(time, timers) {
10251    var start = 0;
10252    var end = timers.length - 2;
10253    var middle, l;
10254
10255    while (start < end) {
10256      // since timers is an array of pairs 'l' will always
10257      // be an integer
10258      l = (end - start) / 2;
10259
10260      // compensate for the index in case even number
10261      // of pairs inside timers
10262      middle = start + l - l % 2;
10263
10264      if (time >= timers[middle]) {
10265        start = middle + 2;
10266      } else {
10267        end = middle;
10268      }
10269    }
10270
10271    return time >= timers[start] ? start + 2 : start;
10272  }
10273});
10274enifed('backburner/deferred-action-queues', ['exports', 'backburner/utils', 'backburner/queue'], function (exports, _backburnerUtils, _backburnerQueue) {
10275  'use strict';
10276
10277  exports.default = DeferredActionQueues;
10278
10279  function DeferredActionQueues(queueNames, options) {
10280    var queues = this.queues = {};
10281    this.queueNames = queueNames = queueNames || [];
10282
10283    this.options = options;
10284
10285    _backburnerUtils.each(queueNames, function (queueName) {
10286      queues[queueName] = new _backburnerQueue.default(queueName, options[queueName], options);
10287    });
10288  }
10289
10290  function noSuchQueue(name) {
10291    throw new Error('You attempted to schedule an action in a queue (' + name + ') that doesn\'t exist');
10292  }
10293
10294  function noSuchMethod(name) {
10295    throw new Error('You attempted to schedule an action in a queue (' + name + ') for a method that doesn\'t exist');
10296  }
10297
10298  DeferredActionQueues.prototype = {
10299    schedule: function (name, target, method, args, onceFlag, stack) {
10300      var queues = this.queues;
10301      var queue = queues[name];
10302
10303      if (!queue) {
10304        noSuchQueue(name);
10305      }
10306
10307      if (!method) {
10308        noSuchMethod(name);
10309      }
10310
10311      if (onceFlag) {
10312        return queue.pushUnique(target, method, args, stack);
10313      } else {
10314        return queue.push(target, method, args, stack);
10315      }
10316    },
10317
10318    flush: function () {
10319      var queues = this.queues;
10320      var queueNames = this.queueNames;
10321      var queueName, queue;
10322      var queueNameIndex = 0;
10323      var numberOfQueues = queueNames.length;
10324
10325      while (queueNameIndex < numberOfQueues) {
10326        queueName = queueNames[queueNameIndex];
10327        queue = queues[queueName];
10328
10329        var numberOfQueueItems = queue._queue.length;
10330
10331        if (numberOfQueueItems === 0) {
10332          queueNameIndex++;
10333        } else {
10334          queue.flush(false /* async */);
10335          queueNameIndex = 0;
10336        }
10337      }
10338    }
10339  };
10340});
10341enifed('backburner/platform', ['exports'], function (exports) {
10342  'use strict';
10343
10344  var GlobalContext;
10345
10346  /* global self */
10347  if (typeof self === 'object') {
10348    GlobalContext = self;
10349
10350    /* global global */
10351  } else if (typeof global === 'object') {
10352      GlobalContext = global;
10353
10354      /* global window */
10355    } else if (typeof window === 'object') {
10356        GlobalContext = window;
10357      } else {
10358        throw new Error('no global: `self`, `global` nor `window` was found');
10359      }
10360
10361  exports.default = GlobalContext;
10362});
10363enifed('backburner/queue', ['exports', 'backburner/utils'], function (exports, _backburnerUtils) {
10364  'use strict';
10365
10366  exports.default = Queue;
10367
10368  function Queue(name, options, globalOptions) {
10369    this.name = name;
10370    this.globalOptions = globalOptions || {};
10371    this.options = options;
10372    this._queue = [];
10373    this.targetQueues = {};
10374    this._queueBeingFlushed = undefined;
10375  }
10376
10377  Queue.prototype = {
10378    push: function (target, method, args, stack) {
10379      var queue = this._queue;
10380      queue.push(target, method, args, stack);
10381
10382      return {
10383        queue: this,
10384        target: target,
10385        method: method
10386      };
10387    },
10388
10389    pushUniqueWithoutGuid: function (target, method, args, stack) {
10390      var queue = this._queue;
10391
10392      for (var i = 0, l = queue.length; i < l; i += 4) {
10393        var currentTarget = queue[i];
10394        var currentMethod = queue[i + 1];
10395
10396        if (currentTarget === target && currentMethod === method) {
10397          queue[i + 2] = args; // replace args
10398          queue[i + 3] = stack; // replace stack
10399          return;
10400        }
10401      }
10402
10403      queue.push(target, method, args, stack);
10404    },
10405
10406    targetQueue: function (targetQueue, target, method, args, stack) {
10407      var queue = this._queue;
10408
10409      for (var i = 0, l = targetQueue.length; i < l; i += 2) {
10410        var currentMethod = targetQueue[i];
10411        var currentIndex = targetQueue[i + 1];
10412
10413        if (currentMethod === method) {
10414          queue[currentIndex + 2] = args; // replace args
10415          queue[currentIndex + 3] = stack; // replace stack
10416          return;
10417        }
10418      }
10419
10420      targetQueue.push(method, queue.push(target, method, args, stack) - 4);
10421    },
10422
10423    pushUniqueWithGuid: function (guid, target, method, args, stack) {
10424      var hasLocalQueue = this.targetQueues[guid];
10425
10426      if (hasLocalQueue) {
10427        this.targetQueue(hasLocalQueue, target, method, args, stack);
10428      } else {
10429        this.targetQueues[guid] = [method, this._queue.push(target, method, args, stack) - 4];
10430      }
10431
10432      return {
10433        queue: this,
10434        target: target,
10435        method: method
10436      };
10437    },
10438
10439    pushUnique: function (target, method, args, stack) {
10440      var KEY = this.globalOptions.GUID_KEY;
10441
10442      if (target && KEY) {
10443        var guid = target[KEY];
10444        if (guid) {
10445          return this.pushUniqueWithGuid(guid, target, method, args, stack);
10446        }
10447      }
10448
10449      this.pushUniqueWithoutGuid(target, method, args, stack);
10450
10451      return {
10452        queue: this,
10453        target: target,
10454        method: method
10455      };
10456    },
10457
10458    invoke: function (target, method, args, _, _errorRecordedForStack) {
10459      if (args && args.length > 0) {
10460        method.apply(target, args);
10461      } else {
10462        method.call(target);
10463      }
10464    },
10465
10466    invokeWithOnError: function (target, method, args, onError, errorRecordedForStack) {
10467      try {
10468        if (args && args.length > 0) {
10469          method.apply(target, args);
10470        } else {
10471          method.call(target);
10472        }
10473      } catch (error) {
10474        onError(error, errorRecordedForStack);
10475      }
10476    },
10477
10478    flush: function (sync) {
10479      var queue = this._queue;
10480      var length = queue.length;
10481
10482      if (length === 0) {
10483        return;
10484      }
10485
10486      var globalOptions = this.globalOptions;
10487      var options = this.options;
10488      var before = options && options.before;
10489      var after = options && options.after;
10490      var onError = globalOptions.onError || globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod];
10491      var target, method, args, errorRecordedForStack;
10492      var invoke = onError ? this.invokeWithOnError : this.invoke;
10493
10494      this.targetQueues = Object.create(null);
10495      var queueItems = this._queueBeingFlushed = this._queue.slice();
10496      this._queue = [];
10497
10498      if (before) {
10499        before();
10500      }
10501
10502      for (var i = 0; i < length; i += 4) {
10503        target = queueItems[i];
10504        method = queueItems[i + 1];
10505        args = queueItems[i + 2];
10506        errorRecordedForStack = queueItems[i + 3]; // Debugging assistance
10507
10508        if (_backburnerUtils.isString(method)) {
10509          method = target[method];
10510        }
10511
10512        // method could have been nullified / canceled during flush
10513        if (method) {
10514          //
10515          //    ** Attention intrepid developer **
10516          //
10517          //    To find out the stack of this task when it was scheduled onto
10518          //    the run loop, add the following to your app.js:
10519          //
10520          //    Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production.
10521          //
10522          //    Once that is in place, when you are at a breakpoint and navigate
10523          //    here in the stack explorer, you can look at `errorRecordedForStack.stack`,
10524          //    which will be the captured stack when this job was scheduled.
10525          //
10526          invoke(target, method, args, onError, errorRecordedForStack);
10527        }
10528      }
10529
10530      if (after) {
10531        after();
10532      }
10533
10534      this._queueBeingFlushed = undefined;
10535
10536      if (sync !== false && this._queue.length > 0) {
10537        // check if new items have been added
10538        this.flush(true);
10539      }
10540    },
10541
10542    cancel: function (actionToCancel) {
10543      var queue = this._queue,
10544          currentTarget,
10545          currentMethod,
10546          i,
10547          l;
10548      var target = actionToCancel.target;
10549      var method = actionToCancel.method;
10550      var GUID_KEY = this.globalOptions.GUID_KEY;
10551
10552      if (GUID_KEY && this.targetQueues && target) {
10553        var targetQueue = this.targetQueues[target[GUID_KEY]];
10554
10555        if (targetQueue) {
10556          for (i = 0, l = targetQueue.length; i < l; i++) {
10557            if (targetQueue[i] === method) {
10558              targetQueue.splice(i, 1);
10559            }
10560          }
10561        }
10562      }
10563
10564      for (i = 0, l = queue.length; i < l; i += 4) {
10565        currentTarget = queue[i];
10566        currentMethod = queue[i + 1];
10567
10568        if (currentTarget === target && currentMethod === method) {
10569          queue.splice(i, 4);
10570          return true;
10571        }
10572      }
10573
10574      // if not found in current queue
10575      // could be in the queue that is being flushed
10576      queue = this._queueBeingFlushed;
10577
10578      if (!queue) {
10579        return;
10580      }
10581
10582      for (i = 0, l = queue.length; i < l; i += 4) {
10583        currentTarget = queue[i];
10584        currentMethod = queue[i + 1];
10585
10586        if (currentTarget === target && currentMethod === method) {
10587          // don't mess with array during flush
10588          // just nullify the method
10589          queue[i + 1] = null;
10590          return true;
10591        }
10592      }
10593    }
10594  };
10595});
10596enifed('backburner/utils', ['exports'], function (exports) {
10597  'use strict';
10598
10599  exports.each = each;
10600  exports.isString = isString;
10601  exports.isFunction = isFunction;
10602  exports.isNumber = isNumber;
10603  exports.isCoercableNumber = isCoercableNumber;
10604  var NUMBER = /\d+/;
10605
10606  function each(collection, callback) {
10607    for (var i = 0; i < collection.length; i++) {
10608      callback(collection[i]);
10609    }
10610  }
10611
10612  function isString(suspect) {
10613    return typeof suspect === 'string';
10614  }
10615
10616  function isFunction(suspect) {
10617    return typeof suspect === 'function';
10618  }
10619
10620  function isNumber(suspect) {
10621    return typeof suspect === 'number';
10622  }
10623
10624  function isCoercableNumber(number) {
10625    return isNumber(number) || NUMBER.test(number);
10626  }
10627});
10628enifed('backburner', ['exports', 'backburner/utils', 'backburner/platform', 'backburner/binary-search', 'backburner/deferred-action-queues'], function (exports, _backburnerUtils, _backburnerPlatform, _backburnerBinarySearch, _backburnerDeferredActionQueues) {
10629  'use strict';
10630
10631  exports.default = Backburner;
10632
10633  function Backburner(queueNames, options) {
10634    this.queueNames = queueNames;
10635    this.options = options || {};
10636    if (!this.options.defaultQueue) {
10637      this.options.defaultQueue = queueNames[0];
10638    }
10639    this.instanceStack = [];
10640    this._debouncees = [];
10641    this._throttlers = [];
10642    this._eventCallbacks = {
10643      end: [],
10644      begin: []
10645    };
10646
10647    var _this = this;
10648    this._boundClearItems = function () {
10649      clearItems();
10650    };
10651
10652    this._timerTimeoutId = undefined;
10653    this._timers = [];
10654
10655    this._platform = this.options._platform || _backburnerPlatform.default;
10656
10657    this._boundRunExpiredTimers = function () {
10658      _this._runExpiredTimers();
10659    };
10660  }
10661
10662  Backburner.prototype = {
10663    begin: function () {
10664      var options = this.options;
10665      var onBegin = options && options.onBegin;
10666      var previousInstance = this.currentInstance;
10667
10668      if (previousInstance) {
10669        this.instanceStack.push(previousInstance);
10670      }
10671
10672      this.currentInstance = new _backburnerDeferredActionQueues.default(this.queueNames, options);
10673      this._trigger('begin', this.currentInstance, previousInstance);
10674      if (onBegin) {
10675        onBegin(this.currentInstance, previousInstance);
10676      }
10677    },
10678
10679    end: function () {
10680      var options = this.options;
10681      var onEnd = options && options.onEnd;
10682      var currentInstance = this.currentInstance;
10683      var nextInstance = null;
10684
10685      // Prevent double-finally bug in Safari 6.0.2 and iOS 6
10686      // This bug appears to be resolved in Safari 6.0.5 and iOS 7
10687      var finallyAlreadyCalled = false;
10688      try {
10689        currentInstance.flush();
10690      } finally {
10691        if (!finallyAlreadyCalled) {
10692          finallyAlreadyCalled = true;
10693
10694          this.currentInstance = null;
10695
10696          if (this.instanceStack.length) {
10697            nextInstance = this.instanceStack.pop();
10698            this.currentInstance = nextInstance;
10699          }
10700          this._trigger('end', currentInstance, nextInstance);
10701          if (onEnd) {
10702            onEnd(currentInstance, nextInstance);
10703          }
10704        }
10705      }
10706    },
10707
10708    /**
10709     Trigger an event. Supports up to two arguments. Designed around
10710     triggering transition events from one run loop instance to the
10711     next, which requires an argument for the first instance and then
10712     an argument for the next instance.
10713      @private
10714     @method _trigger
10715     @param {String} eventName
10716     @param {any} arg1
10717     @param {any} arg2
10718     */
10719    _trigger: function (eventName, arg1, arg2) {
10720      var callbacks = this._eventCallbacks[eventName];
10721      if (callbacks) {
10722        for (var i = 0; i < callbacks.length; i++) {
10723          callbacks[i](arg1, arg2);
10724        }
10725      }
10726    },
10727
10728    on: function (eventName, callback) {
10729      if (typeof callback !== 'function') {
10730        throw new TypeError('Callback must be a function');
10731      }
10732      var callbacks = this._eventCallbacks[eventName];
10733      if (callbacks) {
10734        callbacks.push(callback);
10735      } else {
10736        throw new TypeError('Cannot on() event "' + eventName + '" because it does not exist');
10737      }
10738    },
10739
10740    off: function (eventName, callback) {
10741      if (eventName) {
10742        var callbacks = this._eventCallbacks[eventName];
10743        var callbackFound = false;
10744        if (!callbacks) return;
10745        if (callback) {
10746          for (var i = 0; i < callbacks.length; i++) {
10747            if (callbacks[i] === callback) {
10748              callbackFound = true;
10749              callbacks.splice(i, 1);
10750              i--;
10751            }
10752          }
10753        }
10754        if (!callbackFound) {
10755          throw new TypeError('Cannot off() callback that does not exist');
10756        }
10757      } else {
10758        throw new TypeError('Cannot off() event "' + eventName + '" because it does not exist');
10759      }
10760    },
10761
10762    run: function () /* target, method, args */{
10763      var length = arguments.length;
10764      var method, target, args;
10765
10766      if (length === 1) {
10767        method = arguments[0];
10768        target = null;
10769      } else {
10770        target = arguments[0];
10771        method = arguments[1];
10772      }
10773
10774      if (_backburnerUtils.isString(method)) {
10775        method = target[method];
10776      }
10777
10778      if (length > 2) {
10779        args = new Array(length - 2);
10780        for (var i = 0, l = length - 2; i < l; i++) {
10781          args[i] = arguments[i + 2];
10782        }
10783      } else {
10784        args = [];
10785      }
10786
10787      var onError = getOnError(this.options);
10788
10789      this.begin();
10790
10791      // guard against Safari 6's double-finally bug
10792      var didFinally = false;
10793
10794      if (onError) {
10795        try {
10796          return method.apply(target, args);
10797        } catch (error) {
10798          onError(error);
10799        } finally {
10800          if (!didFinally) {
10801            didFinally = true;
10802            this.end();
10803          }
10804        }
10805      } else {
10806        try {
10807          return method.apply(target, args);
10808        } finally {
10809          if (!didFinally) {
10810            didFinally = true;
10811            this.end();
10812          }
10813        }
10814      }
10815    },
10816
10817    /*
10818      Join the passed method with an existing queue and execute immediately,
10819      if there isn't one use `Backburner#run`.
10820        The join method is like the run method except that it will schedule into
10821      an existing queue if one already exists. In either case, the join method will
10822      immediately execute the passed in function and return its result.
10823       @method join 
10824      @param {Object} target
10825      @param {Function} method The method to be executed 
10826      @param {any} args The method arguments
10827      @return method result
10828    */
10829    join: function () /* target, method, args */{
10830      if (!this.currentInstance) {
10831        return this.run.apply(this, arguments);
10832      }
10833
10834      var length = arguments.length;
10835      var method, target;
10836
10837      if (length === 1) {
10838        method = arguments[0];
10839        target = null;
10840      } else {
10841        target = arguments[0];
10842        method = arguments[1];
10843      }
10844
10845      if (_backburnerUtils.isString(method)) {
10846        method = target[method];
10847      }
10848
10849      if (length === 1) {
10850        return method();
10851      } else if (length === 2) {
10852        return method.call(target);
10853      } else {
10854        var args = new Array(length - 2);
10855        for (var i = 0, l = length - 2; i < l; i++) {
10856          args[i] = arguments[i + 2];
10857        }
10858        return method.apply(target, args);
10859      }
10860    },
10861
10862    /*
10863      Defer the passed function to run inside the specified queue.
10864       @method defer 
10865      @param {String} queueName 
10866      @param {Object} target
10867      @param {Function|String}
10867 method The method or method name to be executed 
10868      @param {any} args The method arguments
10869      @return method result
10870    */
10871    defer: function (queueName /* , target, method, args */) {
10872      var length = arguments.length;
10873      var method, target, args;
10874
10875      if (length === 2) {
10876        method = arguments[1];
10877        target = null;
10878      } else {
10879        target = arguments[1];
10880        method = arguments[2];
10881      }
10882
10883      if (_backburnerUtils.isString(method)) {
10884        method = target[method];
10885      }
10886
10887      var stack = this.DEBUG ? new Error() : undefined;
10888
10889      if (length > 3) {
10890        args = new Array(length - 3);
10891        for (var i = 3; i < length; i++) {
10892          args[i - 3] = arguments[i];
10893        }
10894      } else {
10895        args = undefined;
10896      }
10897
10898      if (!this.currentInstance) {
10899        createAutorun(this);
10900      }
10901      return this.currentInstance.schedule(queueName, target, method, args, false, stack);
10902    },
10903
10904    deferOnce: function (queueName /* , target, method, args */) {
10905      var length = arguments.length;
10906      var method, target, args;
10907
10908      if (length === 2) {
10909        method = arguments[1];
10910        target = null;
10911      } else {
10912        target = arguments[1];
10913        method = arguments[2];
10914      }
10915
10916      if (_backburnerUtils.isString(method)) {
10917        method = target[method];
10918      }
10919
10920      var stack = this.DEBUG ? new Error() : undefined;
10921
10922      if (length > 3) {
10923        args = new Array(length - 3);
10924        for (var i = 3; i < length; i++) {
10925          args[i - 3] = arguments[i];
10926        }
10927      } else {
10928        args = undefined;
10929      }
10930
10931      if (!this.currentInstance) {
10932        createAutorun(this);
10933      }
10934      return this.currentInstance.schedule(queueName, target, method, args, true, stack);
10935    },
10936
10937    setTimeout: function () {
10938      var l = arguments.length;
10939      var args = new Array(l);
10940
10941      for (var x = 0; x < l; x++) {
10942        args[x] = arguments[x];
10943      }
10944
10945      var length = args.length,
10946          method,
10947          wait,
10948          target,
10949          methodOrTarget,
10950          methodOrWait,
10951          methodOrArgs;
10952
10953      if (length === 0) {
10954        return;
10955      } else if (length === 1) {
10956        method = args.shift();
10957        wait = 0;
10958      } else if (length === 2) {
10959        methodOrTarget = args[0];
10960        methodOrWait = args[1];
10961
10962        if (_backburnerUtils.isFunction(methodOrWait) || _backburnerUtils.isFunction(methodOrTarget[methodOrWait])) {
10963          target = args.shift();
10964          method = args.shift();
10965          wait = 0;
10966        } else if (_backburnerUtils.isCoercableNumber(methodOrWait)) {
10967          method = args.shift();
10968          wait = args.shift();
10969        } else {
10970          method = args.shift();
10971          wait = 0;
10972        }
10973      } else {
10974        var last = args[args.length - 1];
10975
10976        if (_backburnerUtils.isCoercableNumber(last)) {
10977          wait = args.pop();
10978        } else {
10979          wait = 0;
10980        }
10981
10982        methodOrTarget = args[0];
10983        methodOrArgs = args[1];
10984
10985        if (_backburnerUtils.isFunction(methodOrArgs) || _backburnerUtils.isString(methodOrArgs) && methodOrTarget !== null && methodOrArgs in methodOrTarget) {
10986          target = args.shift();
10987          method = args.shift();
10988        } else {
10989          method = args.shift();
10990        }
10991      }
10992
10993      var executeAt = Date.now() + parseInt(wait, 10);
10994
10995      if (_backburnerUtils.isString(method)) {
10996        method = target[method];
10997      }
10998
10999      var onError = getOnError(this.options);
11000
11001      function fn() {
11002        if (onError) {
11003          try {
11004            method.apply(target, args);
11005          } catch (e) {
11006            onError(e);
11007          }
11008        } else {
11009          method.apply(target, args);
11010        }
11011      }
11012
11013      return this._setTimeout(fn, executeAt);
11014    },
11015
11016    _setTimeout: function (fn, executeAt) {
11017      if (this._timers.length === 0) {
11018        this._timers.push(executeAt, fn);
11019        this._installTimerTimeout();
11020        return fn;
11021      }
11022
11023      // find position to insert
11024      var i = _backburnerBinarySearch.default(executeAt, this._timers);
11025
11026      this._timers.splice(i, 0, executeAt, fn);
11027
11028      // we should be the new earliest timer if i == 0
11029      if (i === 0) {
11030        this._reinstallTimerTimeout();
11031      }
11032
11033      return fn;
11034    },
11035
11036    throttle: function (target, method /* , args, wait, [immediate] */) {
11037      var backburner = this;
11038      var args = new Array(arguments.length);
11039      for (var i = 0; i < arguments.length; i++) {
11040        args[i] = arguments[i];
11041      }
11042      var immediate = args.pop();
11043      var wait, throttler, index, timer;
11044
11045      if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
11046        wait = immediate;
11047        immediate = true;
11048      } else {
11049        wait = args.pop();
11050      }
11051
11052      wait = parseInt(wait, 10);
11053
11054      index = findThrottler(target, method, this._throttlers);
11055      if (index > -1) {
11056        return this._throttlers[index];
11057      } // throttled
11058
11059      timer = this._platform.setTimeout(function () {
11060        if (!immediate) {
11061          backburner.run.apply(backburner, args);
11062        }
11063        var index = findThrottler(target, method, backburner._throttlers);
11064        if (index > -1) {
11065          backburner._throttlers.splice(index, 1);
11066        }
11067      }, wait);
11068
11069      if (immediate) {
11070        this.run.apply(this, args);
11071      }
11072
11073      throttler = [target, method, timer];
11074
11075      this._throttlers.push(throttler);
11076
11077      return throttler;
11078    },
11079
11080    debounce: function (target, method /* , args, wait, [immediate] */) {
11081      var backburner = this;
11082      var args = new Array(arguments.length);
11083      for (var i = 0; i < arguments.length; i++) {
11084        args[i] = arguments[i];
11085      }
11086
11087      var immediate = args.pop();
11088      var wait, index, debouncee, timer;
11089
11090      if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
11091        wait = immediate;
11092        immediate = false;
11093      } else {
11094        wait = args.pop();
11095      }
11096
11097      wait = parseInt(wait, 10);
11098      // Remove debouncee
11099      index = findDebouncee(target, method, this._debouncees);
11100
11101      if (index > -1) {
11102        debouncee = this._debouncees[index];
11103        this._debouncees.splice(index, 1);
11104        this._platform.clearTimeout(debouncee[2]);
11105      }
11106
11107      timer = this._platform.setTimeout(function () {
11108        if (!immediate) {
11109          backburner.run.apply(backburner, args);
11110        }
11111        var index = findDebouncee(target, method, backburner._debouncees);
11112        if (index > -1) {
11113          backburner._debouncees.splice(index, 1);
11114        }
11115      }, wait);
11116
11117      if (immediate && index === -1) {
11118        backburner.run.apply(backburner, args);
11119      }
11120
11121      debouncee = [target, method, timer];
11122
11123      backburner._debouncees.push(debouncee);
11124
11125      return debouncee;
11126    },
11127
11128    cancelTimers: function () {
11129      _backburnerUtils.each(this._throttlers, this._boundClearItems);
11130      this._throttlers = [];
11131
11132      _backburnerUtils.each(this._debouncees, this._boundClearItems);
11133      this._debouncees = [];
11134
11135      this._clearTimerTimeout();
11136      this._timers = [];
11137
11138      if (this._autorun) {
11139        this._platform.clearTimeout(this._autorun);
11140        this._autorun = null;
11141      }
11142    },
11143
11144    hasTimers: function () {
11145      return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
11146    },
11147
11148    cancel: function (timer) {
11149      var timerType = typeof timer;
11150
11151      if (timer && timerType === 'object' && timer.queue && timer.method) {
11152        // we're cancelling a deferOnce
11153        return timer.queue.cancel(timer);
11154      } else if (timerType === 'function') {
11155        // we're cancelling a setTimeout
11156        for (var i = 0, l = this._timers.length; i < l; i += 2) {
11157          if (this._timers[i + 1] === timer) {
11158            this._timers.splice(i, 2); // remove the two elements
11159            if (i === 0) {
11160              this._reinstallTimerTimeout();
11161            }
11162            return true;
11163          }
11164        }
11165      } else if (Object.prototype.toString.call(timer) === '[object Array]') {
11166        // we're cancelling a throttle or debounce
11167        return this._cancelItem(findThrottler, this._throttlers, timer) || this._cancelItem(findDebouncee, this._debouncees, timer);
11168      } else {
11169        return; // timer was null or not a timer
11170      }
11171    },
11172
11173    _cancelItem: function (findMethod, array, timer) {
11174      var item, index;
11175
11176      if (timer.length < 3) {
11177        return false;
11178      }
11179
11180      index = findMethod(timer[0], timer[1], array);
11181
11182      if (index > -1) {
11183
11184        item = array[index];
11185
11186        if (item[2] === timer[2]) {
11187          array.splice(index, 1);
11188          this._platform.clearTimeout(timer[2]);
11189          return true;
11190        }
11191      }
11192
11193      return false;
11194    },
11195
11196    _runExpiredTimers: function () {
11197      this._timerTimeoutId = undefined;
11198      this.run(this, this._scheduleExpiredTimers);
11199    },
11200
11201    _scheduleExpiredTimers: function () {
11202      var n = Date.now();
11203      var timers = this._timers;
11204      var i = 0;
11205      var l = timers.length;
11206      for (; i < l; i += 2) {
11207        var executeAt = timers[i];
11208        var fn = timers[i + 1];
11209        if (executeAt <= n) {
11210          this.schedule(this.options.defaultQueue, null, fn);
11211        } else {
11212          break;
11213        }
11214      }
11215      timers.splice(0, i);
11216      this._installTimerTimeout();
11217    },
11218
11219    _reinstallTimerTimeout: function () {
11220      this._clearTimerTimeout();
11221      this._installTimerTimeout();
11222    },
11223
11224    _clearTimerTimeout: function () {
11225      if (!this._timerTimeoutId) {
11226        return;
11227      }
11228      this._platform.clearTimeout(this._timerTimeoutId);
11229      this._timerTimeoutId = undefined;
11230    },
11231
11232    _installTimerTimeout: function () {
11233      if (!this._timers.length) {
11234        return;
11235      }
11236      var minExpiresAt = this._timers[0];
11237      var n = Date.now();
11238      var wait = Math.max(0, minExpiresAt - n);
11239      this._timerTimeoutId = this._platform.setTimeout(this._boundRunExpiredTimers, wait);
11240    }
11241  };
11242
11243  Backburner.prototype.schedule = Backburner.prototype.defer;
11244  Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
11245  Backburner.prototype.later = Backburner.prototype.setTimeout;
11246
11247  function getOnError(options) {
11248    return options.onError || options.onErrorTarget && options.onErrorTarget[options.onErrorMethod];
11249  }
11250
11251  function createAutorun(backburner) {
11252    backburner.begin();
11253    backburner._autorun = backburner._platform.setTimeout(function () {
11254      backburner._autorun = null;
11255      backburner.end();
11256    });
11257  }
11258
11259  function findDebouncee(target, method, debouncees) {
11260    return findItem(target, method, debouncees);
11261  }
11262
11263  function findThrottler(target, method, throttlers) {
11264    return findItem(target, method, throttlers);
11265  }
11266
11267  function findItem(target, method, collection) {
11268    var item;
11269    var index = -1;
11270
11271    for (var i = 0, l = collection.length; i < l; i++) {
11272      item = collection[i];
11273      if (item[0] === target && item[1] === method) {
11274        index = i;
11275        break;
11276      }
11277    }
11278
11279    return index;
11280  }
11281
11282  function clearItems(item) {
11283    this._platform.clearTimeout(item[2]);
11284  }
11285});
11286enifed('container/container', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/dictionary', 'ember-metal/features', 'container/owner', 'ember-runtime/mixins/container_proxy', 'ember-metal/symbol'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalDictionary, _emberMetalFeatures, _containerOwner, _emberRuntimeMixinsContainer_proxy, _emberMetalSymbol) {
11287  'use strict';
11288
11289  var CONTAINER_OVERRIDE = _emberMetalSymbol.default('CONTAINER_OVERRIDE');
11290
11291  /**
11292   A container used to instantiate and cache objects.
11293  
11294   Every `Container` must be associated with a `Registry`, which is referenced
11295   to determine the factory and options that should be used to instantiate
11296   objects.
11297  
11298   The public API for `Container` is still in flux and should not be considered
11299   stable.
11300  
11301   @private
11302   @class Container
11303   */
11304  function Container(registry, options) {
11305    this.registry = registry;
11306    this.owner = options && options.owner ? options.owner : null;
11307    this.cache = _emberMetalDictionary.default(options && options.cache ? options.cache : null);
11308    this.factoryCache = _emberMetalDictionary.default(options && options.factoryCache ? options.factoryCache : null);
11309    this.validationCache = _emberMetalDictionary.default(options && options.validationCache ? options.validationCache : null);
11310
11311    this._fakeContainerToInject = _emberRuntimeMixinsContainer_proxy.buildFakeContainerWithDeprecations(this);
11312    this[CONTAINER_OVERRIDE] = undefined;
11313  }
11314
11315  Container.prototype = {
11316    /**
11317     @private
11318     @property owner
11319     @type Object
11320     */
11321    owner: null,
11322
11323    /**
11324     @private
11325     @property registry
11326     @type Registry
11327     @since 1.11.0
11328     */
11329    registry: null,
11330
11331    /**
11332     @private
11333     @property cache
11334     @type InheritingDict
11335     */
11336    cache: null,
11337
11338    /**
11339     @private
11340     @property factoryCache
11341     @type InheritingDict
11342     */
11343    factoryCache: null,
11344
11345    /**
11346     @private
11347     @property validationCache
11348     @type InheritingDict
11349     */
11350    validationCache: null,
11351
11352    /**
11353     Given a fullName return a corresponding instance.
11354      The default behaviour is for lookup to return a singleton instance.
11355     The singleton is scoped to the container, allowing multiple containers
11356     to all have their own locally scoped singletons.
11357      ```javascript
11358     var registry = new Registry();
11359     var container = registry.container();
11360      registry.register('api:twitter', Twitter);
11361      var twitter = container.lookup('api:twitter');
11362      twitter instanceof Twitter; // => true
11363      // by default the container will return singletons
11364     var twitter2 = container.lookup('api:twitter');
11365     twitter2 instanceof Twitter; // => true
11366      twitter === twitter2; //=> true
11367     ```
11368      If singletons are not wanted, an optional flag can be provided at lookup.
11369      ```javascript
11370     var registry = new Registry();
11371     var container = registry.container();
11372      registry.register('api:twitter', Twitter);
11373      var twitter = container.lookup('api:twitter', { singleton: fal
11373se });
11374     var twitter2 = container.lookup('api:twitter', { singleton: false });
11375      twitter === twitter2; //=> false
11376     ```
11377      @private
11378     @method lookup
11379     @param {String} fullName
11380     @param {Object} [options]
11381     @param {String} [options.source] The fullname of the request source (used for local lookup)
11382     @return {any}
11383     */
11384    lookup: function (fullName, options) {
11385      _emberMetalDebug.assert('fullName must be a proper full name', this.registry.validateFullName(fullName));
11386      return lookup(this, this.registry.normalize(fullName), options);
11387    },
11388
11389    /**
11390     Given a fullName, return the corresponding factory.
11391      @private
11392     @method lookupFactory
11393     @param {String} fullName
11394     @param {Object} [options]
11395     @param {String} [options.source] The fullname of the request source (used for local lookup)
11396     @return {any}
11397     */
11398    lookupFactory: function (fullName, options) {
11399      _emberMetalDebug.assert('fullName must be a proper full name', this.registry.validateFullName(fullName));
11400      return factoryFor(this, this.registry.normalize(fullName), options);
11401    },
11402
11403    /**
11404     A depth first traversal, destroying the container, its descendant containers and all
11405     their managed objects.
11406      @private
11407     @method destroy
11408     */
11409    destroy: function () {
11410      eachDestroyable(this, function (item) {
11411        if (item.destroy) {
11412          item.destroy();
11413        }
11414      });
11415
11416      this.isDestroyed = true;
11417    },
11418
11419    /**
11420     Clear either the entire cache or just the cache for a particular key.
11421      @private
11422     @method reset
11423     @param {String} fullName optional key to reset; if missing, resets everything
11424     */
11425    reset: function (fullName) {
11426      if (arguments.length > 0) {
11427        resetMember(this, this.registry.normalize(fullName));
11428      } else {
11429        resetCache(this);
11430      }
11431    },
11432
11433    /**
11434     Returns an object that can be used to provide an owner to a
11435     manually created instance.
11436      @private
11437     @method ownerInjection
11438     @returns { Object }
11439    */
11440    ownerInjection: function () {
11441      var _ref;
11442
11443      return _ref = {}, _ref[_containerOwner.OWNER] = this.owner, _ref;
11444    }
11445  };
11446
11447  function isSingleton(container, fullName) {
11448    return container.registry.getOption(fullName, 'singleton') !== false;
11449  }
11450
11451  function lookup(container, fullName) {
11452    var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
11453
11454    if (options.source) {
11455      fullName = container.registry.expandLocalLookup(fullName, options);
11456
11457      // if expandLocalLookup returns falsey, we do not support local lookup
11458      if (!fullName) {
11459        return;
11460      }
11461    }
11462
11463    if (container.cache[fullName] !== undefined && options.singleton !== false) {
11464      return container.cache[fullName];
11465    }
11466
11467    var value = instantiate(container, fullName);
11468
11469    if (value === undefined) {
11470      return;
11471    }
11472
11473    if (isSingleton(container, fullName) && options.singleton !== false) {
11474      container.cache[fullName] = value;
11475    }
11476
11477    return value;
11478  }
11479
11480  function markInjectionsAsDynamic(injections) {
11481    injections._dynamic = true;
11482  }
11483
11484  function areInjectionsDynamic(injections) {
11485    return !!injections._dynamic;
11486  }
11487
11488  function buildInjections() /* container, ...injections */{
11489    var hash = {};
11490
11491    if (arguments.length > 1) {
11492      var container = arguments[0];
11493      var injections = [];
11494      var injection;
11495
11496      for (var i = 1, l = arguments.length; i < l; i++) {
11497        if (arguments[i]) {
11498          injections = injections.concat(arguments[i]);
11499        }
11500      }
11501
11502      container.registry.validateInjections(injections);
11503
11504      for (i = 0, l = injections.length; i < l; i++) {
11505        injection = injections[i];
11506        hash[injection.property] = lookup(container, injection.fullName);
11507        if (!isSingleton(container, injection.fullName)) {
11508          markInjectionsAsDynamic(hash);
11509        }
11510      }
11511    }
11512
11513    return hash;
11514  }
11515
11516  function factoryFor(container, fullName) {
11517    var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
11518
11519    var registry = container.registry;
11520
11521    if (options.source) {
11522      fullName = registry.expandLocalLookup(fullName, options);
11523
11524      // if expandLocalLookup returns falsey, we do not support local lookup
11525      if (!fullName) {
11526        return;
11527      }
11528    }
11529
11530    var cache = container.factoryCache;
11531    if (cache[fullName]) {
11532      return cache[fullName];
11533    }
11534    var factory = registry.resolve(fullName);
11535    if (factory === undefined) {
11536      return;
11537    }
11538
11539    var type = fullName.split(':')[0];
11540    if (!factory || typeof factory.extend !== 'function' || !_emberMetalCore.default.MODEL_FACTORY_INJECTIONS && type === 'model') {
11541      if (factory && typeof factory._onLookup === 'function') {
11542        factory._onLookup(fullName);
11543      }
11544
11545      // TODO: think about a 'safe' merge style extension
11546      // for now just fallback to create time injection
11547      cache[fullName] = factory;
11548      return factory;
11549    } else {
11550      var injections = injectionsFor(container, fullName);
11551      var factoryInjections = factoryInjectionsFor(container, fullName);
11552      var cacheable = !areInjectionsDynamic(injections) && !areInjectionsDynamic(factoryInjections);
11553
11554      factoryInjections._toString = registry.makeToString(factory, fullName);
11555
11556      var injectedFactory = factory.extend(injections);
11557
11558      // TODO - remove all `container` injections when Ember reaches v3.0.0
11559
11560      injectDeprecatedContainer(injectedFactory.prototype, container);
11561
11562      injectedFactory.reopenClass(factoryInjections);
11563
11564      if (factory && typeof factory._onLookup === 'function') {
11565        factory._onLookup(fullName);
11566      }
11567
11568      if (cacheable) {
11569        cache[fullName] = injectedFactory;
11570      }
11571
11572      return injectedFactory;
11573    }
11574  }
11575
11576  function injectionsFor(container, fullName) {
11577    var registry = container.registry;
11578    var splitName = fullName.split(':');
11579    var type = splitName[0];
11580
11581    var injections = buildInjections(container, registry.getTypeInjections(type), registry.getInjections(fullName));
11582    injections._debugContainerKey = fullName;
11583
11584    _containerOwner.setOwner(injections, container.owner);
11585
11586    return injections;
11587  }
11588
11589  function factoryInjectionsFor(container, fullName) {
11590    var registry = container.registry;
11591    var splitName = fullName.split(':');
11592    var type = splitName[0];
11593
11594    var factoryInjections = buildInjections(container, registry.getFactoryTypeInjections(type), registry.getFactoryInjections(fullName));
11595    factoryInjections._debugContainerKey = fullName;
11596
11597    return factoryInjections;
11598  }
11599
11600  function instantiate(container, fullName) {
11601    var factory = factoryFor(container, fullName);
11602    var lazyInjections, validationCache;
11603
11604    if (container.registry.getOption(fullName, 'instantiate') === false) {
11605      return factory;
11606    }
11607
11608    if (factory) {
11609      if (typeof factory.create !== 'function') {
11610        throw new Error('Failed to create an instance of \'' + fullName + '\'. ' + 'Most likely an improperly defined class or an invali
11610d module export.');
11611      }
11612
11613      validationCache = container.validationCache;
11614
11615      // Ensure that all lazy injections are valid at instantiation time
11616      if (!validationCache[fullName] && typeof factory._lazyInjections === 'function') {
11617        lazyInjections = factory._lazyInjections();
11618        lazyInjections = container.registry.normalizeInjectionsHash(lazyInjections);
11619
11620        container.registry.validateInjections(lazyInjections);
11621      }
11622
11623      validationCache[fullName] = true;
11624
11625      var obj = undefined;
11626
11627      if (typeof factory.extend === 'function') {
11628        // assume the factory was extendable and is already injected
11629        obj = factory.create();
11630      } else {
11631        // assume the factory was extendable
11632        // to create time injections
11633        // TODO: support new'ing for instantiation and merge injections for pure JS Functions
11634        var injections = injectionsFor(container, fullName);
11635
11636        // Ensure that a container is available to an object during instantiation.
11637        // TODO - remove when Ember reaches v3.0.0
11638
11639        // This "fake" container will be replaced after instantiation with a
11640        // property that raises deprecations every time it is accessed.
11641        injections.container = container._fakeContainerToInject;
11642
11643        obj = factory.create(injections);
11644
11645        // TODO - remove when Ember reaches v3.0.0
11646
11647        if (!Object.isFrozen(obj) && 'container' in obj) {
11648          injectDeprecatedContainer(obj, container);
11649        }
11650      }
11651
11652      return obj;
11653    }
11654  }
11655
11656  // TODO - remove when Ember reaches v3.0.0
11657  function injectDeprecatedContainer(object, container) {
11658    Object.defineProperty(object, 'container', {
11659      configurable: true,
11660      enumerable: false,
11661      get: function () {
11662        _emberMetalDebug.deprecate('Using the injected `container` is deprecated. Please use the `getOwner` helper instead to access the owner of this object.', false, { id: 'ember-application.injected-container', until: '3.0.0', url: 'http://emberjs.com/deprecations/v2.x#toc_injected-container-access' });
11663        return this[CONTAINER_OVERRIDE] || container;
11664      },
11665
11666      set: function (value) {
11667        _emberMetalDebug.deprecate('Providing the `container` property to ' + this + ' is deprecated. Please use `Ember.setOwner` or `owner.ownerInjection()` instead to provide an owner to the instance being created.', false, { id: 'ember-application.injected-container', until: '3.0.0', url: 'http://emberjs.com/deprecations/v2.x#toc_injected-container-access' });
11668
11669        this[CONTAINER_OVERRIDE] = value;
11670
11671        return value;
11672      }
11673    });
11674  }
11675
11676  function eachDestroyable(container, callback) {
11677    var cache = container.cache;
11678    var keys = Object.keys(cache);
11679    var key, value;
11680
11681    for (var i = 0, l = keys.length; i < l; i++) {
11682      key = keys[i];
11683      value = cache[key];
11684
11685      if (container.registry.getOption(key, 'instantiate') !== false) {
11686        callback(value);
11687      }
11688    }
11689  }
11690
11691  function resetCache(container) {
11692    eachDestroyable(container, function (value) {
11693      if (value.destroy) {
11694        value.destroy();
11695      }
11696    });
11697
11698    container.cache.dict = _emberMetalDictionary.default(null);
11699  }
11700
11701  function resetMember(container, fullName) {
11702    var member = container.cache[fullName];
11703
11704    delete container.factoryCache[fullName];
11705
11706    if (member) {
11707      delete container.cache[fullName];
11708
11709      if (member.destroy) {
11710        member.destroy();
11711      }
11712    }
11713  }
11714
11715  exports.default = Container;
11716});
11717enifed('container/index', ['exports', 'ember-metal/core', 'container/registry', 'container/container', 'container/owner'], function (exports, _emberMetalCore, _containerRegistry, _containerContainer, _containerOwner) {
11718  'use strict';
11719
11720  /*
11721  Public API for the container is still in flux.
11722  The public API, specified on the application namespace should be considered the stable API.
11723  // @module container
11724    @private
11725  */
11726
11727  /*
11728   Flag to enable/disable model factory injections (disabled by default).
11729   If model factory injections are enabled, models should not be
11730   accessed globally (only through `container.lookupFactory('model:modelName'))`);
11731  */
11732  _emberMetalCore.default.MODEL_FACTORY_INJECTIONS = false;
11733
11734  if (_emberMetalCore.default.ENV && typeof _emberMetalCore.default.ENV.MODEL_FACTORY_INJECTIONS !== 'undefined') {
11735    _emberMetalCore.default.MODEL_FACTORY_INJECTIONS = !!_emberMetalCore.default.ENV.MODEL_FACTORY_INJECTIONS;
11736  }
11737
11738  exports.Registry = _containerRegistry.default;
11739  exports.Container = _containerContainer.default;
11740  exports.getOwner = _containerOwner.getOwner;
11741  exports.setOwner = _containerOwner.setOwner;
11742});
11743enifed('container/owner', ['exports', 'ember-metal/symbol'], function (exports, _emberMetalSymbol) {
11744  /**
11745  @module ember
11746  @submodule ember-runtime
11747  */
11748
11749  'use strict';
11750
11751  exports.getOwner = getOwner;
11752  exports.setOwner = setOwner;
11753  var OWNER = _emberMetalSymbol.default('OWNER');
11754
11755  exports.OWNER = OWNER;
11756  /**
11757    Framework objects in an Ember application (components, services, routes, etc.)
11758    are created via a factory and dependency injection system. Each of these
11759    objects is the responsibility of an "owner", which handled its
11760    instantiation and manages its lifetime.
11761  
11762    `getOwner` fetches the owner object responsible for an instance. This can
11763    be used to lookup or resolve other class instances, or register new factories
11764    into the owner.
11765  
11766    For example, this component dynamically looks up a service based on the
11767    `audioType` passed as an attribute:
11768  
11769    ```
11770    
11770// app/components/play-audio.js
11771    import Ember from 'ember';
11772  
11773    // Usage:
11774    //
11775    //   {{play-audio audioType=model.audioType audioFile=model.file}}
11776    //
11777    export default Ember.Component.extend({
11778      audioService: Ember.computed('audioType', function() {
11779        let owner = Ember.getOwner(this);
11780        return owner.lookup(`service:${this.get('audioType')}`);
11781      }),
11782      click() {
11783        let player = this.get('audioService');
11784        player.play(this.get('audioFile'));
11785      }
11786    });
11787    ```
11788  
11789    @method getOwner
11790    @param {Object} object An object with an owner.
11791    @return {Object} An owner object.
11792    @for Ember
11793    @public
11794  */
11795
11796  function getOwner(object) {
11797    return object[OWNER];
11798  }
11799
11800  /**
11801    `setOwner` forces a new owner on a given object instance. This is primarily
11802    useful in some testing cases.
11803  
11804    @method setOwner
11805    @param {Object} object An object with an owner.
11806    @return {Object} An owner object.
11807    @for Ember
11808    @public
11809  */
11810
11811  function setOwner(object, owner) {
11812    object[OWNER] = owner;
11813  }
11814});
11815enifed('container/registry', ['exports', 'ember-metal/features', 'ember-metal/debug', 'ember-metal/dictionary', 'ember-metal/empty_object', 'ember-metal/assign', 'container/container'], function (exports, _emberMetalFeatures, _emberMetalDebug, _emberMetalDictionary, _emberMetalEmpty_object, _emberMetalAssign, _containerContainer) {
11816  'use strict';
11817
11818  var VALID_FULL_NAME_REGEXP = /^[^:]+.+:[^:]+$/;
11819
11820  /**
11821   A registry used to store factory and option information keyed
11822   by type.
11823  
11824   A `Registry` stores the factory and option information needed by a
11825   `Container` to instantiate and cache objects.
11826  
11827   The API for `Registry` is still in flux and should not be considered stable.
11828  
11829   @private
11830   @class Registry
11831   @since 1.11.0
11832  */
11833  function Registry(options) {
11834    this.fallback = options && options.fallback ? options.fallback : null;
11835
11836    if (options && options.resolver) {
11837      this.resolver = options.resolver;
11838
11839      if (typeof this.resolver === 'function') {
11840        deprecateResolverFunction(this);
11841      }
11842    }
11843
11844    this.registrations = _emberMetalDictionary.default(options && options.registrations ? options.registrations : null);
11845
11846    this._typeInjections = _emberMetalDictionary.default(null);
11847    this._injections = _emberMetalDictionary.default(null);
11848    this._factoryTypeInjections = _emberMetalDictionary.default(null);
11849    this._factoryInjections = _emberMetalDictionary.default(null);
11850
11851    this._localLookupCache = new _emberMetalEmpty_object.default();
11852    this._normalizeCache = _emberMetalDictionary.default(null);
11853    this._resolveCache = _emberMetalDictionary.default(null);
11854    this._failCache = _emberMetalDictionary.default(null);
11855
11856    this._options = _emberMetalDictionary.default(null);
11857    this._typeOptions = _emberMetalDictionary.default(null);
11858  }
11859
11860  Registry.prototype = {
11861    /**
11862     A backup registry for resolving registrations when no matches can be found.
11863      @private
11864     @property fallback
11865     @type Registry
11866     */
11867    fallback: null,
11868
11869    /**
11870     An object that has a `resolve` method that resolves a name.
11871      @private
11872     @property resolver
11873     @type Resolver
11874     */
11875    resolver: null,
11876
11877    /**
11878     @private
11879     @property registrations
11880     @type InheritingDict
11881     */
11882    registrations: null,
11883
11884    /**
11885     @private
11886      @property _typeInjections
11887     @type InheritingDict
11888     */
11889    _typeInjections: null,
11890
11891    /**
11892     @private
11893      @property _injections
11894     @type InheritingDict
11895     */
11896    _injections: null,
11897
11898    /**
11899     @private
11900      @property _factoryTypeInjections
11901     @type InheritingDict
11902     */
11903    _factoryTypeInjections: null,
11904
11905    /**
11906     @private
11907      @property _factoryInjections
11908     @type InheritingDict
11909     */
11910    _factoryInjections: null,
11911
11912    /**
11913     @private
11914      @property _normalizeCache
11915     @type InheritingDict
11916     */
11917    _normalizeCache: null,
11918
11919    /**
11920     @private
11921      @property _resolveCache
11922     @type InheritingDict
11923     */
11924    _resolveCache: null,
11925
11926    /**
11927     @private
11928      @property _options
11929     @type InheritingDict
11930     */
11931    _options: null,
11932
11933    /**
11934     @private
11935      @property _typeOptions
11936     @type InheritingDict
11937     */
11938    _typeOptions: null,
11939
11940    /**
11941     Creates a container based on this registry.
11942      @private
11943     @method container
11944     @param {Object} options
11945     @return {Container} created container
11946     */
11947    container: function (options) {
11948      return new _containerContainer.default(this, options);
11949    },
11950
11951    /**
11952     Registers a factory for later injection.
11953      Example:
11954      ```javascript
11955     var registry = new Registry();
11956      registry.register('model:user', Person, {singleton: false });
11957     registry.register('fruit:favorite', Orange);
11958     registry.register('communication:main', Email, {singleton: false});
11959     ```
11960      @private
11961     @method register
11962     @param {String} fullName
11963     @param {Function} factory
11964     @param {Object} options
11965     */
11966    register: function (fullName, factory) {
11967      var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
11968
11969      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
11970
11971      if (factory === undefined) {
11972        throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
11973      }
11974
11975      var normalizedName = this.normalize(fullName);
11976
11977      if (this._resolveCache[normalizedName]) {
11978        throw new Error('Cannot re-register: `' + fullName + '`, as it has already been resolved.');
11979      }
11980
11981      delete this._failCache[normalizedName];
11982      this.registrations[normalizedName] = factory;
11983      this._options[normalizedName] = options;
11984    },
11985
11986    /**
11987     Unregister a fullName
11988      ```javascript
11989     var registry = new Registry();
11990     registry.register('model:user', User);
11991      registry.resolve('model:user').create() instanceof User //=> true
11992      registry.unregister('model:user')
11993     registry.resolve('model:user') === undefined //=> true
11994     ```
11995      @private
11996     @method unregister
11997     @param {String} fullName
11998     */
11999    unregister: function (fullName) {
12000      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
12001
12002      var normalizedName = this.normalize(fullName);
12003
12004      this._localLookupCache = new _emberMetalEmpty_object.default();
12005
12006      delete this.registrations[normalizedName];
12007      delete this._resolveCache[normalizedName];
12008      delete this._failCache[normalizedName];
12009      delete this._options[normalizedName];
12010    },
12011
12012    /**
12013     Given a fullName return the corresponding factory.
12014      By default `resolve` will retrieve the factory from
12015     the registry.
12016      ```javascript
12017     var registry = new Registry();
12018     registry.register('api:twitter', Twitter);
12019      registry.resolve('api:twitter') // => Twitter
12020     ```
12021      Optionally the registry can be provided with a custom resolver.
12022     If provided, `resolve` will first provide the custom resolver
12023     the opportunity to resolve the fullName, otherwise it will fallback
12024     to the registry.
12025      ```javascript
12026     var registry = new Registry();
12027     registry.resolver = function(fullName) {
12028        // lookup via the module system of choice
12029      };
12030      // the twitter factory is added to the module system
12031     registry.resolve('api:twitter') // => Twitter
12032     ```
12033      @private
12034     @method resolve
12035     @param {String} fullName
12036     @param {Object} [options]
12037     @param {String} [options.source] the fullname of the request source (used for local lookups)
12038     @return {Function} fullName's factory
12039     */
12040    resolve: function (fullName, options) {
12041      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
12042      var factory = resolve(this, this.normalize(fullName), options);
12043      if (factory === undefined && this.fallback) {
12044        var _fallback;
12045
12046        factory = (_fallback = this.fallback).resolve.apply(_fallback, arguments);
12047      }
12048      return factory;
12049    },
12050
12051    /**
12052     A hook that can be used to describe how the resolver will
12053     attempt to find the factory.
12054      For example, the default Ember `.describe` returns the full
12055     class name (including namespace) where Ember's resolver expects
12056     to find the `fullName`.
12057      @private
12058     @method describe
12059     @param {String} fullName
12060     @return {string} described fullName
12061     */
12062    describe: function (fullName) {
12063      if (this.resolver && this.resolver.lookupDescription) {
12064        return this.resolver.lookupDescription(fullName);
12065      } else if (this.fallback) {
12066        return this.fallback.describe(fullName);
12067      } else {
12068        return fullName;
12069      }
12070    },
12071
12072    /**
12073     A hook to enable custom fullName normalization behaviour
12074      @private
12075     @method normalizeFullName
12076     @param {String} fullName
12077     @return {string} normalized fullName
12078     */
12079    normalizeFullName: function (fullName) {
12080      if (this.resolver && this.resolver.normalize) {
12081        return this.resolver.normalize(fullName);
12082      } else if (this.fallback) {
12083        return this.fallback.normalizeFullName(fullName);
12084      } else {
12085        return fullName;
12086      }
12087    },
12088
12089    /**
12090     Normalize a fullName based on the application's conventions
12091      @private
12092     @method normalize
12093     @param {String} fullName
12094     @return {string} normalized fullName
12095     */
12096    normalize: function (fullName) {
12097      return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this.normalizeFullName(fullName));
12098    },
12099
12100    /**
12101     @method makeToString
12102      @private
12103     @param {any} factory
12104     @param {string} fullName
12105     @return {function} toString function
12106     */
12107    makeToString: function (factory, fullName) {
12108      if (this.resolver && this.resolver.makeToString) {
12109        return this.resolver.makeToString(factory, fullName);
12110      } else if (this.fallback) {
12111        return this.fallback.makeToString(factory, fullName);
12112      } else {
12113        return factory.toString();
12114      }
12115    },
12116
12117    /**
12118     Given a fullName check if the container is aware of its factory
12119     or singleton instance.
12120      @private
12121     @method has
12122     @param {String} fullName
12123     @param {Object} [options]
12124     @param {String} [options.source] the fullname of the request source (used for local lookups)
12125     @return {Boolean}
12126     */
12127    has: function (fullName, options) {
12128      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
12129
12130      var source = undefined;
12131
12132      source = options && options.source && this.normalize(options.source);
12133
12134      return has(this, this.normalize(fullName), source);
12135    },
12136
12137    /**
12138     Allow registering options for all factories of a type.
12139      ```javascript
12140     var registry = new Registry();
12141     var container = registry.container();
12142      // if all of type `connection` must not be singletons
12143     registry.optionsForType('connection', { singleton: false });
12144      registry.register('connection:twitter', TwitterConnection);
12145     registry.register('connection:facebook', FacebookConnection);
12146      var twitter = container.lookup('connection:twitter');
12147     var twitter2 = container.lookup('connection:twitter');
12148      twitter === twitter2; // => false
12149      var facebook = container.lookup('connection:facebook');
12150     var facebook2 = container.lookup('connection:facebook');
12151      facebook === facebook2; // => false
12152     ```
12153      @private
12154     @method optionsForType
12155     @param {String} type
12156     @param {Object} options
12157     */
12158    optionsForType: function (type, options) {
12159      this._typeOptions[type] = options;
12160    },
12161
12162    getOptionsForType: function (type) {
12163      var optionsForType = this._typeOptions[type];
12164      if (optionsForType === undefined && this.fallback) {
12165        optionsForType = this.fallback.getOptionsForType(type);
12166      }
12167      return optionsForType;
12168    },
12169
12170    /**
12171     @private
12172     @method options
12173     @param {String} fullName
12174     @param {Object} options
12175     */
12176    options: function (fullName) {
12177      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
12178
12179      var normalizedName = this.normalize(fullName);
12180      this._options[normalizedName] = options;
12181    },
12182
12183    getOptions: function (fullName) {
12184      var normalizedName = this.normalize(fullName);
12185      var options = this._options[normalizedName];
12186      if (options === undefined && this.fallback) {
12187        options = this.fallback.getOptions(fullName);
12188      }
12189      return options;
12190    },
12191
12192    getOption: function (fullName, optionName) {
12193      var options = this._options[fullName];
12194
12195      if (options && options[optionName] !== undefined) {
12196        return options[optionName];
12197      }
12198
12199      var type = fullName.split(':')[0];
12200      options = this._typeOptions[type];
12201
12202      if (options && options[optionName] !== undefined) {
12203        return options[optionName];
12204      } else if (this.fallback) {
12205        return this.fallback.getOption(fullName, optionName);
12206      }
12207    },
12208
12209    /**
12210     Used only via `injection`.
12211      Provides a specialized form of injection, specifically enabling
12212     all objects of one type to be injected with a reference to another
12213     object.
12214      For example, provided each object of type `controller` needed a `router`.
12215     one would do the following:
12216      ```javascript
12217     var registry = new Registry();
12218     var container = registry.container();
12219      registry.register('router:main', Router);
12220     registry.register('controller:user', UserController);
12221     registry.register('controller:post', PostController);
12222      registry.typeInjection('controller', 'router', 'router:main');
12223      var user = container.lookup('controller:user');
12224     var post = container.lookup('controller:post');
12225      user.router instanceof Router; //=> true
12226     post.router instanceof Router; //=> true
12227      // both controllers share the same router
12228     user.router === post.router; //=> true
12229     ```
12230      @private
12231     @method typeInjection
12232     @param {String} type
12233     @param {String} property
12234     @param {String} fullName
12235     */
12236    typeInjection: function (type, property, fullName) {
12237      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
12238
12239      var fullNameType = fullName.split(':')[0];
12240      if (fullNameType === type) {
12241        throw new Error('Cannot inject a `' + fullName + '` on other ' + type + '(s).');
12242      }
12243
12244      var injections = this._typeInjections[type] || (this._typeInjections[type] = []);
12245
12246      injections.push({
12247        property: property,
12248        fullName: fullName
12249      });
12250    },
12251
12252    /**
12253     Defines injection rules.
12254      These rules are used to inject dependencies onto objects when they
12255     are instantiated.
12256      Two forms of injections are possible:
12257      * Injecting one fullName on another fullName
12258     * Injecting one fullName on a type
12259      Example:
12260      ```javascript
12261     var registry = new Registry();
12262     var container = registry.container();
12263      registry.register('source:main', Source);
12264     registry.register('model:user', User);
12265     registry.register('model:post', Post);
12266      // injecting one fullName on another fullName
12267     // eg. each user model gets a post model
12268     registry.injection('model:user', 'post', 'model:post');
12269      // injecting one fullName on another type
12270     registry.injection('model', 'source', 'source:main');
12271      var user = container.lookup('model:user');
12272     var post = container.lookup('model:post');
12273      user.source instanceof Source; //=> true
12274     post.source instanceof Source; //=> true
12275      user.post instanceof Post; //=> true
12276      // and both models share the same source
12277     user.source === post.source; //=> true
12278     ```
12279      @private
12280     @method injection
12281     @param {String} factoryName
12282     @param {String} property
12283     @param {String} injectionName
12284     */
12285    injection: function (fullName, property, injectionName) {
12286      this.validateFullName(injectionName);
12287      var normalizedInjectionName = this.normalize(injectionName);
12288
12289      if (fullName.indexOf(':') === -1) {
12290        return this.typeInjection(fullName, property, normalizedInjectionName);
12291      }
12292
12293      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
12294      var normalizedName = this.normalize(fullName);
12295
12296      var injections = this._injections[normalizedName] || (this._injections[normalizedName] = []);
12297
12298      injections.push({
12299        property: property,
12300        fullName: normalizedInjectionName
12301      });
12302    },
12303
12304    /**
12305     Used only via `factoryInjection`.
12306      Provides a specialized form of injection, specifically enabling
12307     all factory of one type to be injected with a reference to another
12308     object.
12309      For example, provided each factory of type `model` needed a `store`.
12310     one would do the following:
12311      ```javascript
12312     var registry = new Registry();
12313      registry.register('store:main', SomeStore);
12314      registry.factoryTypeInjection('model', 'store', 'store:main');
12315      var store = registry.lookup('store:main');
12316     var UserFactory = registry.lookupFactory('model:user');
12317      UserFactory.store instanceof SomeStore; //=> true
12318     ```
12319      @private
12320     @method factoryTypeInjection
12321     @param {String} type
12322     @param {String} property
12323     @param {String} fullName
12324     */
12325    factoryTypeInjection: function (type, property, fullName) {
12326      var injections = this._factoryTypeInjections[type] || (this._factoryTypeInjections[type] = []);
12327
12328      injections.push({
12329        property: property,
12330        fullName: this.normalize(fullName)
12331      });
12332    },
12333
12334    /**
12335     Defines factory injection rules.
12336      Similar to regular injection rules, but are run against factories, via
12337     `Registry#lookupFactory`.
12338      These rules are used to inject objects onto factories when they
12339     are looked up.
12340      Two forms of injections are possible:
12341      * Injecting one fullName on another fullName
12342     * Injecting one fullName on a type
12343      Example:
12344      ```javascript
12345     var registry = new Registry();
12346     var container = registry.container();
12347      registry.register('store:main', Store);
12348     registry.register('store:secondary', OtherStore);
12349     registry.register('model:user', User);
12350     registry.register('model:post', Post);
12351      // injecting one fullName on another type
12352     registry.factoryInjection('model', 'store', 'store:main');
12353      // injecting one fullName on another fullName
12354     registry.factoryInjection('model:post', 'secondaryStore', 'store:secondary');
12355      var UserFactory = container.lookupFactory('model:user');
12356     var PostFactory = container.lookupFactory('model:post');
12357     var store = container.lookup('store:main');
12358      UserFactory.store instanceof Store; //=> true
12359     UserFactory.secondaryStore instanceof OtherStore; //=> false
12360      PostFactory.store instanceof Store; //=> true
12361     PostFactory.secondaryStore instanceof OtherStore; //=> true
12362      // and both models share the same source instance
12363     UserFactory.store === PostFactory.store; //=> true
12364     ```
12365      @private
12366     @method factoryInjection
12367     @param {String} factoryName
12368     @param {String} property
12369     @param {String} injectionName
12370     */
12371    factoryInjection: function (fullName, property, injectionName) {
12372      var normalizedName = this.normalize(fullName);
12373      var normalizedInjectionName = this.normalize(injectionName);
12374
12375      this.validateFullName(injectionName);
12376
12377      if (fullName.indexOf(':') === -1) {
12378        return this.factoryTypeInjection(normalizedName, property, normalizedInjectionName);
12379      }
12380
12381      var injections = this._factoryInjections[normalizedName] || (this._factoryInjections[normalizedName] = []);
12382
12383      injections.push({
12384        property: property,
12385        fullName: normalizedInjectionName
12386      });
12387    },
12388
12389    /**
12390     @private
12391     @method knownForType
12392     @param {String} type the type to iterate over
12393    */
12394    knownForType: function (type) {
12395      var fallbackKnown = undefined,
12396          resolverKnown = undefined;
12397
12398      var localKnown = _emberMetalDictionary.default(null);
12399      var registeredNames = Object.keys(this.registrations);
12400      for (var index = 0, _length = registeredNames.length; index < _length; index++) {
12401        var fullName = registeredNames[index];
12402        var itemType = fullName.split(':')[0];
12403
12404        if (itemType === type) {
12405          localKnown[fullName] = true;
12406        }
12407      }
12408
12409      if (this.fallback) {
12410        fallbackKnown = this.fallback.knownForType(type);
12411      }
12412
12413      if (this.resolver && this.resolver.knownForType) {
12414        resolverKnown = this.resolver.knownForType(type);
12415      }
12416
12417      return _emberMetalAssign.default({}, fallbackKnown, localKnown, resolverKnown);
12418    },
12419
12420    validateFullName: function (fullName) {
12421      if (!VALID_FULL_NAME_REGEXP.test(fullName)) {
12422        throw new TypeError('Invalid Fullname, expected: `type:name` got: ' + fullName);
12423      }
12424      return true;
12425    },
12426
12427    validateInjections: function (injections) {
12428      if (!injections) {
12429        return;
12430      }
12431
12432      var fullName;
12433
12434      for (var i = 0, length = injections.length; i < length; i++) {
12435        fullName = injections[i].fullName;
12436
12437        if (!this.has(fullName)) {
12438          throw new Error('Attempting to inject an unknown injection: `' + fullName + '`');
12439        }
12440      }
12441    },
12442
12443    normalizeInjectionsHash: function (hash) {
12444      var injections = [];
12445
12446      for (var key in hash) {
12447        if (hash.hasOwnProperty(key)) {
12448          _emberMetalDebug.assert('Expected a proper full name, given \'' + hash[key] + '\'', this.validateFullName(hash[key]));
12449
12450          injections.push({
12451            property: key,
12452            fullName: hash[key]
12453          });
12454        }
12455      }
12456
12457      return injections;
12458    },
12459
12460    getInjections: function (fullName) {
12461      var injections = this._injections[fullName] || [];
12462      if (this.fallback) {
12463        injections = injections.concat(this.fallback.getInjections(fullName));
12464      }
12465      return injections;
12466    },
12467
12468    getTypeInjections: function (type) {
12469      var injections = this._typeInjections[type] || [];
12470      if (this.fallback) {
12471        injections = injections.concat(this.fallback.getTypeInjections(type));
12472      }
12473      return injections;
12474    },
12475
12476    getFactoryInjections: function (fullName) {
12477      var injections = this._factoryInjections[fullName] || [];
12478      if (this.fallback) {
12479        injections = injections.concat(this.fallback.getFactoryInjections(fullName));
12480      }
12481      return injections;
12482    },
12483
12484    getFactoryTypeInjections: function (type) {
12485      var injections = this._factoryTypeInjections[type] || [];
12486      if (this.fallback) {
12487        injections = injections.concat(this.fallback.getFactoryTypeInjections(type));
12488      }
12489      return injections;
12490    }
12491  };
12492
12493  function deprecateResolverFunction(registry) {
12494    _emberMetalDebug.deprecate('Passing a `resolver` function into a Registry is deprecated. Please pass in a Resolver object with a `resolve` method.', false, { id: 'ember-application.registry-resolver-as-function', until: '3.0.0', url: 'http://emberjs.com/deprecations/v2.x#toc_registry-resolver-as-function' });
12495    registry.resolver = {
12496      resolve: registry.resolver
12497    };
12498  }
12499
12500  /**
12501    Given a fullName and a source fullName returns the fully resolved
12502    fullName. Used to allow for local lookup.
12503     ```javascript
12504    var registry = new Registry();
12505     // the twitter factory is added to the module system
12506    registry.expandLocalLookup('component:post-title', { source: 'template:post' }) // => component:post/post-title
12507    ```
12508     @private
12509    @method expandLocalLookup
12510    @param {String} fullName
12511    @param {Object} [options]
12512    @param {String} [options.source] the fullname of the request source (used for local lookups)
12513    @return {String} fullName
12514  */
12515  Registry.prototype.expandLocalLookup = function Registry_expandLocalLookup(fullName, options) {
12516    if (this.resolver && this.resolver.expandLocalLookup) {
12517      _emberMetalDebug.assert('fullName must be a proper full name', this.validateFullName(fullName));
12518      _emberMetalDebug.assert('options.source must be provided to expandLocalLookup', options && options.source);
12519      _emberMetalDebug.assert('options.source must be a proper full name', this.validateFullName(options.source));
12520
12521      var normalizedFullName = this.normalize(fullName);
12522      var normalizedSource = this.normalize(options.source);
12523
12524      return expandLocalLookup(this, normalizedFullName, normalizedSource);
12525    } else if (this.fallback) {
12526      return this.fallback.expandLocalLookup(fullName, options);
12527    } else {
12528      return null;
12529    }
12530  };
12531
12532  function expandLocalLookup(registry, normalizedName, normalizedSource) {
12533    var cache = registry._localLookupCache;
12534    var normalizedNameCache = cache[normalizedName];
12535
12536    if (!normalizedNameCache) {
12537      normalizedNameCache = cache[normalizedName] = new _emberMetalEmpty_object.default();
12538    }
12539
12540    var cached = normalizedNameCache[normalizedSource];
12541
12542    if (cached !== undefined) {
12543      return cached;
12544    }
12545
12546    var expanded = registry.resolver.expandLocalLookup(normalizedName, normalizedSource);
12547
12548    return normalizedNameCache[normalizedSource] = expanded;
12549  }
12550
12551  function resolve(registry, normalizedName, options) {
12552    if (options && options.source) {
12553      // when `source` is provided expand normalizedName
12554      // and source into the full normalizedName
12555      normalizedName = registry.expandLocalLookup(normalizedName, options);
12556
12557      // if expandLocalLookup returns falsey, we do not support local lookup
12558      if (!normalizedName) {
12559        return;
12560      }
12561    }
12562
12563    var cached = registry._resolveCache[normalizedName];
12564    if (cached !== undefined) {
12565      return cached;
12566    }
12567    if (registry._failCache[normalizedName]) {
12568      return;
12569    }
12570
12571    var resolved = undefined;
12572
12573    if (registry.resolver) {
12574      resolved = registry.resolver.resolve(normalizedName);
12575    }
12576
12577    if (resolved === undefined) {
12578      resolved = registry.registrations[normalizedName];
12579    }
12580
12581    if (resolved === undefined) {
12582      registry._failCache[normalizedName] = true;
12583    } else {
12584      registry._resolveCache[normalizedName] = resolved;
12585    }
12586
12587    return resolved;
12588  }
12589
12590  function has(registry, fullName, source) {
12591    return registry.resolve(fullName, { source: source }) !== undefined;
12592  }
12593
12594  exports.default = Registry;
12595});
12596enifed('dag-map/platform', ['exports'], function (exports) {
12597  'use strict';
12598
12599  var platform;
12600
12601  /* global self */
12602  if (typeof self === 'object') {
12603    platform = self;
12604
12605    /* global global */
12606  } else if (typeof global === 'object') {
12607      platform = global;
12608    } else {
12609      throw new Error('no global: `self` or `global` found');
12610    }
12611
12612  exports.default = platform;
12613});
12614enifed('dag-map', ['exports', 'vertex', 'visit'], function (exports, _vertex, _visit) {
12615  'use strict';
12616
12617  exports.default = DAG;
12618
12619  /**
12620   * DAG stands for Directed acyclic graph.
12621   *
12622   * It is used to build a graph of dependencies checking that there isn't circular
12623   * dependencies. p.e Registering initializers with a certain precedence order.
12624   *
12625   * @class DAG
12626   * @constructor
12627   */
12628
12629  function DAG() {
12630    this.names = [];
12631    this.vertices = Object.create(null);
12632  }
12633
12634  /**
12635   * Adds a vertex entry to the graph unless it is already added.
12636   *
12637   * @private
12638   * @method add
12639   * @param {String} name The name of the vertex to add
12640   */
12641  DAG.prototype.add = function (name) {
12642    if (!name) {
12643      throw new Error("Can't add Vertex without name");
12644    }
12645    if (this.vertices[name] !== undefined) {
12646      return this.vertices[name];
12647    }
12648    var vertex = new _vertex.default(name);
12649    this.vertices[name] = vertex;
12650    this.names.push(name);
12651    return vertex;
12652  };
12653
12654  /**
12655   * Adds a vertex to the graph and sets its value.
12656   *
12657   * @private
12658   * @method map
12659   * @param {String} name The name of the vertex.
12660   * @param         value The value to put in the vertex.
12661   */
12662  DAG.prototype.map = function (name, value) {
12663    this.add(name).value = value;
12664  };
12665
12666  /**
12667   * Connects the vertices with the given names, adding them to the graph if
12668   * necessary, only if this does not produce is any circular dependency.
12669   *
12670   * @private
12671   * @method addEdge
12672   * @param {String} fromName The name the vertex where the edge starts.
12673   * @param {String} toName The name the vertex where the edge ends.
12674   */
12675  DAG.prototype.addEdge = function (fromName, toName) {
12676    if (!fromName || !toName || fromName === toName) {
12677      return;
12678    }
12679    var from = this.add(fromName);
12680    var to = this.add(toName);
12681    if (to.incoming.hasOwnProperty(fromName)) {
12682      return;
12683    }
12684    function checkCycle(vertex, path) {
12685      if (vertex.name === toName) {
12686        throw new Error("cycle detected: " + toName + " <- " + path.join(" <- "));
12687      }
12688    }
12689    _visit.default(from, checkCycle);
12690    from.hasOutgoing = true;
12691    to.incoming[fromName] = from;
12692    to.incomingNames.push(fromName);
12693  };
12694
12695  /**
12696   * Visits all the vertex of the graph calling the given function with each one,
12697   * ensuring that the vertices are visited respecting their precedence.
12698   *
12699   * @method  topsort
12700   * @param {Function} fn The function to be invoked on each vertex.
12701   */
12702  DAG.prototype.topsort = function (fn) {
12703    var visited = {};
12704    var vertices = this.vertices;
12705    var names = this.names;
12706    var len = names.length;
12707    var i, vertex;
12708
12709    for (i = 0; i < len; i++) {
12710      vertex = vertices[names[i]];
12711      if (!vertex.hasOutgoing) {
12712        _visit.default(vertex, fn, visited);
12713      }
12714    }
12715  };
12716
12717  /**
12718   * Adds a vertex with the given name and value to the graph and joins it with the
12719   * vertices referenced in _before_ and _after_. If there isn't vertices with those
12720   * names, they are added too.
12721   *
12722   * If either _before_ or _after_ are falsy/empty, the added vertex will not have
12723   * an incoming/outgoing edge.
12724   *
12725   * @method addEdges
12726   * @param {String} name The name of the vertex to be added.
12727   * @param         value The value of that vertex.
12728   * @param        before An string or array of strings with the names of the vertices before
12729   *                      which this vertex must be visited.
12730   * @param         after An string or array of strings with the names of the vertex after
12731   *                      which this vertex must be visited.
12732   *
12733   */
12734  DAG.prototype.addEdges = function (name, value, before, after) {
12735    var i;
12736    this.map(name, value);
12737    if (before) {
12738      if (typeof before === 'string') {
12739        this.addEdge(name, before);
12740      } else {
12741        for (i = 0; i < before.length; i++) {
12742          this.addEdge(name, before[i]);
12743        }
12744      }
12745    }
12746    if (after) {
12747      if (typeof after === 'string') {
12748        this.addEdge(after, name);
12749      } else {
12750        for (i = 0; i < after.length; i++) {
12751          this.addEdge(after[i], name);
12752        }
12753      }
12754    }
12755  };
12756});
12757enifed('dag-map.umd', ['exports', 'dag-map/platform', 'dag-map'], function (exports, _dagMapPlatform, _dagMap) {
12758  'use strict';
12759
12760  /* global define:true module:true window: true */
12761  if (typeof define === 'function' && define.amd) {
12762    define(function () {
12763      return _dagMap.default;
12764    });
12765  } else if (typeof module !== 'undefined' && module.exports) {
12766    module.exports = _dagMap.default;
12767  } else if (typeof _dagMapPlatform.default !== 'undefined') {
12768    _dagMapPlatform.default['DAG'] = _dagMap.default;
12769  }
12770});
12771enifed('dom-helper/build-html-dom', ['exports'], function (exports) {
12772  /* global XMLSerializer:false */
12773  'use strict';
12774
12775  var svgHTMLIntegrationPoints = { foreignObject: 1, desc: 1, title: 1 };
12776  exports.svgHTMLIntegrationPoints = svgHTMLIntegrationPoints;
12777  var svgNamespace = 'http://www.w3.org/2000/svg';
12778
12779  exports.svgNamespace = svgNamespace;
12780  var doc = typeof document === 'undefined' ? false : document;
12781
12782  // Safari does not like using innerHTML on SVG HTML integration
12783  // points (desc/title/foreignObject).
12784  var needsIntegrationPointFix = doc && (function (document) {
12785    if (document.createElementNS === undefined) {
12786      return;
12787    }
12788    // In FF title will not accept innerHTML.
12789    var testEl = document.createElementNS(svgNamespace, 'title');
12790    testEl.innerHTML = "<div></div>";
12791    return testEl.childNodes.length === 0 || testEl.childNodes[0].nodeType !== 1;
12792  })(doc);
12793
12794  // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
12795  // is a "zero-scope" element. This problem can be worked around by making
12796  // the first node an invisible text node. We, like Modernizr, use &shy;
12797  var needsShy = doc && (function (document) {
12798    var testEl = document.createElement('div');
12799    testEl.innerHTML = "<div></div>";
12800    testEl.firstChild.innerHTML = "<script><\/script>";
12801    return testEl.firstChild.innerHTML === '';
12802  })(doc);
12803
12804  // IE 8 (and likely earlier) likes to move whitespace preceeding
12805  // a script tag to appear after it. This means that we can
12806  // accidentally remove whitespace when updating a morph.
12807  var movesWhitespace = doc && (function (document) {
12808    var testEl = document.createElement('div');
12809    testEl.innerHTML = "Test: <script type='text/x-placeholder'><\/script>Value";
12810    return testEl.childNodes[0].nodeValue === 'Test:' && testEl.childNodes[2].nodeValue === ' Value';
12811  })(doc);
12812
12813  var tagNamesRequiringInnerHTMLFix = doc && (function (document) {
12814    var tagNamesRequiringInnerHTMLFix;
12815    // IE 9 and earlier don't allow us to set innerHTML on col, colgroup, frameset,
12816    // html, style, table, tbody, tfoot, thead, title, tr. Detect this and add
12817    // them to an initial list of corrected tags.
12818    //
12819    // Here we are only dealing with the ones which can have child nodes.
12820    //
12821    var tableNeedsInnerHTMLFix;
12822    var tableInnerHTMLTestElement = document.createElement('table');
12823    try {
12824      tableInnerHTMLTestElement.innerHTML = '<tbody></tbody>';
12825    } catch (e) {} finally {
12826      tableNeedsInnerHTMLFix = tableInnerHTMLTestElement.childNodes.length === 0;
12827    }
12828    if (tableNeedsInnerHTMLFix) {
12829      tagNamesRequiringInnerHTMLFix = {
12830        colgroup: ['table'],
12831        table: [],
12832        tbody: ['table'],
12833        tfoot: ['table'],
12834        thead: ['table'],
12835        tr: ['table', 'tbody']
12836      };
12837    }
12838
12839    // IE 8 doesn't allow setting innerHTML on a select tag. Detect this and
12840    // add it to the list of corrected tags.
12841    //
12842    var selectInnerHTMLTestElement = document.createElement('select');
12843    selectInnerHTMLTestElement.innerHTML = '<option></option>';
12844    if (!selectInnerHTMLTestElement.childNodes[0]) {
12845      tagNamesRequiringInnerHTMLFix = tagNamesRequiringInnerHTMLFix || {};
12846      tagNamesRequiringInnerHTMLFix.select = [];
12847    }
12848    return tagNamesRequiringInnerHTMLFix;
12849  })(doc);
12850
12851  function scriptSafeInnerHTML(element, html) {
12852    // without a leading text node, IE will drop a leading script tag.
12853    html = '&shy;' + html;
12854
12855    element.innerHTML = html;
12856
12857    var nodes = element.childNodes;
12858
12859    // Look for &shy; to remove it.
12860    var shyElement = nodes[0];
12861    while (shyElement.nodeType === 1 && !shyElement.nodeName) {
12862      shyElement = shyElement.firstChild;
12863    }
12864    // At this point it's the actual unicode character.
12865    if (shyElement.nodeType === 3 && shyElement.nodeValue.charAt(0) === "\u00AD") {
12866      var newValue = shyElement.nodeValue.slice(1);
12867      if (newValue.length) {
12868        shyElement.nodeValue = shyElement.nodeValue.slice(1);
12869      } else {
12870        shyElement.parentNode.removeChild(shyElement);
12871      }
12872    }
12873
12874    return nodes;
12875  }
12876
12877  function buildDOMWithFix(html, contextualElement) {
12878    var tagName = contextualElement.tagName;
12879
12880    // Firefox versions < 11 do not have support for element.outerHTML.
12881    var outerHTML = contextualElement.outerHTML || new XMLSerializer().serializeToString(contextualElement);
12882    if (!outerHTML) {
12883      throw "Can't set innerHTML on " + tagName + " in this browser";
12884    }
12885
12886    html = fixSelect(html, contextualElement);
12887
12888    var wrappingTags = tagNamesRequiringInnerHTMLFix[tagName.toLowerCase()];
12889
12890    var startTag = outerHTML.match(new RegExp("<" + tagName + "([^>]*)>", 'i'))[0];
12891    var endTag = '</' + tagName + '>';
12892
12893    var wrappedHTML = [startTag, html, endTag];
12894
12895    var i = wrappingTags.length;
12896    var wrappedDepth = 1 + i;
12897    while (i--) {
12898      wrappedHTML.unshift('<' + wrappingTags[i] + '>');
12899      wrappedHTML.push('</' + wrappingTags[i] + '>');
12900    }
12901
12902    var wrapper = document.createElement('div');
12903    scriptSafeInnerHTML(wrapper, wrappedHTML.join(''));
12904    var element = wrapper;
12905    while (wrappedDepth--) {
12906      element = element.firstChild;
12907      while (element && element.nodeType !== 1) {
12908        element = element.nextSibling;
12909      }
12910    }
12911    while (element && element.tagName !== tagName) {
12912      element = element.nextSibling;
12913    }
12914    return element ? element.childNodes : [];
12915  }
12916
12917  var buildDOM;
12918  if (needsShy) {
12919    buildDOM = function buildDOM(html, contextualElement, dom) {
12920      html = fixSelect(html, contextualElement);
12921
12922      contextualElement = dom.cloneNode(contextualElement, false);
12923      scriptSafeInnerHTML(contextualElement, html);
12924      return contextualElement.childNodes;
12925    };
12926  } else {
12927    buildDOM = function buildDOM(html, contextualElement, dom) {
12928      html = fixSelect(html, contextualElement);
12929
12930      contextualElement = dom.cloneNode(contextualElement, false);
12931      contextualElement.innerHTML = html;
12932      return contextualElement.childNodes;
12933    };
12934  }
12935
12936  function fixSelect(html, contextualElement) {
12937    if (contextualElement.tagName === 'SELECT') {
12938      html = "<option></option>" + html;
12939    }
12940
12941    return html;
12942  }
12943
12944  var buildIESafeDOM;
12945  if (tagNamesRequiringInnerHTMLFix || movesWhitespace) {
12946    buildIESafeDOM = function buildIESafeDOM(html, contextualElement, dom) {
12947      // Make a list of the leading text on script nodes. Include
12948      // script tags without any whitespace for easier processing later.
12949      var spacesBefore = [];
12950      var spacesAfter = [];
12951      if (typeof html === 'string') {
12952        html = html.replace(/(\s*)(<script)/g, function (match, spaces, tag) {
12953          spacesBefore.push(spaces);
12954          return tag;
12955        });
12956
12957        html = html.replace(/(<\/script>)(\s*)/g, function (match, tag, spaces) {
12958          spacesAfter.push(spaces);
12959          return tag;
12960        });
12961      }
12962
12963      // Fetch nodes
12964      var nodes;
12965      if (tagNamesRequiringInnerHTMLFix[contextualElement.tagName.toLowerCase()]) {
12966        // buildDOMWithFix uses string wrappers for problematic innerHTML.
12967        nodes = buildDOMWithFix(html, contextualElement);
12968      } else {
12969        nodes = buildDOM(html, contextualElement, dom);
12970      }
12971
12972      // Build a list of script tags, the nodes themselves will be
12973      // mutated as we add test nodes.
12974      var i, j, node, nodeScriptNodes;
12975      var scriptNodes = [];
12976      for (i = 0; i < nodes.length; i++) {
12977        node = nodes[i];
12978        if (node.nodeType !== 1) {
12979          continue;
12980        }
12981        if (node.tagName === 'SCRIPT') {
12982          scriptNodes.push(node);
12983        } else {
12984          nodeScriptNodes = node.getElementsByTagName('script');
12985          for (j = 0; j < nodeScriptNodes.length; j++) {
12986            scriptNodes.push(nodeScriptNodes[j]);
12987          }
12988        }
12989      }
12990
12991      // Walk the script tags and put back their leading text nodes.
12992      var scriptNode, textNode, spaceBefore, spaceAfter;
12993      for (i = 0; i < scriptNodes.length; i++) {
12994        scriptNode = scriptNodes[i];
12995        spaceBefore = spacesBefore[i];
12996        if (spaceBefore && spaceBefore.length > 0) {
12997          textNode = dom.document.createTextNode(spaceBefore);
12998          scriptNode.parentNode.insertBefore(textNode, scriptNode);
12999        }
13000
13001        spaceAfter = spacesAfter[i];
13002        if (spaceAfter && spaceAfter.length > 0) {
13003          textNode = dom.document.createTextNode(spaceAfter);
13004          scriptNode.parentNode.insertBefore(textNode, scriptNode.nextSibling);
13005        }
13006      }
13007
13008      return nodes;
13009    };
13010  } else {
13011    buildIESafeDOM = buildDOM;
13012  }
13013
13014  var buildHTMLDOM;
13015  if (needsIntegrationPointFix) {
13016    exports.buildHTMLDOM = buildHTMLDOM = function buildHTMLDOM(html, contextualElement, dom) {
13017      if (svgHTMLIntegrationPoints[contextualElement.tagName]) {
13018        return buildIESafeDOM(html, document.createElement('div'), dom);
13019      } else {
13020        return buildIESafeDOM(html, contextualElement, dom);
13021      }
13022    };
13023  } else {
13024    exports.buildHTMLDOM = buildHTMLDOM = buildIESafeDOM;
13025  }
13026
13027  exports.buildHTMLDOM = buildHTMLDOM;
13028});
13029enifed('dom-helper/classes', ['exports'], function (exports) {
13030  'use strict';
13031
13032  var doc = typeof document === 'undefined' ? false : document;
13033
13034  // PhantomJS has a broken classList. See https://github.com/ariya/phantomjs/issues/12782
13035  var canClassList = doc && (function () {
13036    var d = document.createElement('div');
13037    if (!d.classList) {
13038      return false;
13039    }
13040    d.classList.add('boo');
13041    d.classList.add('boo', 'baz');
13042    return d.className === 'boo baz';
13043  })();
13044
13045  function buildClassList(element) {
13046    var classString = element.getAttribute('class') || '';
13047    return classString !== '' && classString !== ' ' ? classString.split(' ') : [];
13048  }
13049
13050  function intersect(containingArray, valuesArray) {
13051    var containingIndex = 0;
13052    var containingLength = containingArray.length;
13053    var valuesIndex = 0;
13054    var valuesLength = valuesArray.length;
13055
13056    var intersection = new Array(valuesLength);
13057
13058    // TODO: rewrite this loop in an optimal manner
13059    for (; containingIndex < containingLength; containingIndex++) {
13060      valuesIndex = 0;
13061      for (; valuesIndex < valuesLength; valuesIndex++) {
13062        if (valuesArray[valuesIndex] === containingArray[containingIndex]) {
13063          intersection[valuesIndex] = containingIndex;
13064          break;
13065        }
13066      }
13067    }
13068
13069    return intersection;
13070  }
13071
13072  function addClassesViaAttribute(element, classNames) {
13073    var existingClasses = buildClassList(element);
13074
13075    var indexes = intersect(existingClasses, classNames);
13076    var didChange = false;
13077
13078    for (var i = 0, l = classNames.length; i < l; i++) {
13079      if (indexes[i] === undefined) {
13080        didChange = true;
13081        existingClasses.push(classNames[i]);
13082      }
13083    }
13084
13085    if (didChange) {
13086      element.setAttribute('class', existingClasses.length > 0 ? existingClasses.join(' ') : '');
13087    }
13088  }
13089
13090  function removeClassesViaAttribute(element, classNames) {
13091    var existingClasses = buildClassList(element);
13092
13093    var indexes = intersect(classNames, existingClasses);
13094    var didChange = false;
13095    var newClasses = [];
13096
13097    for (var i = 0, l = existingClasses.length; i < l; i++) {
13098      if (indexes[i] === undefined) {
13099        newClasses.push(existingClasses[i]);
13100      } else {
13101        didChange = true;
13102      }
13103    }
13104
13105    if (didChange) {
13106      element.setAttribute('class', newClasses.length > 0 ? newClasses.join(' ') : '');
13107    }
13108  }
13109
13110  var addClasses, removeClasses;
13111  if (canClassList) {
13112    exports.addClasses = addClasses = function addClasses(element, classNames) {
13113      if (element.classList) {
13114        if (classNames.length === 1) {
13115          element.classList.add(classNames[0]);
13116        } else if (classNames.length === 2) {
13117          element.classList.add(classNames[0], classNames[1]);
13118        } else {
13119          element.classList.add.apply(element.classList, classNames);
13120        }
13121      } else {
13122        addClassesViaAttribute(element, classNames);
13123      }
13124    };
13125    exports.removeClasses = removeClasses = function removeClasses(element, classNames) {
13126      if (element.classList) {
13127        if (classNames.length === 1) {
13128          element.classList.remove(classNames[0]);
13129        } else if (classNames.length === 2) {
13130          element.classList.remove(classNames[0], classNames[1]);
13131        } else {
13132          element.classList.remove.apply(element.classList, classNames);
13133        }
13134      } else {
13135        removeClassesViaAttribute(element, classNames);
13136      }
13137    };
13138  } else {
13139    exports.addClasses = addClasses = addClassesViaAttribute;
13140    exports.removeClasses = removeClasses = removeClassesViaAttribute;
13141  }
13142
13143  exports.addClasses = addClasses;
13144  exports.removeClasses = removeClasses;
13145});
13146enifed('dom-helper/prop', ['exports'], function (exports) {
13147  'use strict';
13148
13149  exports.isAttrRemovalValue = isAttrRemovalValue;
13150  exports.normalizeProperty = normalizeProperty;
13151
13152  function isAttrRemovalValue(value) {
13153    return value === null || value === undefined;
13154  }
13155
13156  /*
13157   *
13158   * @method normalizeProperty
13159   * @param element {HTMLElement}
13160   * @param slotName {String}
13161   * @returns {Object} { name, type }
13162   */
13163
13164  function normalizeProperty(element, slotName) {
13165    var type, normalized;
13166
13167    if (slotName in element) {
13168      normalized = slotName;
13169      type = 'prop';
13170    } else {
13171      var lower = slotName.toLowerCase();
13172      if (lower in element) {
13173        type = 'prop';
13174        normalized = lower;
13175      } else {
13176        type = 'attr';
13177        normalized = slotName;
13178      }
13179    }
13180
13181    if (type === 'prop' && (normalized.toLowerCase() === 'style' || preferAttr(element.tagName, normalized))) {
13182      type = 'attr';
13183    }
13184
13185    return { normalized: normalized, type: type };
13186  }
13187
13188  // properties that MUST be set as attributes, due to:
13189  // * browser bug
13190  // * strange spec outlier
13191  var ATTR_OVERRIDES = {
13192
13193    // phantomjs < 2.0 lets you set it as a prop but won't reflect it
13194    // back to the attribute. button.getAttribute('type') === null
13195    BUTTON: { type: true, form: true },
13196
13197    INPUT: {
13198      // TODO: remove when IE8 is droped
13199      // Some versions of IE (IE8) throw an exception when setting
13200      // `input.list = 'somestring'`:
13201      // https://github.com/emberjs/ember.js/issues/10908
13202      // https://github.com/emberjs/ember.js/issues/11364
13203      list: true,
13204      // Some version of IE (like IE9) actually throw an exception
13205      // if you set input.type = 'something-unknown'
13206      type: true,
13207      form: true,
13208      // Chrome 46.0.2464.0: 'autocorrect' in document.createElement('input') === false
13209      // Safari 8.0.7: 'autocorrect' in document.createElement('input') === false
13210      // Mobile Safari (iOS 8.4 simulator): 'autocorrect' in document.createElement('input') === true
13211      autocorrect: true
13212    },
13213
13214    // element.form is actually a legitimate readOnly property, that is to be
13215    // mutated, but must be mutated by setAttribute...
13216    SELECT: { form: true },
13217    OPTION: { form: true },
13218    TEXTAREA: { form: true },
13219    LABEL: { form: true },
13220    FIELDSET: { form: true },
13221    LEGEND: { form: true },
13222    OBJECT: { form: true }
13223  };
13224
13225  function preferAttr(tagName, propName) {
13226    var tag = ATTR_OVERRIDES[tagName.toUpperCase()];
13227    return tag && tag[propName.toLowerCase()] || false;
13228  }
13229});
13230enifed("dom-helper", ["exports", "htmlbars-runtime/morph", "morph-attr", "dom-helper/build-html-dom", "dom-helper/classes", "dom-helper/prop"], function (exports, _htmlbarsRuntimeMorph, _morphAttr, _domHelperBuildHtmlDom, _domHelperClasses, _domHelperProp) {
13231  /*globals module, URL*/
13232
13233  "use strict";
13234
13235  var doc = typeof document === 'undefined' ? false : document;
13236
13237  var deletesBlankTextNodes = doc && (function (document) {
13238    var element = document.createElement('div');
13239    element.appendChild(document.createTextNode(''));
13240    var clonedElement = element.cloneNode(true);
13241    return clonedElement.childNodes.length === 0;
13242  })(doc);
13243
13244  var ignoresCheckedAttribute = doc && (function (document) {
13245    var element = document.createElement('input');
13246    element.setAttribute('checked', 'checked');
13247    var clonedElement = element.cloneNode(false);
13248    return !clonedElement.checked;
13249  })(doc);
13250
13251  var canRemoveSvgViewBoxAttribute = doc && (doc.createElementNS ? (function (document) {
13252    var element = document.createElementNS(_domHelperBuildHtmlDom.svgN
13252amespace, 'svg');
13253    element.setAttribute('viewBox', '0 0 100 100');
13254    element.removeAttribute('viewBox');
13255    return !element.getAttribute('viewBox');
13256  })(doc) : true);
13257
13258  var canClone = doc && (function (document) {
13259    var element = document.createElement('div');
13260    element.appendChild(document.createTextNode(' '));
13261    element.appendChild(document.createTextNode(' '));
13262    var clonedElement = element.cloneNode(true);
13263    return clonedElement.childNodes[0].nodeValue === ' ';
13264  })(doc);
13265
13266  // This is not the namespace of the element, but of
13267  // the elements inside that elements.
13268  function interiorNamespace(element) {
13269    if (element && element.namespaceURI === _domHelperBuildHtmlDom.svgNamespace && !_domHelperBuildHtmlDom.svgHTMLIntegrationPoints[element.tagName]) {
13270      return _domHelperBuildHtmlDom.svgNamespace;
13271    } else {
13272      return null;
13273    }
13274  }
13275
13276  // The HTML spec allows for "omitted start tags". These tags are optional
13277  // when their intended child is the first thing in the parent tag. For
13278  // example, this is a tbody start tag:
13279  //
13280  // <table>
13281  //   <tbody>
13282  //     <tr>
13283  //
13284  // The tbody may be omitted, and the browser will accept and render:
13285  //
13286  // <table>
13287  //   <tr>
13288  //
13289  // However, the omitted start tag will still be added to the DOM. Here
13290  // we test the string and context to see if the browser is about to
13291  // perform this cleanup.
13292  //
13293  // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
13294  // describes which tags are omittable. The spec for tbody and colgroup
13295  // explains this behavior:
13296  //
13297  // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-tbody-element
13298  // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-colgroup-element
13299  //
13300
13301  var omittedStartTagChildTest = /<([\w:]+)/;
13302  function detectOmittedStartTag(string, contextualElement) {
13303    // Omitted start tags are only inside table tags.
13304    if (contextualElement.tagName === 'TABLE') {
13305      var omittedStartTagChildMatch = omittedStartTagChildTest.exec(string);
13306      if (omittedStartTagChildMatch) {
13307        var omittedStartTagChild = omittedStartTagChildMatch[1];
13308        // It is already asserted that the contextual element is a table
13309        // and not the proper start tag. Just see if a tag was omitted.
13310        return omittedStartTagChild === 'tr' || omittedStartTagChild === 'col';
13311      }
13312    }
13313  }
13314
13315  function buildSVGDOM(html, dom) {
13316    var div = dom.document.createElement('div');
13317    div.innerHTML = '<svg>' + html + '</svg>';
13318    return div.firstChild.childNodes;
13319  }
13320
13321  var guid = 1;
13322
13323  function ElementMorph(element, dom, namespace) {
13324    this.element = element;
13325    this.dom = dom;
13326    this.namespace = namespace;
13327    this.guid = "element" + guid++;
13328
13329    this._state = undefined;
13330    this.isDirty = true;
13331  }
13332
13333  ElementMorph.prototype.getState = function () {
13334    if (!this._state) {
13335      this._state = {};
13336    }
13337
13338    return this._state;
13339  };
13340
13341  ElementMorph.prototype.setState = function (newState) {
13342    /*jshint -W093 */
13343
13344    return this._state = newState;
13345  };
13346
13347  // renderAndCleanup calls `clear` on all items in the morph map
13348  // just before calling `destroy` on the morph.
13349  //
13350  // As a future refactor this could be changed to set the property
13351  // back to its original/default value.
13352  ElementMorph.prototype.clear = function () {};
13353
13354  ElementMorph.prototype.destroy = function () {
13355    this.element = null;
13356    this.dom = null;
13357  };
13358
13359  /*
13360   * A class wrapping DOM functions to address environment compatibility,
13361   * namespaces, contextual elements for morph un-escaped content
13362   * insertion.
13363   *
13364   * When entering a template, a DOMHelper should be passed:
13365   *
13366   *   template(context, { hooks: hooks, dom: new DOMHelper() });
13367   *
13368   * TODO: support foreignObject as a passed contextual element. It has
13369   * a namespace (svg) that does not match its internal namespace
13370   * (xhtml).
13371   *
13372   * @class DOMHelper
13373   * @constructor
13374   * @param {HTMLDocument} _document The document DOM methods are proxied to
13375   */
13376  function DOMHelper(_document) {
13377    this.document = _document || document;
13378    if (!this.document) {
13379      throw new Error("A document object must be passed to the DOMHelper, or available on the global scope");
13380    }
13381    this.canClone = canClone;
13382    this.namespace = null;
13383
13384    installEnvironmentSpecificMethods(this);
13385  }
13386
13387  var prototype = DOMHelper.prototype;
13388  prototype.constructor = DOMHelper;
13389
13390  prototype.getElementById = function (id, rootNode) {
13391    rootNode = rootNode || this.document;
13392    return rootNode.getElementById(id);
13393  };
13394
13395  prototype.insertBefore = function (element, childElement, referenceChild) {
13396    return element.insertBefore(childElement, referenceChild);
13397  };
13398
13399  prototype.appendChild = function (element, childElement) {
13400    return element.appendChild(childElement);
13401  };
13402
13403  var itemAt;
13404
13405  // It appears that sometimes, in yet to be itentified scenarios PhantomJS 2.0
13406  // crashes on childNodes.item(index), but works as expected with childNodes[index];
13407  //
13408  // Although it would be nice to move to childNodes[index] in all scenarios,
13409  // this would require SimpleDOM to maintain the childNodes array. This would be
13410  // quite costly, in both dev time and runtime.
13411  //
13412  // So instead, we choose the best possible method and call it a day.
13413  //
13414  /*global navigator */
13415  if (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('PhantomJS')) {
13416    itemAt = function (nodes, index) {
13417      return nodes[index];
13418    };
13419  } else {
13420    itemAt = function (nodes, index) {
13421      return nodes.item(index);
13422    };
13423  }
13424
13425  prototype.childAt = function (element, indices) {
13426    var child = element;
13427
13428    for (var i = 0; i < indices.length; i++) {
13429      child = itemAt(child.childNodes, indices[i]);
13430    }
13431
13432    return child;
13433  };
13434
13435  // Note to a Fellow Implementor:
13436  // Ahh, accessing a child node at an index. Seems like it should be so simple,
13437  // doesn't it? Unfortunately, this particular method has caused us a surprising
13438  // amount of pain. As you'll note below, this method has been modified to walk
13439  // the linked list of child nodes rather than access the child by index
13440  // directly, even though there are two (2) APIs in the DOM that do this for us.
13441  // If you're thinking to yourself, "What an oversight! What an opportunity to
13442  // optimize this code!" then to you I say: stop! For I have a tale to tell.
13443  //
13444  // First, this code must be compatible with simple-dom for rendering on the
13445  // server where there is no real DOM. Previously, we accessed a child node
13446  // directly via `element.childNodes[index]`. While we *could* in theory do a
13447  // full-fidelity simulation of a live `childNodes` array, this is slow,
13448  // complicated and error-prone.
13449  //
13450  // "No problem," we thought, "we'll just use the similar
13451  // `childNodes.item(index)` API." Then, we could just implement our own `item`
13452  // method in simple-dom and walk the child node linked list there, allowing
13453  // us to retain the performance advantages of the (surely optimized) `item()`
13454  // API in the browser.
13455  //
13456  // Unfortunately, an enterprising soul named Samy Alzahrani discovered that in
13457  // IE8, accessing an item out-of-bounds via `item()` causes an exception where
13458  // other browsers return null. This necessitated a... check of
13459  // `childNodes.length`, bringing us back around to having to supp
13459ort a
13460  // full-fidelity `childNodes` array!
13461  //
13462  // Worst of all, Kris Selden investigated how browsers are actualy implemented
13463  // and discovered that they're all linked lists under the hood anyway. Accessing
13464  // `childNodes` requires them to allocate a new live collection backed by that
13465  // linked list, which is itself a rather expensive operation. Our assumed
13466  // optimization had backfired! That is the danger of magical thinking about
13467  // the performance of native implementations.
13468  //
13469  // And this, my friends, is why the following implementation just walks the
13470  // linked list, as surprised as that may make you. Please ensure you understand
13471  // the above before changing this and submitting a PR.
13472  //
13473  // Tom Dale, January 18th, 2015, Portland OR
13474  prototype.childAtIndex = function (element, index) {
13475    var node = element.firstChild;
13476
13477    for (var idx = 0; node && idx < index; idx++) {
13478      node = node.nextSibling;
13479    }
13480
13481    return node;
13482  };
13483
13484  prototype.appendText = function (element, text) {
13485    return element.appendChild(this.document.createTextNode(text));
13486  };
13487
13488  prototype.setAttribute = function (element, name, value) {
13489    element.setAttribute(name, String(value));
13490  };
13491
13492  prototype.getAttribute = function (element, name) {
13493    return element.getAttribute(name);
13494  };
13495
13496  prototype.setAttributeNS = function (element, namespace, name, value) {
13497    element.setAttributeNS(namespace, name, String(value));
13498  };
13499
13500  prototype.getAttributeNS = function (element, namespace, name) {
13501    return element.getAttributeNS(namespace, name);
13502  };
13503
13504  if (canRemoveSvgViewBoxAttribute) {
13505    prototype.removeAttribute = function (element, name) {
13506      element.removeAttribute(name);
13507    };
13508  } else {
13509    prototype.removeAttribute = function (element, name) {
13510      if (element.tagName === 'svg' && name === 'viewBox') {
13511        element.setAttribute(name, null);
13512      } else {
13513        element.removeAttribute(name);
13514      }
13515    };
13516  }
13517
13518  prototype.setPropertyStrict = function (element, name, value) {
13519    if (value === undefined) {
13520      value = null;
13521    }
13522
13523    if (value === null && (name === 'value' || name === 'type' || name === 'src')) {
13524      value = '';
13525    }
13526
13527    element[name] = value;
13528  };
13529
13530  prototype.getPropertyStrict = function (element, name) {
13531    return element[name];
13532  };
13533
13534  prototype.setProperty = function (element, name, value, namespace) {
13535    if (element.namespaceURI === _domHelperBuildHtmlDom.svgNamespace) {
13536      if (_domHelperProp.isAttrRemovalValue(value)) {
13537        element.removeAttribute(name);
13538      } else {
13539        if (namespace) {
13540          element.setAttributeNS(namespace, name, value);
13541        } else {
13542          element.setAttribute(name, value);
13543        }
13544      }
13545    } else {
13546      var _normalizeProperty = _domHelperProp.normalizeProperty(element, name);
13547
13548      var normalized = _normalizeProperty.normalized;
13549      var type = _normalizeProperty.type;
13550
13551      if (type === 'prop') {
13552        element[normalized] = value;
13553      } else {
13554        if (_domHelperProp.isAttrRemovalValue(value)) {
13555          element.removeAttribute(name);
13556        } else {
13557          if (namespace && element.setAttributeNS) {
13558            element.setAttributeNS(namespace, name, value);
13559          } else {
13560            element.setAttribute(name, value);
13561          }
13562        }
13563      }
13564    }
13565  };
13566
13567  if (doc && doc.createElementNS) {
13568    // Only opt into namespace detection if a contextualElement
13569    // is passed.
13570    prototype.createElement = function (tagName, contextualElement) {
13571      var namespace = this.namespace;
13572      if (contextualElement) {
13573        if (tagName === 'svg') {
13574          namespace = _domHelperBuildHtmlDom.svgNamespace;
13575        } else {
13576          namespace = interiorNamespace(contextualElement);
13577        }
13578      }
13579      if (namespace) {
13580        return this.document.createElementNS(namespace, tagName);
13581      } else {
13582        return this.document.createElement(tagName);
13583      }
13584    };
13585    prototype.setAttributeNS = function (element, namespace, name, value) {
13586      element.setAttributeNS(namespace, name, String(value));
13587    };
13588  } else {
13589    prototype.createElement = function (tagName) {
13590      return this.document.createElement(tagName);
13591    };
13592    prototype.setAttributeNS = function (element, namespace, name, value) {
13593      element.setAttribute(name, String(value));
13594    };
13595  }
13596
13597  prototype.addClasses = _domHelperClasses.addClasses;
13598  prototype.removeClasses = _domHelperClasses.removeClasses;
13599
13600  prototype.setNamespace = function (ns) {
13601    this.namespace = ns;
13602  };
13603
13604  prototype.detectNamespace = function (element) {
13605    this.namespace = interiorNamespace(element);
13606  };
13607
13608  prototype.createDocumentFragment = function () {
13609    return this.document.createDocumentFragment();
13610  };
13611
13612  prototype.createTextNode = function (text) {
13613    return this.document.createTextNode(text);
13614  };
13615
13616  prototype.createComment = function (text) {
13617    return this.document.createComment(text);
13618  };
13619
13620  prototype.repairClonedNode = function (element, blankChildTextNodes, isChecked) {
13621    if (deletesBlankTextNodes && blankChildTextNodes.length > 0) {
13622      for (var i = 0, len = blankChildTextNodes.length; i < len; i++) {
13623        var textNode = this.document.createTextNode(''),
13624            offset = blankChildTextNodes[i],
13625            before = this.childAtIndex(element, offset);
13626        if (before) {
13627          element.insertBefore(textNode, before);
13628        } else {
13629          element.appendChild(textNode);
13630        }
13631      }
13632    }
13633    if (ignoresCheckedAttribute && isChecked) {
13634      element.setAttribute('checked', 'checked');
13635    }
13636  };
13637
13638  prototype.cloneNode = function (element, deep) {
13639    var clone = element.cloneNode(!!deep);
13640    return clone;
13641  };
13642
13643  prototype.AttrMorphClass = _morphAttr.default;
13644
13645  prototype.createAttrMorph = function (element, attrName, namespace) {
13646    return this.AttrMorphClass.create(element, attrName, this, namespace);
13647  };
13648
13649  prototype.ElementMorphClass = ElementMorph;
13650
13651  prototype.createElementMorph = function (element, namespace) {
13652    return new this.ElementMorphClass(element, this, namespace);
13653  };
13654
13655  prototype.createUnsafeAttrMorph = function (element, attrName, namespace) {
13656    var morph = this.createAttrMorph(element, attrName, namespace);
13657    morph.escaped = false;
13658    return morph;
13659  };
13660
13661  prototype.MorphClass = _htmlbarsRuntimeMorph.default;
13662
13663  prototype.createMorph = function (parent, start, end, contextualElement) {
13664    if (contextualElement && contextualElement.nodeType === 11) {
13665      throw new Error("Cannot pass a fragment as the contextual element to createMorph");
13666    }
13667
13668    if (!contextualElement && parent && parent.nodeType === 1) {
13669      contextualElement = parent;
13670    }
13671    var morph = new this.MorphClass(this, contextualElement);
13672    morph.firstNode = start;
13673    morph.lastNode = end;
13674    return morph;
13675  };
13676
13677  prototype.createFragmentMorph = function (contextualElement) {
13678    if (contextualElement && contextualElement.nodeType === 11) {
13679      throw new Error("Cannot pass a fragment as the contextual element to createMorph");
13680    }
13681
13682    var fragment = this.createDocumentFragment();
13683    return _htmlbarsRuntimeMorph.default.create(this, contextualElement, fragment);
13684  };
13685
13686  prototype.replaceContentWithMorph = function (element) {
13687    var firstChild = element.firstChild;
13688
13689    if (!firstChild) {
13690      var comment = this.createComment('');
13691      this.appendChild(element, comment);
13692      return _htmlbarsRuntimeMorph.default.create(this, element, comment);
13693    } else {
13694      var morph = _htmlbarsRuntimeMorph.default.attach(this, element, firstChild, element.lastChild);
13695      morph.clear();
13696      return morph;
13697    }
13698  };
13699
13700  prototype.createUnsafeMorph = function (parent, start, end, contextualElement) {
13701    var morph = this.createMorph(parent, start, end, contextualElement);
13702    morph.parseTextAsHTML = true;
13703    return morph;
13704  };
13705
13706  // This helper is just to keep the templates good looking,
13707  // passing integers instead of element references.
13708  prototype.createMorphAt = function (parent, startIndex, endIndex, contextualElement) {
13709    var single = startIndex === endIndex;
13710    var start = this.childAtIndex(parent, startIndex);
13711    var end = single ? start : this.childAtIndex(parent, endIndex);
13712    return this.createMorph(parent, start, end, contextualElement);
13713  };
13714
13715  prototype.createUnsafeMorphAt = function (parent, startIndex, endIndex, contextualElement) {
13716    var morph = this.createMorphAt(parent, startIndex, endIndex, contextualElement);
13717    morph.parseTextAsHTML = true;
13718    return morph;
13719  };
13720
13721  prototype.insertMorphBefore = function (element, referenceChild, contextualElement) {
13722    var insertion = this.document.createComment('');
13723    element.insertBefore(insertion, referenceChild);
13724    return this.createMorph(element, insertion, insertion, contextualElement);
13725  };
13726
13727  prototype.appendMorph = function (element, contextualElement) {
13728    var insertion = this.document.createComment('');
13729    element.appendChild(insertion);
13730    return this.createMorph(element, insertion, insertion, contextualElement);
13731  };
13732
13733  prototype.insertBoundary = function (fragment, index) {
13734    // this will always be null or firstChild
13735    var child = index === null ? null : this.childAtIndex(fragment, index);
13736    this.insertBefore(fragment, this.createTextNode(''), child);
13737  };
13738
13739  prototype.setMorphHTML = function (morph, html) {
13740    morph.setHTML(html);
13741  };
13742
13743  prototype.parseHTML = function (html, contextualElement) {
13744    var childNodes;
13745
13746    if (interiorNamespace(contextualElement) === _domHelperBuildHtmlDom.svgNamespace) {
13747      childNodes = buildSVGDOM(html, this);
13748    } else {
13749      var nodes = _domHelperBuildHtmlDom.buildHTMLDOM(html, contextualElement, this);
13750      if (detectOmittedStartTag(html, contextualElement)) {
13751        var node = nodes[0];
13752        while (node && node.nodeType !== 1) {
13753          node = node.nextSibling;
13754        }
13755        childNodes = node.childNodes;
13756      } else {
13757        childNodes = nodes;
13758      }
13759    }
13760
13761    // Copy node list to a fragment.
13762    var fragment = this.document.createDocumentFragment();
13763
13764    if (childNodes && childNodes.length > 0) {
13765      var currentNode = childNodes[0];
13766
13767      // We prepend an <option> to <select> boxes to absorb any browser bugs
13768      // related to auto-select behavior. Skip past it.
13769      if (contextualElement.tagName === 'SELECT') {
13770        currentNode = currentNode.nextSibling;
13771      }
13772
13773      while (currentNode) {
13774        var tempNode = currentNode;
13775        currentNode = currentNode.nextSibling;
13776
13777        fragment.appendChild(tempNode);
13778      }
13779    }
13780
13781    return fragment;
13782  };
13783
13784  var nodeURL;
13785  var parsingNode;
13786
13787  function installEnvironmentSpecificMethods(domHelper) {
13788    var protocol = browserProtocolForURL.call(domHelper, 'foobar:baz');
13789
13790    // Test to see if our DOM implementation parses
13791    // and normalizes URLs.
13792    if (protocol === 'foobar:') {
13793      // Swap in the method that doesn't do this test now that
13794      // we know it works.
13795      domHelper.protocolForURL = browserProtocolForURL;
13796    } else if (typeof URL === 'object') {
13797      // URL globally provided, likely from FastBoot's sandbox
13798      nodeURL = URL;
13799      domHelper.protocolForURL = nodeProtocolForURL;
13800    } else if (typeof module === 'object' && typeof module.require === 'function') {
13801      // Otherwise, we need to fall back to our own URL parsing.
13802      // Global `require` is shadowed by Ember's loader so we have to use the fully
13803      // qualified `module.require`.
13804      nodeURL = module.require('url');
13805      domHelper.protocolForURL = nodeProtocolForURL;
13806    } else {
13807      throw new Error("DOM Helper could not find valid URL parsing mechanism");
13808    }
13809
13810    // A SimpleDOM-specific extension that allows us to place HTML directly
13811    // into the DOM tree, for when the output target is always serialized HTML.
13812    if (domHelper.document.createRawHTMLSection) {
13813      domHelper.setMorphHTML = nodeSetMorphHTML;
13814    }
13815  }
13816
13817  function nodeSetMorphHTML(morph, html) {
13818    var section = this.document.createRawHTMLSection(html);
13819    morph.setNode(section);
13820  }
13821
13822  function browserProtocolForURL(url) {
13823    if (!parsingNode) {
13824      parsingNode = this.document.createElement('a');
13825    }
13826
13827    parsingNode.href = url;
13828    return parsingNode.protocol;
13829  }
13830
13831  function nodeProtocolForURL(url) {
13832    var protocol = nodeURL.parse(url).protocol;
13833    return protocol === null ? ':' : protocol;
13834  }
13835
13836  exports.default = DOMHelper;
13837});
13838enifed('ember/index', ['exports', 'ember-metal', 'ember-runtime', 'ember-views', 'ember-routing', 'ember-application', 'ember-extension-support', 'ember-htmlbars', 'ember-routing-htmlbars', 'ember-routing-views', 'require', 'ember-runtime/system/lazy_load'], function (exports, _emberMetal, _emberRuntime, _emberViews, _emberRouting, _emberApplication, _emberExtensionSupport, _emberHtmlbars, _emberRoutingHtmlbars, _emberRoutingViews, _require, _emberRuntimeSystemLazy_load) {
13839  // require the main entry points for each of these packages
13840  // this is so that the global exports occur properly
13841  'use strict';
13842
13843  if (_require.has('ember-template-compiler')) {
13844    _require.default('ember-template-compiler');
13845  }
13846
13847  // do this to ensure that Ember.Test is defined properly on the global
13848  // if it is present.
13849  if (_require.has('ember-testing')) {
13850    _require.default('ember-testing');
13851  }
13852
13853  _emberRuntimeSystemLazy_load.runLoadHooks('Ember');
13854
13855  /**
13856  @module ember
13857  */
13858});
13859enifed('ember-application/index', ['exports', 'ember-metal/core', 'ember-metal/features', 'ember-runtime/system/lazy_load', 'ember-application/system/resolver', 'ember-application/system/application', 'ember-application/system/application-instance', 'ember-application/system/engine', 'ember-application/system/engine-instance'], function (exports, _emberMetalCore, _emberMetalFeatures, _emberRuntimeSystemLazy_load, _emberApplicationSystemResolver, _emberApplicationSystemApplication, _emberApplicationSystemApplicationInstance, _emberApplicationSystemEngine, _emberApplicationSystemEngineInstance) {
13860  'use strict';
13861
13862  _emberMetalCore.default.Application = _emberApplicationSystemApplication.default;
13863  _emberMetalCore.default.Resolver = _emberApplicationSystemResolver.Resolver;
13864  _emberMetalCore.default.DefaultResolver = _emberApplicationSystemResolver.default;
13865
13866  _emberRuntimeSystemLazy_load.runLoadHooks('Ember.Application', _emberApplicationSystemApplication.default);
13867});
13868
13869/**
13870@module ember
13871@submodule ember-application
13872*/
13873
13874// Expose `EngineInstance` and `ApplicationInstance` for easy overriding.
13875// Reanalyze whether to continue exposing these after feature flag is removed.
13876enifed('ember-application/system/application-instance', ['exports', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/run_loop', 'ember-metal/computed', 'ember-htmlbars/system/dom-helper', 'ember-runtime/mixins/registry_proxy', 'ember-metal-views', 'ember-metal/assign', 'ember-metal/environment', 'ember-runtime/ext/rsvp', 'ember-views/system/jquery', 'ember-application/system/engine-instance'], function (exports, _emberMetalDebug, _emberMetalFeatures, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalRun_loop, _emberMetalComputed, _emberHtmlbarsSystemDomHelper, _emberRuntimeMixinsReg
13876istry_proxy, _emberMetalViews, _emberMetalAssign, _emberMetalEnvironment, _emberRuntimeExtRsvp, _emberViewsSystemJquery, _emberApplicationSystemEngineInstance) {
13877  /**
13878  @module ember
13879  @submodule ember-application
13880  */
13881
13882  'use strict';
13883
13884  var BootOptions = undefined;
13885
13886  /**
13887    The `ApplicationInstance` encapsulates all of the stateful aspects of a
13888    running `Application`.
13889  
13890    At a high-level, we break application boot into two distinct phases:
13891  
13892    * Definition time, where all of the classes, templates, and other
13893      dependencies are loaded (typically in the browser).
13894    * Run time, where we begin executing the application once everything
13895      has loaded.
13896  
13897    Definition time can be expensive and only needs to happen once since it is
13898    an idempotent operation. For example, between test runs and FastBoot
13899    requests, the application stays the same. It is only the state that we want
13900    to reset.
13901  
13902    That state is what the `ApplicationInstance` manages: it is responsible for
13903    creating the container that contains all application state, and disposing of
13904    it once the particular test run or FastBoot request has finished.
13905  
13906    @public
13907    @class Ember.ApplicationInstance
13908    @extends Ember.EngineInstance
13909  */
13910
13911  var ApplicationInstance = _emberApplicationSystemEngineInstance.default.extend({
13912    /**
13913      The `Application` for which this is an instance.
13914       @property {Ember.Application} application
13915      @private
13916    */
13917    application: null,
13918
13919    /**
13920      The DOM events for which the event dispatcher should listen.
13921       By default, the application's `Ember.EventDispatcher` listens
13922      for a set of standard DOM events, such as `mousedown` and
13923      `keyup`, and delegates them to your application's `Ember.View`
13924      instances.
13925       @private
13926      @property {Object} customEvents
13927    */
13928    customEvents: null,
13929
13930    /**
13931      The root DOM element of the Application as an element or a
13932      [jQuery-compatible selector
13933      string](http://api.jquery.com/category/selectors/).
13934       @private
13935      @property {String|DOMElement} rootElement
13936    */
13937    rootElement: null,
13938
13939    init: function () {
13940      this._super.apply(this, arguments);
13941
13942      var application = this.application;
13943
13944      // Register this instance in the per-instance registry.
13945      //
13946      // Why do we need to register the instance in the first place?
13947      // Because we need a good way for the root route (a.k.a ApplicationRoute)
13948      // to notify us when it has created the root-most view. That view is then
13949      // appended to the rootElement, in the case of apps, to the fixture harness
13950      // in tests, or rendered to a string in the case of FastBoot.
13951      this.register('-application-instance:main', this, { instantiate: false });
13952
13953      this._booted = false;
13954    },
13955
13956    /**
13957      Initialize the `Ember.ApplicationInstance` and return a promise that resolves
13958      with the instance itself when the boot process is complete.
13959       The primary task here is to run any registered instance initializers.
13960       See the documentation on `BootOptions` for the options it takes.
13961       @private
13962      @method boot
13963      @param options
13964      @return {Promise<Ember.ApplicationInstance,Error>}
13965    */
13966    boot: function () {
13967      var _this = this;
13968
13969      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
13970
13971      if (this._bootPromise) {
13972        return this._bootPromise;
13973      }
13974
13975      this._bootPromise = new _emberRuntimeExtRsvp.default.Promise(function (resolve) {
13976        return resolve(_this._bootSync(options));
13977      });
13978
13979      return this._bootPromise;
13980    },
13981
13982    /**
13983      Unfortunately, a lot of existing code assumes booting an instance is
13984      synchronous – specifically, a lot of tests assumes the last call to
13985      `app.advanceReadiness()` or `app.reset()` will result in a new instance
13986      being fully-booted when the current runloop completes.
13987       We would like new code (like the `visit` API) to stop making this assumption,
13988      so we created the asynchronous version above that returns a promise. But until
13989      we have migrated all the code, we would have to expose this method for use
13990      *internally* in places where we need to boot an instance synchronously.
13991       @private
13992    */
13993    _bootSync: function (options) {
13994      if (this._booted) {
13995        return this;
13996      }
13997
13998      options = new BootOptions(options);
13999
14000      var registry = this.__registry__;
14001
14002      registry.register('-environment:main', options.toEnvironment(), { instantiate: false });
14003      registry.injection('view', '_environment', '-environment:main');
14004      registry.injection('route', '_environment', '-environment:main');
14005
14006      registry.register('renderer:-dom', {
14007        create: function () {
14008          return new _emberMetalViews.Renderer(new _emberHtmlbarsSystemDomHelper.default(options.document), { destinedForDOM: options.isInteractive });
14009        }
14010      });
14011
14012      if (options.rootElement) {
14013        this.rootElement = options.rootElement;
14014      } else {
14015        this.rootElement = this.application.rootElement;
14016      }
14017
14018      if (options.location) {
14019        var router = _emberMetalProperty_get.get(this, 'router');
14020        _emberMetalProperty_set.set(router, 'location', options.location);
14021      }
14022
14023      this.application.runInstanceInitializers(this);
14024
14025      if (options.isInteractive) {
14026        this.setupEventDispatcher();
14027      }
14028
14029      this._booted = true;
14030
14031      return this;
14032    },
14033
14034    router: _emberMetalComputed.computed(function () {
14035      return this.lookup('router:main');
14036    }).readOnly(),
14037
14038    /**
14039      This hook is called by the root-most Route (a.k.a. the ApplicationRoute)
14040      when it has finished creating the root View. By default, we simply take the
14041      view and append it to the `rootElement` specified on the Application.
14042       In cases like FastBoot and testing, we can override this hook and implement
14043      custom behavior, such as serializing to a string and sending over an HTTP
14044      socket rather than appending to DOM.
14045       @param view {Ember.View} the root-most view
14046      @private
14047    */
14048    didCreateRootView: function (view) {
14049      view.appendTo(this.rootElement);
14050    },
14051
14052    /**
14053      Tells the router to start routing. The router will ask the location for the
14054      current URL of the page to determine the initial URL to start routing to.
14055      To start the app at a specific URL, call `handleURL` instead.
14056       @private
14057    */
14058    startRouting: function () {
14059      var router = _emberMetalProperty_get.get(this, 'router');
14060      router.startRouting();
14061      this._didSetupRouter = true;
14062    },
14063
14064    /**
14065      @private
14066       Sets up the router, initializing the child router and configuring the
14067      location before routing begins.
14068       Because setup should only occur once, multiple calls to `setupRouter`
14069      beyond the first call have no effect.
14070    */
14071    setupRouter: function () {
14072      if (this._didSetupRouter) {
14073        return;
14074      }
14075      this._didSetupRouter = true;
14076
14077      var router = _emberMetalProperty_get.get(this, 'router');
14078      router.setupRouter();
14079    },
14080
14081    /**
14082      Directs the router to route to a particular URL. This is useful in tests,
14083      for example, to tell the app to start at a particular URL.
14084       @param url {String} the URL the router should route to
14085      @private
14086    */
14087    handleURL: function (url) {
14088      var router = _emberMetalProperty_get.get(this, 'router');
14089
14090      this.setupRouter();
14091      return router.handleURL(url);
14092    },
14093
14094    /**
14095      @private
14096    */
14097    setupEventDispatcher: function () {
14098      var dispatcher = this.lookup('event_dispatcher:main');
14099      var applicationCustomEvents = _emberMetalProperty_get.get(this.application, 'customEvents');
14100      var instanceCustomEvents = _emberMetalProperty_get.get(this, 'customEvents');
14101
14102      var customEvents = _emberMetalAssign.default({}, applicationCustomEvents, instanceCustomEvents);
14103      dispatcher.setup(customEvents, this.rootElement);
14104
14105      return dispatcher;
14106    }
14107  });
14108
14109  ApplicationInstance.reopen({
14110    /**
14111      Returns the current URL of the app instance. This is useful when your
14112      app does not update the browsers URL bar (i.e. it uses the `'none'`
14113      location adapter).
14114       @public
14115      @return {String} the current URL
14116    */
14117    getURL: function () {
14118      var router = _emberMetalProperty_get.get(this, 'router');
14119      return _emberMetalProperty_get.get(router, 'url');
14120    },
14121
14122    // `instance.visit(url)` should eventually replace `instance.handleURL()`;
14123    // the test helpers can probably be switched to use this implementation too
14124
14125    /**
14126      Navigate the instance to a particular URL. This is useful in tests, for
14127      example, or to tell the app to start at a particular URL. This method
14128      returns a promise that resolves with the app instance when the transition
14129      is complete, or rejects if the transion was aborted due to an error.
14130       @public
14131      @param url {String} the destination URL
14132      @return {Promise}
14133    */
14134    visit: function (url) {
14135      var _this2 = this;
14136
14137      this.setupRouter();
14138
14139      var router = _emberMetalProperty_get.get(this, 'router');
14140
14141      var handleResolve = function () {
14142        // Resolve only after rendering is complete
14143        return new _emberRuntimeExtRsvp.default.Promise(function (resolve) {
14144          // TODO: why is this necessary? Shouldn't 'actions' queue be enough?
14145          // Also, aren't proimses supposed to be async anyway?
14146          _emberMetalRun_loop.default.next(null, resolve, _this2);
14147        });
14148      };
14149
14150      var handleReject = function (error) {
14151        if (error.error) {
14152          throw error.error;
14153        } else if (error.name === 'TransitionAborted' && router.router.activeTransition) {
14154          return router.router.activeTransition.then(handleResolve, handleReject);
14155        } else if (error.name === 'TransitionAborted') {
14156          throw new Error(error.message);
14157        } else {
14158          throw error;
14159        }
14160      };
14161
14162      // Keeps the location adapter's internal URL in-sync
14163      _emberMetalProperty_get.get(router, 'location').setURL(url);
14164
14165      return router.handleURL(url).then(handleResolve, handleReject);
14166    }
14167  });
14168
14169  /**
14170    A list of boot-time configuration options for customizing the behavior of
14171    an `Ember.ApplicationInstance`.
14172     This is an interface class that exists purely to document the available
14173    options; you do not need to construct it manually. Simply pass a regular
14174    JavaScript object containing the desired options into methods that require
14175    one of these options object:
14176     ```javascript
14177    MyApp.visit("/", { location: "none", rootElement: "#container" });
14178    ```
14179     Not all combinations of the supported options are valid. See the documentation
14180    on `Ember.Application#visit` for the supported configurations.
14181     Internal, experimental or otherwise unstable flags are marked as private.
14182     @class BootOptions
14183    @namespace Ember.ApplicationInstance
14184    @public
14185  */
14186  BootOptions = function BootOptions() {
14187    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
14188
14189    /**
14190      Provide a specific instance of jQuery. This is useful in conjunction with
14191      the `document` option, as it allows you to use a copy of `jQuery` that is
14192      appropriately bound to the foreign `document` (e.g. a jsdom).
14193       This is highly experimental and support very incomplete at the moment.
14194       @property jQuery
14195      @type Object
14196      @default auto-detected
14197      @private
14198    */
14199    this.jQuery = _emberViewsSystemJquery.default; // This default is overridable below
14200
14201    /**
14202      Interactive mode: whether we need to set up event delegation and invoke
14203      lifecycle callbacks on Components.
14204       @property isInteractive
14205      @type boolean
14206      @default auto-detected
14207      @private
14208    */
14209    this.isInteractive = _emberMetalEnvironment.default.hasDOM; // This default is overridable below
14210
14211    /**
14212      Run in a full browser environment.
14213       When this flag is set to `false`, it will disable most browser-specific
14214      and interactive features. Specifically:
14215       * It does not use `jQuery` to append the root view; the `rootElement`
14216        (either specified as a subsequent option or on the application itself)
14217        must already be an `Element` in the given `document` (as opposed to a
14218        string selector).
14219       * It does not set up an `EventDispatcher`.
14220       * It does not run any `Component` lifecycle hooks (such as `didInsertElement`).
14221       * It sets the `location` option to `"none"`. (If you would like to use
14222        the location adapter specified in the app's router instead, you can also
14223        specify `{ location: null }` to specifically opt-out.)
14224       @property isBrowser
14225      @type boolean
14226      @default auto-detected
14227      @public
14228    */
14229    if (options.isBrowser !== undefined) {
14230      this.isBrowser = !!options.isBrowser;
14231    } else {
14232      this.isBrowser = _emberMetalEnvironment.default.hasDOM;
14233    }
14234
14235    if (!this.isBrowser) {
14236      this.jQuery = null;
14237      this.isInteractive = false;
14238      this.location = 'none';
14239    }
14240
14241    /**
14242      Disable rendering completely.
14243       When this flag is set to `true`, it will disable the entire rendering
14244      pipeline. Essentially, this puts the app into "routing-only" mode. No
14245      templates will be rendered, and no Components will be created.
14246       @property shouldRender
14247      @type boolean
14248      @default true
14249      @public
14250    */
14251    if (options.shouldRender !== undefined) {
14252      this.shouldRender = !!options.shouldRender;
14253    } else {
14254      this.shouldRender = true;
14255    }
14256
14257    if (!this.shouldRender) {
14258      this.jQuery = null;
14259      this.isInteractive = false;
14260    }
14261
14262    /**
14263      If present, render into the given `Document` object instead of the
14264      global `window.document` object.
14265       In practice, this is only useful in non-browser environment or in
14266      non-interactive mode, because Ember's `jQuery` dependency is
14267      implicitly bound to the current document, causing event delegation
14268      to not work properly when the app is rendered into a foreign
14269      document object (such as an iframe's `contentDocument`).
14270       In non-browser mode, this could be a "`Document`-like" object as
14271      Ember only interact with a small subset of the DOM API in non-
14272      interactive mode. While the exact requirements have not yet been
14273      formalized, the `SimpleDOM` library's implementation is known to
14274      work.
14275       @property document
14276      @type Document
14277      @default the global `document` object
14278      @public
14279    */
14280    if (options.document) {
14281      this.document = options.document;
14282    } else {
14283      this.document = typeof document !== 'undefined' ? document : null;
14284    }
14285
14286    /**
14287      If present, overrides the application's `rootElement` property on
14288      the instance. This is useful for testing environment, where you
14289      might want to append the root view to a fixture area.
14290       In non-browser mode, because Ember does not have access to jQuery,
14291      this options must be specified as a DOM `Element` object instead of
14292      a selector string.
14293       See the documentation on `Ember.Applications`'s `rootElement` for
14294      details.
14295       @property rootElement
14296      @type String|Element
14297      @default null
14298      @public
14299     */
14300    if (options.rootElement) {
14301      this.rootElement = options.rootElement;
14302    }
14303
14304    // Set these options last to give the user a chance to override the
14305    // defaults from the "combo" options like `isBrowser` (although in
14306    // practice, the resulting combination is probably invalid)
14307
14308    /**
14309      If present, overrides the router's `location` property with this
14310      value. This is useful for environments where trying to modify the
14311      URL would be inappropriate.
14312       @property location
14313      @type string
14314      @default null
14315      @public
14316    */
14317    if (options.location !== undefined) {
14318      this.location = options.location;
14319    }
14320
14321    if (options.jQuery !== undefined) {
14322      this.jQuery = options.jQuery;
14323    }
14324
14325    if (options.isInteractive !== undefined) {
14326      this.isInteractive = !!options.isInteractive;
14327    }
14328  };
14329
14330  BootOptions.prototype.toEnvironment = function () {
14331    var env = _emberMetalAssign.default({}, _emberMetalEnvironment.default);
14332    // For compatibility with existing code
14333    env.hasDOM = this.isBrowser;
14334    env.options = this;
14335    return env;
14336  };
14337
14338  Object.defineProperty(ApplicationInstance.prototype, 'container', {
14339    configurable: true,
14340    enumerable: false,
14341    get: function () {
14342      var instance = this;
14343      return {
14344        lookup: function () {
14345          _emberMetalDebug.deprecate('Using `ApplicationInstance.container.lookup` is deprecated. Please use `ApplicationInstance.lookup` instead.', false, {
14346            id: 'ember-application.app-instance-container',
14347            until: '3.0.0',
14348            url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-applicationinstance-container'
14349          });
14350          return instance.lookup.apply(instance, arguments);
14351        }
14352      };
14353    }
14354  });
14355
14356  Object.defineProperty(ApplicationInstance.prototype, 'registry', {
14357    configurable: true,
14358    enumerable: false,
14359    get: function () {
14360      return _emberRuntimeMixinsRegistry_proxy.buildFakeRegistryWithDeprecations(this, 'ApplicationInstance');
14361    }
14362  });
14363
14364  exports.default = ApplicationInstance;
14365});
14366enifed('ember-application/system/application', ['exports', 'ember-metal', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/property_get', 'ember-runtime/system/lazy_load', 'ember-metal/run_loop', 'ember-runtime/controllers/controller', 'ember-metal-views', 'ember-htmlbars/system/dom-helper', 'ember-views/views/select', 'ember-routing-views/views/outlet', 'ember-views/views/view', 'ember-views/system/event_dispatcher', 'ember-views/system/jquery', 'ember-routing/system/route', 'ember-routing/system/router', 'ember-routing/location/hash_location', 'ember-routing/location/history_location', 'ember-routing/location/auto_location', 'ember-routing/location/none_location', 'ember-routing/system/cache', 'ember-application/system/application-instance', 'ember-views/views/text_field', 'ember-views/views/text_area', 'ember-views/views/checkbox', 'ember-views/views/legacy_each_view', 'ember-routing-views/components/link-to', 'ember-routing/services/routing', 'ember-extension-support/container_debug_adapter', 'ember-runtime/mixins/registry_proxy', 'ember-metal/environment', 'ember-runtime/ext/rsvp', 'ember-application/system/engine'], function (exports, _emberMetal, _emberMetalDebug, _emberMetalFeatures, _emberMetalProperty_get, _emberRuntimeSystemLazy_load, _emberMetalRun_loop, _emberRuntimeControllersController, _emberMetalViews, _emberHtmlbarsSystemDomHelper, _emberViewsViewsSelect, _emberRoutingViewsViewsOutlet, _emberViewsViewsView, _emberViewsSystemEvent_dispatcher, _emberViewsSystemJquery, _emberRoutingSystemRoute, _emberRoutingSystemRouter, _emberRoutingLocationHash_location, _emberRoutingLocationHistory_location, _emberRoutingLocationAuto_location, _emberRoutingLocationNone_location, _emberRoutingSystemCache, _emberApplicationSystemApplicationInstance, _emberViewsViewsText_field, _emberViewsViewsText_area, _emberViewsViewsCheckbox, _emberViewsViewsLegacy_each_view, _emberRoutingViewsComponentsLinkTo, _emberRoutingServicesRouting, _emberExtensionSupportContainer_debug_adapter, _emberRuntimeMixinsReg
14366istry_proxy, _emberMetalEnvironment, _emberRuntimeExtRsvp, _emberApplicationSystemEngine) {
14367  /**
14368  @module ember
14369  @submodule ember-application
14370  */
14371  'use strict';
14372
14373  exports._resetLegacyAddonWarnings = _resetLegacyAddonWarnings;
14374
14375  var librariesRegistered = false;
14376
14377  var warnedAboutLegacyViewAddon = false;
14378  var warnedAboutLegacyControllerAddon = false;
14379
14380  // For testing
14381
14382  function _resetLegacyAddonWarnings() {
14383    warnedAboutLegacyViewAddon = false;
14384    warnedAboutLegacyControllerAddon = false;
14385  }
14386
14387  /**
14388    An instance of `Ember.Application` is the starting point for every Ember
14389    application. It helps to instantiate, initialize and coordinate the many
14390    objects that make up your app.
14391  
14392    Each Ember app has one and only one `Ember.Application` object. In fact, the
14393    very first thing you should do in your application is create the instance:
14394  
14395    ```javascript
14396    window.App = Ember.Application.create();
14397    ```
14398  
14399    Typically, the application object is the only global variable. All other
14400    classes in your app should be properties on the `Ember.Application` instance,
14401    which highlights its first role: a global namespace.
14402  
14403    For example, if you define a view class, it might look like this:
14404  
14405    ```javascript
14406    App.MyView = Ember.View.extend();
14407    ```
14408  
14409    By default, calling `Ember.Application.create()` will automatically initialize
14410    your application by calling the `Ember.Application.initialize()` method. If
14411    you need to delay initialization, you can call your app's `deferReadiness()`
14412    method. When you are ready for your app to be initialized, call its
14413    `advanceReadiness()` method.
14414  
14415    You can define a `ready` method on the `Ember.Application` instance, which
14416    will be run by Ember when the application is initialized.
14417  
14418    Because `Ember.Application` inherits from `Ember.Namespace`, any classes
14419    you create will have useful string representations when calling `toString()`.
14420    See the `Ember.Namespace` documentation for more information.
14421  
14422    While you can think of your `Ember.Application` as a container that holds the
14423    other classes in your application, there are several other responsibilities
14424    going on under-the-hood that you may want to understand.
14425  
14426    ### Event Delegation
14427  
14428    Ember uses a technique called _event delegation_. This allows the framework
14429    to set up a global, shared event listener instead of requiring each view to
14430    do it manually. For example, instead of each view registering its own
14431    `mousedown` listener on its associated element, Ember sets up a `mousedown`
14432    listener on the `body`.
14433  
14434    If a `mousedown` event occurs, Ember will look at the target of the event and
14435    start walking up the DOM node tree, finding corresponding views and invoking
14436    their `mouseDown` method as it goes.
14437  
14438    `Ember.Application` has a number of default events that it listens for, as
14439    well as a mapping from lowercase events to camel-cased view method names. For
14440    example, the `keypress` event causes the `keyPress` method on the view to be
14441    called, the `dblclick` event causes `doubleClick` to be called, and so on.
14442  
14443    If there is a bubbling browser event that Ember does not listen for by
14444    default, you can specify custom events and their corresponding view method
14445    names by setting the application's `customEvents` property:
14446  
14447    ```javascript
14448    var App = Ember.Application.create({
14449      customEvents: {
14450        // add support for the paste event
14451        paste: 'paste'
14452      }
14453    });
14454    ```
14455  
14456    To prevent Ember from setting up a listener for a default event,
14457    specify the event name with a `null` value in the `customEvents`
14458    property:
14459  
14460    ```javascript
14461    var App = Ember.Application.create({
14462      customEvents: {
14463        // prevent listeners for mouseenter/mouseleave events
14464        mouseenter: null,
14465        mouseleave: null
14466      }
14467    });
14468    ```
14469  
14470    By default, the application sets up these event listeners on the document
14471    body. However, in cases where you are embedding an Ember application inside
14472    an existing page, you may want it to set up the listeners on an element
14473    inside the body.
14474  
14475    For example, if only events inside a DOM element with the ID of `ember-app`
14476    should be delegated, set your application's `rootElement` property:
14477  
14478    ```javascript
14479    var App = Ember.Application.create({
14480      rootElement: '#ember-app'
14481    });
14482    ```
14483  
14484    The `rootElement` can be either a DOM element or a jQuery-compatible selector
14485    string. Note that *views appended to the DOM outside the root element will
14486    not receive events.* If you specify a custom root element, make sure you only
14487    append views inside it!
14488  
14489    To learn more about the advantages of event delegation and the Ember view
14490    layer, and a list of the event listeners that are setup by default, visit the
14491    [Ember View Layer guide](http://emberjs.com/guides/understanding-ember/the-view-layer/#toc_event-delegation).
14492  
14493    ### Initializers
14494  
14495    Libraries on top of Ember can add initializers, like so:
14496  
14497    ```javascript
14498    Ember.Application.initializer({
14499      name: 'api-adapter',
14500  
14501      initialize: function(application) {
14502        application.register('api-adapter:main', ApiAdapter);
14503      }
14504    });
14505    ```
14506  
14507    Initializers provide an opportunity to access the internal registry, which
14508    organizes the different components of an Ember application. Additionally
14509    they provide a chance to access the instantiated application. Beyond
14510    being used for libraries, initializers are also a great way to organize
14511    dependency injection or setup in your own application.
14512  
14513    ### Routing
14514  
14515    In addition to creating your application's router, `Ember.Application` is
14516    also responsible for telling the router when to start routing. Transitions
14517    between routes can be logged with the `LOG_TRANSITIONS` flag, and more
14518    detailed intra-transition logging can be logged with
14519    the `LOG_TRANSITIONS_INTERNAL` flag:
14520  
14521    ```javascript
14522    var App = Ember.Application.create({
14523      LOG_TRANSITIONS: true, // basic logging of successful transitions
14524      LOG_TRANSITIONS_INTERNAL: true // detailed logging of all routing steps
14525    });
14526    ```
14527  
14528    By default, the router will begin trying to translate the current URL into
14529    application state once the browser emits the `DOMContentReady` event. If you
14530    need to defer routing, you can call the application's `deferReadiness()`
14531    method. Once routing can begin, call the `advanceReadiness()` method.
14532  
14533    If there is any setup required before routing begins, you can implement a
14534    `ready()` method on your app that will be invoked immediately before routing
14535    begins.
14536  
14537    @class Application
14538    @namespace Ember
14539    @extends Ember.Engine
14540    @uses RegistryProxyMixin
14541    @public
14542  */
14543
14544  var Application = _emberApplicationSystemEngine.default.extend({
14545    _suppressDeferredDeprecation: true,
14546
14547    /**
14548      The root DOM element of the Application. This can be specified as an
14549      element or a
14550      [jQuery-compatible selector string](http://api.jquery.com/category/selectors/).
14551       This is the element that will be passed to the Application's,
14552      `eventDispatcher`, which sets up the listeners for event delegation. Every
14553      view in your application should be a child of the element you specify here.
14554       @property rootElement
14555      @type DOMElement
14556      @default 'body'
14557      @public
14558    */
14559    rootElement: 'body',
14560
14561    /**
14562      The `Ember.EventDispatcher` responsible for delegating events to this
14563      application's views.
14564       The event dispatcher is created by the application at initialization time
14565      and sets up event listeners on the DOM element described by the
14566      application's `rootElement` property.
14567       See the documentation for `Ember.EventDispatcher` for more information.
14568       @property eventDispatcher
14569      @type Ember.EventDispatcher
14570      @default null
14571      @public
14572    */
14573    eventDispatcher: null,
14574
14575    /**
14576      The DOM events for which the event dispatcher should listen.
14577       By default, the application's `Ember.EventDispatcher` listens
14578      for a set of standard DOM events, such as `mousedown` and
14579      `keyup`, and delegates them to your application's `Ember.View`
14580      instances.
14581       If you would like additional bubbling events to be delegated to your
14582      views, set your `Ember.Application`'s `customEvents` property
14583      to a hash containing the DOM event name as the key and the
14584      corresponding view method name as the value. Setting an event to
14585      a value of `null` will prevent a default event listener from being
14586      added for that event.
14587       To add new events to be listened to:
14588       ```javascript
14589      var App = Ember.Application.create({
14590        customEvents: {
14591          // add support for the paste event
14592          paste: 'paste'
14593        }
14594      });
14595      ```
14596       To prevent default events from being listened to:
14597       ```javascript
14598      var App = Ember.Application.create({
14599        customEvents: {
14600          // remove support for mouseenter / mouseleave events
14601          mouseenter: null,
14602          mouseleave: null
14603        }
14604      });
14605      ```
14606      @property customEvents
14607      @type Object
14608      @default null
14609      @public
14610    */
14611    customEvents: null,
14612
14613    /**
14614      Whether the application should automatically start routing and render
14615      templates to the `rootElement` on DOM ready. While default by true,
14616      other environments such as FastBoot or a testing harness can set this
14617      property to `false` and control the precise timing and behavior of the boot
14618      process.
14619       @property autoboot
14620      @type Boolean
14621      @default true
14622      @private
14623    */
14624    autoboot: true,
14625
14626    /**
14627      Whether the application should be configured for the legacy "globals mode".
14628      Under this mode, the Application object serves as a global namespace for all
14629      classes.
14630       ```javascript
14631      var App = Ember.Application.create({
14632        ...
14633      });
14634       App.Router.reopen({
14635        location: 'none'
14636      });
14637       App.Router.map({
14638        ...
14639      });
14640       App.MyComponent = Ember.Component.extend({
14641        ...
14642      });
14643      ```
14644       This flag also exposes other internal APIs that assumes the existence of
14645      a special "default instance", like `App.__container__.lookup(...)`.
14646       This option is currently not configurable, its value is derived from
14647      the `autoboot` flag – disabling `autoboot` also implies opting-out of
14648      globals mode support, although they are ultimately orthogonal concerns.
14649       Some of the global modes features are already deprecated 
14649in 1.x. The
14650      existence of this flag is to untangle the globals mode code paths from
14651      the autoboot code paths, so that these legacy features can be reviewed
14652      for deprecation/removal separately.
14653       Forcing the (autoboot=true, _globalsMode=false) here and running the tests
14654      would reveal all the places where we are still relying on these legacy
14655      behavior internally (mostly just tests).
14656       @property _globalsMode
14657      @type Boolean
14658      @default true
14659      @private
14660    */
14661    _globalsMode: true,
14662
14663    init: function () {
14664      this._super.apply(this, arguments);
14665
14666      if (!this.$) {
14667        this.$ = _emberViewsSystemJquery.default;
14668      }
14669
14670      registerLibraries();
14671      logLibraryVersions();
14672
14673      // Start off the number of deferrals at 1. This will be decremented by
14674      // the Application's own `boot` method.
14675      this._readinessDeferrals = 1;
14676      this._booted = false;
14677
14678      this.autoboot = this._globalsMode = !!this.autoboot;
14679
14680      if (this._globalsMode) {
14681        this._prepareForGlobalsMode();
14682      }
14683
14684      if (this.autoboot) {
14685        this.waitForDOMReady();
14686      }
14687    },
14688
14689    /**
14690      Create an ApplicationInstance for this application.
14691       @private
14692      @method buildInstance
14693      @return {Ember.ApplicationInstance} the application instance
14694    */
14695    buildInstance: function () {
14696      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
14697
14698      options.base = this;
14699      options.application = this;
14700      return _emberApplicationSystemApplicationInstance.default.create(options);
14701    },
14702
14703    /**
14704      Enable the legacy globals mode by allowing this application to act
14705      as a global namespace. See the docs on the `_globalsMode` property
14706      for details.
14707       Most of these features are already deprecated in 1.x, so we can
14708      stop using them internally and try to remove them.
14709       @private
14710      @method _prepareForGlobalsMode
14711    */
14712    _prepareForGlobalsMode: function () {
14713      // Create subclass of Ember.Router for this Application instance.
14714      // This is to ensure that someone reopening `App.Router` does not
14715      // tamper with the default `Ember.Router`.
14716      this.Router = (this.Router || _emberRoutingSystemRouter.default).extend();
14717
14718      this._buildDeprecatedInstance();
14719    },
14720
14721    /*
14722      Build the deprecated instance for legacy globals mode support.
14723      Called when creating and resetting the application.
14724       This is orthogonal to autoboot: the deprecated instance needs to
14725      be created at Application construction (not boot) time to expose
14726      App.__container__ and the global Ember.View.views registry. If
14727      autoboot sees that this instance exists, it will continue booting
14728      it to avoid doing unncessary work (as opposed to building a new
14729      instance at boot time), but they are otherwise unrelated.
14730       @private
14731      @method _buildDeprecatedInstance
14732    */
14733    _buildDeprecatedInstance: function () {
14734      // Build a default instance
14735      var instance = this.buildInstance();
14736
14737      // Legacy support for App.__container__ and other global methods
14738      // on App that rely on a single, default instance.
14739      this.__deprecatedInstance__ = instance;
14740      this.__container__ = instance.__container__;
14741
14742      // For the default instance only, set the view registry to the global
14743      // Ember.View.views hash for backwards-compatibility.
14744      _emberViewsViewsView.default.views = instance.lookup('-view-registry:main');
14745    },
14746
14747    /**
14748      Automatically kick-off the boot process for the application once the
14749      DOM has become ready.
14750       The initialization itself is scheduled on the actions queue which
14751      ensures that code-loading finishes before booting.
14752       If you are asynchronously loading code, you should call `deferReadiness()`
14753      to defer booting, and then call `advanceReadiness()` once all of your code
14754      has finished loading.
14755       @private
14756      @method waitForDOMReady
14757    */
14758    waitForDOMReady: function () {
14759      if (!this.$ || this.$.isReady) {
14760        _emberMetalRun_loop.default.schedule('actions', this, 'domReady');
14761      } else {
14762        this.$().ready(_emberMetalRun_loop.default.bind(this, 'domReady'));
14763      }
14764    },
14765
14766    /**
14767      This is the autoboot flow:
14768       1. Boot the app by calling `this.boot()`
14769      2. Create an instance (or use the `__deprecatedInstance__` in globals mode)
14770      3. Boot the instance by calling `instance.boot()`
14771      4. Invoke the `App.ready()` callback
14772      5. Kick-off routing on the instance
14773       Ideally, this is all we would need to do:
14774       ```javascript
14775      _autoBoot() {
14776        this.boot().then(() => {
14777          let instance = (this._globalsMode) ? this.__deprecatedInstance__ : this.buildInstance();
14778          return instance.boot();
14779        }).then((instance) => {
14780          App.ready();
14781          instance.startRouting();
14782        });
14783      }
14784      ```
14785       Unfortunately, we cannot actually write this because we need to participate
14786      in the "synchronous" boot process. While the code above would work fine on
14787      the initial boot (i.e. DOM ready), when `App.reset()` is called, we need to
14788      boot a new instance synchronously (see the documentation on `_bootSync()`
14789      for details).
14790       Because of this restriction, the actual logic of this method is located
14791      inside `didBecomeReady()`.
14792       @private
14793      @method domReady
14794    */
14795    domReady: function () {
14796      if (this.isDestroyed) {
14797        return;
14798      }
14799
14800      this._bootSync();
14801
14802      // Continues to `didBecomeReady`
14803    },
14804
14805    /**
14806      Use this to defer readiness until some condition is true.
14807       Example:
14808       ```javascript
14809      var App = Ember.Application.create();
14810       App.deferReadiness();
14811       // Ember.$ is a reference to the jQuery object/function
14812      Ember.$.getJSON('/auth-token', function(token) {
14813        App.token = token;
14814        App.advanceReadiness();
14815      });
14816      ```
14817       This allows you to perform asynchronous setup logic and defer
14818      booting your application until the setup has finished.
14819       However, if the setup requires a loading UI, it might be better
14820      to use the router for this purpose.
14821       @method deferReadiness
14822      @public
14823    */
14824    deferReadiness: function () {
14825      _emberMetalDebug.assert('You must call deferReadiness on an instance of Ember.Application', this instanceof Application);
14826      _emberMetalDebug.assert('You cannot defer readiness since the `ready()` hook has already been called.', this._readinessDeferrals > 0);
14827      this._readinessDeferrals++;
14828    },
14829
14830    /**
14831      Call `advanceReadiness` after any asynchronous setup logic has completed.
14832      Each call to `deferReadiness` must be matched by a call to `advanceReadiness`
14833      or the application will never become ready and routing will not begin.
14834       @method advanceReadiness
14835      @see {Ember.Application#deferReadiness}
14836      @public
14837    */
14838    advanceReadiness: function () {
14839      _emberMetalDebug.assert('You must call advanceReadiness on an instance of Ember.Application', this instanceof Application);
14840      this._readinessDeferrals--;
14841
14842      if (this._readinessDeferrals === 0) {
14843        _emberMetalRun_loop.default.once(this, this.didBecomeReady);
14844      }
14845    },
14846
14847    /**
14848      Initialize the application and return a promise that resolves with the `Ember.Application`
14849      object when the boot process is complete.
14850       Run any application initializers and run the application load hook. These hooks may
14851      choose to defer readiness. For example, an authentication hook might want to defer
14852      readiness until the auth token has been retrieved.
14853       By default, this method is called automatically on "DOM ready"; however, if autoboot
14854      is disabled, this is automatically called when the first application instance is
14855      created via `visit`.
14856       @private
14857      @method boot
14858      @return {Promise<Ember.Application,Error>}
14859    */
14860    boot: function () {
14861      if (this._bootPromise) {
14862        return this._bootPromise;
14863      }
14864
14865      try {
14866        this._bootSync();
14867      } catch (_) {
14868        // Ignore th error: in the asynchronous boot path, the error is already reflected
14869        // in the promise rejection
14870      }
14871
14872      return this._bootPromise;
14873    },
14874
14875    /**
14876      Unfortunately, a lot of existing code assumes the booting process is
14877      "synchronous". Specifically, a lot of tests assumes the last call to
14878      `app.advanceReadiness()` or `app.reset()` will result in the app being
14879      fully-booted when the current runloop completes.
14880       We would like new code (like the `visit` API) to stop making this assumption,
14881      so we created the asynchronous version above that returns a promise. But until
14882      we have migrated all the code, we would have to expose this method for use
14883      *internally* in places where we need to boot an app "synchronously".
14884       @private
14885    */
14886    _bootSync: function () {
14887      if (this._booted) {
14888        return;
14889      }
14890
14891      if (_emberMetal.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT && !warnedAboutLegacyViewAddon) {
14892        _emberMetalDebug.deprecate('Support for the `ember-legacy-views` addon will end soon, please remove it from your application.', false, { id: 'ember-legacy-views', until: '2.6.0', url: 'http://emberjs.com/deprecations/v1.x/#toc_ember-view' });
14893
14894        warnedAboutLegacyViewAddon = true;
14895      }
14896
14897      if (_emberMetal.default.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT && !warnedAboutLegacyControllerAddon) {
14898        _emberMetalDebug.deprecate('Support for the `ember-legacy-controllers` addon will end soon, please remove it from your application.', false, { id: 'ember-legacy-controllers', until: '2.6.0', url: 'http://emberjs.com/deprecations/v1.x/#toc_objectcontroller' });
14899
14900        warnedAboutLegacyControllerAddon = true;
14901      }
14902
14903      // Even though this returns synchronously, we still need to make sure the
14904      // boot promise exists for book-keeping purposes: if anything went wrong in
14905      // the boot process, we need to store the error as a rejection on the boot
14906      // promise so that a future caller of `boot()` can tell what failed.
14907      var defer = this._bootResolver = new _emberRuntimeExtRsvp.default.defer();
14908      this._bootPromise = defer.promise;
14909
14910      try {
14911        this.runInitializers();
14912        _emberRuntimeSystemLazy_load.runLoadHooks('application', this);
14913        this.advanceReadiness();
14914        // Continues to `didBecomeReady`
14915      } catch (error) {
14916        // For the asynchronous boot path
14917        defer.reject(error);
14918
14919        // For the synchronous boot path
14920        throw error;
14921      }
14922    },
14923
14924    /**
14925      Reset the application. This is typically used only in tests. It cleans up
14926      the application in the following order:
14927       1. Deactivate existing routes
14928      2. Destroy all objects in the container
14929      3. Create a new application container
14930      4. Re-route to the existing url
14931       Typical Example:
14932       ```javascript
14933      var App;
14934       run(function() {
14935        App = Ember.Application.create();
14936      });
14937       module('acceptance test', {
14938        setup: function() {
14939          App.reset();
14940        }
14941      });
14942       test('first test', function() {
14943        // App is freshly reset
14944      });
14945       test('second test', function() {
14946        // App is again freshly reset
14947      });
14948      ```
14949       Advanced Example:
14950       Occasionally you may want to prevent the app from initializing during
14951      setup. This could enable extra configuration, or enable asserting prior
14952      to the app becoming ready.
14953       ```javascript
14954      var App;
14955       run(function() {
14956        App = Ember.Application.create();
14957      });
14958       module('acceptance test', {
14959        setup: function() {
14960          run(function() {
14961            App.reset();
14962            App.deferReadiness();
14963          });
14964        }
14965      });
14966       test('first test', function() {
14967        ok(true, 'something before app is initialized');
14968         run(function() {
14969          App.advanceReadiness();
14970        });
14971         ok(true, 'something after app is initialized');
14972      });
14973      ```
14974       @method reset
14975      @public
14976    */
14977    reset: function () {
14978      _emberMetalDebug.assert('Calling reset() on instances of `Ember.Application` is not\n            supported when globals mode is disabled; call `visit()` to\n            create new `Ember.ApplicationInstance`s and dispose them\n            via their `destroy()` method instead.', this._globalsMode && this.autoboot);
14979
14980      var instance = this.__deprecatedInstance__;
14981
14982      this._readinessDeferrals = 1;
14983      this._bootPromise = null;
14984      this._bootResolver = null;
14985      this._booted = false;
14986
14987      function handleReset() {
14988        _emberMetalRun_loop.default(instance, 'destroy');
14989        this._buildDeprecatedInstance();
14990        _emberMetalRun_loop.default.schedule('actions', this, '_bootSync');
14991      }
14992
14993      _emberMetalRun_loop.default.join(this, handleReset);
14994    },
14995
14996    /**
14997      @private
14998      @method didBecomeReady
14999    */
15000    didBecomeReady: function () {
15001      try {
15002        // TODO: Is this still needed for _globalsMode = false?
15003        if (!_emberMetal.default.testing) {
15004          // Eagerly name all classes that are already loaded
15005          _emberMetal.default.Namespace.processAll();
15006          _emberMetal.default.BOOTED = true;
15007        }
15008
15009        // See documentation on `_autoboot()` for details
15010        if (this.autoboot) {
15011          var instance = undefined;
15012
15013          if (this._globalsMode) {
15014            // If we already have the __deprecatedInstance__ lying around, boot it to
15015            // avoid unnecessary work
15016            instance = this.__deprecatedInstance__;
15017          } else {
15018            // Otherwise, build an instance and boot it. This is currently unreachable,
15019            // because we forced _globalsMode to === autoboot; but having this branch
15020            // allows us to locally toggle that flag for weeding out legacy globals mode
15021            // dependencies independently
15022            instance = this.buildInstance();
15023          }
15024
15025          instance._bootSync();
15026
15027          // TODO: App.ready() is not called when autoboot is disabled, is this correct?
15028          this.ready();
15029
15030          instance.startRouting();
15031        }
15032
15033        // For the asynchronous boot path
15034        this._bootResolver.resolve(this);
15035
15036        // For the synchronous boot path
15037        this._booted = true;
15038      } catch (error) {
15039        // For the asynchronous boot path
15040        this._bootResolver.reject(error);
15041
15042        // For the synchronous boot path
15043        throw error;
15044      }
15045    },
15046
15047    /**
15048      Called when the Application has become ready, immediately before routing
15049      begins. The call will be delayed until the DOM has become ready.
15050       @event ready
15051      @public
15052    */
15053    ready: function () {
15054      return this;
15055    },
15056
15057    // This method must be moved to the application instance object
15058    willDestroy: function () {
15059      this._super.apply(this, arguments);
15060      _emberMetal.default.BOOTED = false;
15061      this._booted = false;
15062      this._bootPromise = null;
15063      this._bootResolver = null;
15064
15065      if (_emberRuntimeSystemLazy_load._loaded.application === this) {
15066        _emberRuntimeSystemLazy_load._loaded.application = undefined;
15067      }
15068
15069      if (this._globalsMode && this.__deprecatedInstance__) {
15070        this.__deprecatedInstance__.destroy();
15071      }
15072    }
15073  });
15074
15075  Object.defineProperty(Application.prototype, 'registry', {
15076    configurable: true,
15077    enumerable: false,
15078    get: function () {
15079      return _emberRuntimeMixinsRegistry_proxy.buildFakeRegistryWithDeprecations(this, 'Application');
15080    }
15081  });
15082
15083  Application.reopen({
15084    /**
15085      Boot a new instance of `Ember.ApplicationInstance` for the current
15086      application and navigate it to the given `url`. Returns a `Promise` that
15087      resolves with the instance when the initial routing and rendering is
15088      complete, or rejects with any error that occured during the boot process.
15089       When `autoboot` is disabled, calling `visit` would first cause the
15090      application to boot, which runs the application initializers.
15091       This method also takes a hash of boot-time configuration options for
15092      customizing the instance's behavior. See the documentation on
15093      `Ember.ApplicationInstance.BootOptions` for details.
15094       `Ember.ApplicationInstance.BootOptions` is an interface class that exists
15095      purely to document the available options; you do not need to construct it
15096      manually. Simply pass a regular JavaScript object containing of the
15097      desired options:
15098       ```javascript
15099      MyApp.visit("/", { location: "none", rootElement: "#container" });
15100      ```
15101       ### Supported Scenarios
15102       While the `BootOptions` class exposes a large number of knobs, not all
15103      combinations of them are valid; certain incompatible combinations might
15104      result in unexpected behavior.
15105       For example, booting the instance in the full browser environment
15106      while specifying a foriegn `document` object (e.g. `{ isBrowser: true,
15107      document: iframe.contentDocument }`) does not work correctly today,
15108      largely due to Ember's jQuery dependency.
15109       Currently, there are three officially supported scenarios/configurations.
15110      Usages outside of these scenarios are not guaranteed to work, but please
15111      feel free to file bug reports documenting your experience and any issues
15112      you encountered to help expand support.
15113       #### Browser Applications (Manual Boot)
15114       The setup is largely similar to how Ember works out-of-the-box. Normally,
15115      Ember will boot a default instance for your Application on "DOM ready".
15116      However, you can customize this behavior by disabling `autoboot`.
15117       For example, this allows you to render a miniture demo of your application
15118      into a specific area on your marketing website:
15119       ```javascript
15120      import MyApp from 'my-app';
15121       $(function() {
15122        let App = MyApp.create({ autoboot: false });
15123         let options = {
15124          // Override the router's location adapter to prevent it from updating
15125          // the URL in the address bar
15126          location: 'none',
15127           // Override the default `rootElement` on the app to render into a
15128          // specific `div` on the page
15129          rootElement: '#demo'
15130        };
15131         // Start the app at the special demo URL
15132        App.visit('/demo', options);
15133      });
15134      ````
15135       Or perhaps you might want to boot two instances of your app on the same
15136      page for a split-screen multiplayer experience:
15137       ```javascript
15138      import MyApp from 'my-app';
15139       $(function() {
15140        let App = MyApp.create({ autoboot: false });
15141         let sessionId = MyApp.generateSessionID();
15142         let player1 = App.visit(`/matches/join?name=Player+1&session=${sessionId}`, { rootElement: '#left', location: 'none' });
15143        let player2 = App.visit(`/matches/join?name=Player+2&session=${sessionId}`, { rootElement: '#right', location: 'none' });
15144         Promise.all([player1, player2]).then(() => {
15145          // Both apps have completed the initial render
15146          $('#loading').fadeOut();
15147        });
15148      });
15149      ```
15150       Do note that each app instance maintains their own registry/container, so
15151      they will run in complete isolation by default.
15152       #### Server-Side Rendering (also known as FastBoot)
15153       This setup allows you to run your Ember app in a server environment using
15154      Node.js and render its content into static HTML for SEO purposes.
15155       ```javascript
15156      const HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap);
15157       function renderURL(url) {
15158        let dom = new SimpleDOM.Document();
15159        let rootElement = dom.body;
15160        let options = { isBrowser: false, document: dom, rootElement: rootElement };
15161         return MyApp.visit(options).then(instance => {
15162          try {
15163            return HTMLSerializer.serialize(rootElement.firstChild);
15164          } finally {
15165            instance.destroy();
15166          }
15167        });
15168      }
15169      ```
15170       In this scenario, because Ember does not have access to a global `document`
15171      object in the Node.js environment, you must provide one explicitly. In practice,
15172      in the non-browser environment, the stand-in `document` object only need to
15173      implement a limited subset of the full DOM API. The `SimpleDOM` library is known
15174      to work.
15175       Since there is no access to jQuery in the non-browser environment, you must also
15176      specify a DOM `Element` object in the same `document` for the `rootElement` option
15177      (as opposed to a selector string like `"body"`).
15178       See the documentation on the `isBrowser`, `document` and `rootElement` properties
15179      on `Ember.ApplicationInstance.BootOptions` for details.
15180       #### Server-Side Resource Discovery
15181       This setup allows you to run the routing layer of your Ember app in a server
15182      environment using Node.js and completely disable rendering. This allows you
15183      to simulate and discover the resources (i.e. AJAX requests) needed to fufill
15184      a given request and eagerly "push" these resources to the client.
15185       ```app/initializers/network-service.js
15186      import BrowserNetworkService from 'app/services/network/browser';
15187      import NodeNetworkService from 'app/services/network/node';
15188       // Inject a (hypothetical) service for abstracting all AJAX calls and use
15189      // the appropiate implementaion on the client/server. This also allows the
15190      // server to log all the AJAX calls made during a particular request and use
15191      // that for resource-discovery purpose.
15192       export function initialize(application) {
15193        if (window) { // browser
15194          application.register('service:network', BrowserNetworkService);
15195        } else { // node
15196          application.register('service:network', NodeNetworkService);
15197        }
15198         application.inject('route', 'network', 'service:network');
15199      };
15200       export default {
15201        name: 'network-service',
15202        initialize: initialize
15203      };
15204      ```
15205       ```app/routes/post.js
15206      import Ember from 'ember';
15207       // An example of how the (hypothetical) service is used in routes.
15208       export default Ember.Route.extend({
15209        model(params) {
15210          return this.network.fetch(`/api/posts/${params.post_id}.json`);
15211        },
15212         afterModel(post) {
15213          if (post.isExternalContent) {
15214            return this.network.fetch(`/api/external/?url=${post.externalURL}`);
15215          } else {
15216            return post;
15217          }
15218        }
15219      });
15220      ```
15221       ```javascript
15222      // Finally, put all the pieces together
15223       function discoverResourcesFor(url) {
15224        return MyApp.visit(url, { isBrowser: false, shouldRender: false }).then(instance => {
15225          let networkService = instance.lookup('service:network');
15226          return networkService.requests; // => { "/api/posts/123.json": "..." }
15227        });
15228      }
15229      ```
15230       @public
15231      @method visit
15232      @param url {String} The initial URL to navigate to
15233      @param options {Ember.ApplicationInstance.BootOptions}
15234      @return {Promise<Ember.ApplicationInstance, Error>}
15235    */
15236    visit: function (url, options) {
15237      var _this = this;
15238
15239      return this.boot().then(function () {
15240        return _this.buildInstance().boot(options).then(function (instance) {
15241          return instance.visit(url);
15242        });
15243      });
15244    }
15245  });
15246
15247  Application.reopenClass({
15248    /**
15249      This creates a registry with the default Ember naming conventions.
15250       It also configures the registry:
15251       * registered views are created every time they are looked up (they are
15252        not singletons)
15253      * registered templates are not factories; the registered value is
15254        returned directly.
15255      * the router receives the application as its `namespace` property
15256      * all controllers receive the router as their `target` and `controllers`
15257        properties
15258      * all controllers receive the application as their `namespace` property
15259      * the application view receives the application controller as its
15260        `controller` property
15261      * the application view receives the application template as its
15262        `defaultTemplate` property
15263       @private
15264      @method buildRegistry
15265      @static
15266      @param {Ember.Application} namespace the application for which to
15267        build the registry
15268      @return {Ember.Registry} the built registry
15269      @public
15270    */
15271    buildRegistry: function (namespace) {
15272      var registry = this._super.apply(this, arguments);
15273
15274      registry.optionsForType('component', { singleton: false });
15275      registry.optionsForType('view', { singleton: false });
15276      registry.optionsForType('template', { instantiate: false });
15277
15278      registry.register('application:main', namespace, { instantiate: false });
15279
15280      registry.register('controller:basic', _emberRuntimeControllersController.default, { instantiate: false });
15281
15282      registry.register('renderer:-dom', { create: function () {
15283          return new _emberMetalViews.Renderer(new _emberHtmlbarsSystemDomHelper.default());
15284        } });
15285
15286      registry.injection('view', 'renderer', 'renderer:-dom');
15287      if (_emberMetal.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
15288        registry.register('view:select', _emberViewsViewsSelect.default);
15289      }
15290      registry.register('view:-outlet', _emberRoutingViewsViewsOutlet.OutletView);
15291
15292      registry.register('-view-registry:main', { create: function () {
15293          return {};
15294        } });
15295
15296      registry.injection('view', '_viewRegistry', '-view-registry:main');
15297
15298      registry.register('view:toplevel', _emberViewsViewsView.default.extend());
15299
15300      registry.register('route:basic', _emberRoutingSystemRoute.default, { instantiate: false });
15301      registry.register('event_dispatcher:main', _emberViewsSystemEvent_dispatcher.default);
15302
15303      registry.injection('router:main', 'namespace', 'application:main');
15304      registry.injection('view:-outlet', 'namespace', 'application:main');
15305
15306      registry.register('location:auto', _emberRoutingLocationAuto_location.default);
15307      registry.register('location:hash', _emberRoutingLocationHash_location.default);
15308      registry.register('location:history', _emberRoutingLocationHistory_location.default);
15309      registry.register('location:none', _emberRoutingLocationNone_location.default);
15310
15311      registry.injection('controller', 'target', 'router:main');
15312      registry.injection('controller', 'namespace', 'application:main');
15313
15314      registry.register('-bucket-cache:main', _emberRoutingSystemCache.default);
15315      registry.injection('router', '_bucketCache', '-bucket-cache:main');
15316      registry.injection('route', '_bucketCache', '-bucket-cache:main');
15317      registry.injection('controller', '_bucketCache', '-bucket-cache:main');
15318
15319      registry.injection('route', 'router', 'router:main');
15320
15321      registry.register('component:-text-field', _emberViewsViewsText_field.default);
15322      registry.register('component:-text-area', _emberViewsViewsText_area.default);
15323      registry.register('component:-checkbox', _emberViewsViewsCheckbox.default);
15324      registry.register('view:-legacy-each', _emberViewsViewsLegacy_each_view.default);
15325      registry.register('component:link-to', _emberRoutingViewsComponentsLinkTo.default);
15326
15327      // Register the routing service...
15328      registry.register('service:-routing', _emberRoutingServicesRouting.default);
15329      // Then inject the app router into it
15330      registry.injection('service:-routing', 'router', 'router:main');
15331
15332      // DEBUGGING
15333      registry.register('resolver-for-debugging:main', registry.resolver, { instantiate: false });
15334      registry.injection('container-debug-adapter:main', 'resolver', 'resolver-for-debugging:main');
15335      registry.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main');
15336      // Custom resolver authors may want to register their own ContainerDebugAdapter with this key
15337
15338      registry.register('container-debug-adapter:main', _emberExtensionSupportContainer_debug_adapter.default);
15339
15340      return registry;
15341    }
15342  });
15343
15344  function registerLibraries() {
15345    if (!librariesRegistered) {
15346      librariesRegistered = true;
15347
15348      if (_emberMetalEnvironment.default.hasDOM) {
15349        _emberMetal.default.libraries.registerCoreLibrary('jQuery', _emberViewsSystemJquery.default().jquery);
15350      }
15351    }
15352  }
15353
15354  function logLibraryVersions() {
15355    if (_emberMetal.default.LOG_VERSION) {
15356      // we only need to see this once per Application#init
15357      _emberMetal.default.LOG_VERSION = false;
15358      var libs = _emberMetal.default.libraries._registry;
15359
15360      var nameLengths = libs.map(function (item) {
15361        return _emberMetalProperty_get.get(item, 'name.length');
15362      });
15363
15364      var maxNameLength = Math.max.apply(this, nameLengths);
15365
15366      _emberMetalDebug.debug('-------------------------------');
15367      for (var i = 0, l = libs.length; i < l; i++) {
15368        var lib = libs[i];
15369        var spaces = new Array(maxNameLength - lib.name.length + 1).join(' ');
15370        _emberMetalDebug.debug([lib.name, spaces, ' : ', lib.version].join(''));
15371      }
15372      _emberMetalDebug.debug('-------------------------------');
15373    }
15374  }
15375
15376  exports.default = Application;
15377});
15378// Ember.libraries, LOG_VERSION, Namespace, BOOTED
15379
15380// Force-assign these flags to their default values when the feature is
15381// disabled, this ensures we can rely on their values in other paths.
15382enifed('ember-application/system/engine-instance', ['exports', 'ember-runtime/system/object', 'container/registry', 'ember-runtime/mixins/container_proxy', 'ember-runtime/mixins/registry_proxy', 'ember-metal/run_loop'], function (exports, _emberRuntimeSystemObject, _containerRegistry, _emberRuntimeMixinsContainer_proxy, _emberRuntimeMixinsRegistry_proxy, _emberMetalRun_loop) {
15383  /**
15384  @module ember
15385  @submodule ember-application
15386  */
15387
15388  'use strict';
15389
15390  /**
15391    The `EngineInstance` encapsulates all of the stateful aspects of a
15392    running `Engine`.
15393  
15394    @public
15395    @class Ember.EngineInstance
15396    @extends Ember.Object
15397    @uses RegistryProxyMixin
15398    @uses ContainerProxyMixin
15399    @category ember-application-engines
15400  */
15401
15402  var EngineInstance = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsRegistry_proxy.default, _emberRuntimeMixinsContainer_proxy.default, {
15403    /**
15404      The base `Engine` for which this is an instance.
15405       @property {Ember.Engine} engine
15406      @private
15407    */
15408    base: null,
15409
15410    init: function () {
15411      this._super.apply(this, arguments);
15412
15413      var base = this.base;
15414
15415      if (!base) {
15416        base = this.application;
15417        this.base = base;
15418      }
15419
15420      // Create a per-instance registry that will use the application's registry
15421      // as a fallback for resolving registrations.
15422      var registry = this.__registry__ = new _containerRegistry.default({
15423        fallback: base.__registry__
15424      });
15425
15426      // Create a per-instance container from the instance's registry
15427      this.__container__ = registry.container({ owner: this });
15428    },
15429
15430    /**
15431     Unregister a factory.
15432      Overrides `RegistryProxy#unregister` in order to clear any cached instances
15433     of the unregistered factory.
15434      @public
15435     @method unregister
15436     @param {String} fullName
15437     */
15438    unregister: function (fullName) {
15439      this.__container__.reset(fullName);
15440      this._super.apply(this, arguments);
15441    },
15442
15443    /**
15444      @private
15445    */
15446    willDestroy: function () {
15447      this._super.apply(this, arguments);
15448      _emberMetalRun_loop.default(this.__container__, 'destroy');
15449    }
15450  });
15451
15452  exports.default = EngineInstance;
15453});
15454enifed('ember-application/system/engine', ['exports', 'ember-runtime/system/namespace', 'container/registry', 'ember-runtime/mixins/registry_proxy', 'dag-map', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/empty_object', 'ember-application/system/resolver', 'ember-application/system/engine-instance'], function (exports, _emberRuntimeSystemNamespace, _containerRegistry, _emberRuntimeMixinsRegistry_proxy, _dagMap, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalDebug, _emberMetalUtils, _emberMetalEmpty_object, _emberApplicationSystemResolver, _emberApplicationSystemEngineInstance) {
15455  /**
15456  @module ember
15457  @submodule ember-application
15458  */
15459  'use strict';
15460
15461  function props(obj) {
15462    var properties = [];
15463
15464    for (var key in obj) {
15465      properties.push(key);
15466    }
15467
15468    return properties;
15469  }
15470
15471  /**
15472    The `Engine` class contains core functionality for both applications and
15473    engines.
15474  
15475    Each engine manages a registry that's used for dependency injection and
15476    exposed through `RegistryProxy`.
15477  
15478    Engines also manage initializers and instance initializers.
15479  
15480    Engines can spawn `EngineInstance` instances via `buildInstance()`.
15481  
15482    @class Engine
15483    @namespace Ember
15484    @extends Ember.Namespace
15485    @uses RegistryProxy
15486    @category ember-application-engines
15487    @public
15488  */
15489  var Engine = _emberRuntimeSystemNamespace.default.extend(_emberRuntimeMixinsRegistry_proxy.default, {
15490    init: function () {
15491      this._super.apply(this, arguments);
15492
15493      this.buildRegistry();
15494    },
15495
15496    /**
15497      Create an EngineInstance for this application.
15498       @private
15499      @method buildInstance
15500      @return {Ember.EngineInstance} the application instance
15501    */
15502    buildInstance: function () {
15503      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
15504
15505      options.base = this;
15506      return _emberApplicationSystemEngineInstance.default.create(options);
15507    },
15508
15509    /**
15510      Build and configure the registry for the current application.
15511       @private
15512      @method buildRegistry
15513      @return {Ember.Registry} the configured registry
15514    */
15515    buildRegistry: function () {
15516      var registry = this.__registry__ = this.constructor.buildRegistry(this);
15517
15518      return registry;
15519    },
15520
15521    /**
15522      @private
15523      @method initializer
15524    */
15525    initializer: function (options) {
15526      this.constructor.initializer(options);
15527    },
15528
15529    /**
15530      @private
15531      @method instanceInitializer
15532    */
15533    instanceInitializer: function (options) {
15534      this.constructor.instanceInitializer(options);
15535    },
15536
15537    /**
15538      @private
15539      @method runInitializers
15540    */
15541    runInitializers: function () {
15542      var _this = this;
15543
15544      this._runInitializer('initializers', function (name, initializer) {
15545        _emberMetalDebug.assert('No application initializer named \'' + name + '\'', !!initializer);
15546        if (initializer.initialize.length === 2) {
15547          _emberMetalDebug.deprecate('The `initialize` method for Application initializer \'' + name + '\' should take only one argument - `App`, an instance of an `Application`.', false, {
15548            id: 'ember-application.app-initializer-initialize-arguments',
15549            until: '3.0.0',
15550            url: 'http://emberjs.com/deprecations/v2.x/#toc_initializer-arity'
15551          });
15552
15553          initializer.initialize(_this.__registry__, _this);
15554        } else {
15555          initializer.initialize(_this);
15556        }
15557      });
15558    },
15559
15560    /**
15561      @private
15562      @since 1.12.0
15563      @method runInstanceInitializers
15564    */
15565    runInstanceInitializers: function (instance) {
15566      this._runInitializer('instanceInitializers', function (name, initializer) {
15567        _emberMetalDebug.assert('No instance initializer named \'' + name + '\'', !!initializer);
15568        initializer.initialize(instance);
15569      });
15570    },
15571
15572    _runInitializer: function (bucketName, cb) {
15573      var initializersByName = _emberMetalProperty_get.get(this.constructor, bucketName);
15574      var initializers = props(initializersByName);
15575      var graph = new _dagMap.default();
15576      var initializer;
15577
15578      for (var i = 0; i < initializers.length; i++) {
15579        initializer = initializersByName[initializers[i]];
15580        graph.addEdges(initializer.name, initializer, initializer.before, initializer.after);
15581      }
15582
15583      graph.topsort(function (vertex) {
15584        cb(vertex.name, vertex.value);
15585      });
15586    }
15587  });
15588
15589  Engine.reopenClass({
15590    initializers: new _emberMetalEmpty_object.default(),
15591    instanceInitializers: new _emberMetalEmpty_object.default(),
15592
15593    /**
15594      The goal of initializers should be to register dependencies and injections.
15595      This phase runs once. Because these initializers may load code, they are
15596      allowed to defer application readiness and advance it. If you need to access
15597      the container or store you should use an InstanceInitializer that will be run
15598      after all initializers and therefore after all code is loaded and the app is
15599      ready.
15600       Initializer receives an object which has the following attributes:
15601      `name`, `before`, `after`, `initialize`. The only required attribute is
15602      `initialize`, all others are optional.
15603       * `name` allows you to specify under which name the initializer is registered.
15604      This must be a unique name, as trying to register two initializer
15604s with the
15605      same name will result in an error.
15606       ```javascript
15607      Ember.Application.initializer({
15608        name: 'namedInitializer',
15609         initialize: function(application) {
15610          Ember.debug('Running namedInitializer!');
15611        }
15612      });
15613      ```
15614       * `before` and `after` are used to ensure that this initializer is ran prior
15615      or after the one identified by the value. This value can be a single string
15616      or an array of strings, referencing the `name` of other initializers.
15617       An example of ordering initializers, we create an initializer named `first`:
15618       ```javascript
15619      Ember.Application.initializer({
15620        name: 'first',
15621         initialize: function(application) {
15622          Ember.debug('First initializer!');
15623        }
15624      });
15625       // DEBUG: First initializer!
15626      ```
15627       We add another initializer named `second`, specifying that it should run
15628      after the initializer named `first`:
15629       ```javascript
15630      Ember.Application.initializer({
15631        name: 'second',
15632        after: 'first',
15633         initialize: function(application) {
15634          Ember.debug('Second initializer!');
15635        }
15636      });
15637       // DEBUG: First initializer!
15638      // DEBUG: Second initializer!
15639      ```
15640       Afterwards we add a further initializer named `pre`, this time specifying
15641      that it should run before the initializer named `first`:
15642       ```javascript
15643      Ember.Application.initializer({
15644        name: 'pre',
15645        before: 'first',
15646         initialize: function(application) {
15647          Ember.debug('Pre initializer!');
15648        }
15649      });
15650       // DEBUG: Pre initializer!
15651      // DEBUG: First initializer!
15652      // DEBUG: Second initializer!
15653      ```
15654       Finally we add an initializer named `post`, specifying it should run after
15655      both the `first` and the `second` initializers:
15656       ```javascript
15657      Ember.Application.initializer({
15658        name: 'post',
15659        after: ['first', 'second'],
15660         initialize: function(application) {
15661          Ember.debug('Post initializer!');
15662        }
15663      });
15664       // DEBUG: Pre initializer!
15665      // DEBUG: First initializer!
15666      // DEBUG: Second initializer!
15667      // DEBUG: Post initializer!
15668      ```
15669       * `initialize` is a callback function that receives one argument,
15670        `application`, on which you can operate.
15671       Example of using `application` to register an adapter:
15672       ```javascript
15673      Ember.Application.initializer({
15674        name: 'api-adapter',
15675         initialize: function(application) {
15676          application.register('api-adapter:main', ApiAdapter);
15677        }
15678      });
15679      ```
15680       @method initializer
15681      @param initializer {Object}
15682      @public
15683    */
15684
15685    initializer: buildInitializerMethod('initializers', 'initializer'),
15686
15687    /**
15688      Instance initializers run after all initializers have run. Because
15689      instance initializers run after the app is fully set up. We have access
15690      to the store, container, and other items. However, these initializers run
15691      after code has loaded and are not allowed to defer readiness.
15692       Instance initializer receives an object which has the following attributes:
15693      `name`, `before`, `after`, `initialize`. The only required attribute is
15694      `initialize`, all others are optional.
15695       * `name` allows you to specify under which name the instanceInitializer is
15696      registered. This must be a unique name, as trying to register two
15697      instanceInitializer with the same name will result in an error.
15698       ```javascript
15699      Ember.Application.instanceInitializer({
15700        name: 'namedinstanceInitializer',
15701         initialize: function(application) {
15702          Ember.debug('Running namedInitializer!');
15703        }
15704      });
15705      ```
15706       * `before` and `after` are used to ensure that this initializer is ran prior
15707      or after the one identified by the value. This value can be a single string
15708      or an array of strings, referencing the `name` of other initializers.
15709       * See Ember.Application.initializer for discussion on the usage of before
15710      and after.
15711       Example instanceInitializer to preload data into the store.
15712       ```javascript
15713      Ember.Application.initializer({
15714        name: 'preload-data',
15715         initialize: function(application) {
15716          var userConfig, userConfigEncoded, store;
15717          // We have a HTML escaped JSON representation of the user's basic
15718          // configuration generated server side and stored in the DOM of the main
15719          // index.html file. This allows the app to have access to a set of data
15720          // without making any additional remote calls. Good for basic data that is
15721          // needed for immediate rendering of the page. Keep in mind, this data,
15722          // like all local models and data can be manipulated by the user, so it
15723          // should not be relied upon for security or authorization.
15724          //
15725          // Grab the encoded data from the meta tag
15726          userConfigEncoded = Ember.$('head meta[name=app-user-config]').attr('content');
15727          // Unescape the text, then parse the resulting JSON into a real object
15728          userConfig = JSON.parse(unescape(userConfigEncoded));
15729          // Lookup the store
15730          store = application.lookup('service:store');
15731          // Push the encoded JSON into the store
15732          store.pushPayload(userConfig);
15733        }
15734      });
15735      ```
15736       @method instanceInitializer
15737      @param instanceInitializer
15738      @public
15739    */
15740    instanceInitializer: buildInitializerMethod('instanceInitializer
15740s', 'instance initializer'),
15741
15742    /**
15743      This creates a registry with the default Ember naming conventions.
15744       It also configures the registry:
15745       * registered views are created every time they are looked up (they are
15746        not singletons)
15747      * registered templates are not factories; the registered value is
15748        returned directly.
15749      * the router receives the application as its `namespace` property
15750      * all controllers receive the router as their `target` and `controllers`
15751        properties
15752      * all controllers receive the application as their `namespace` property
15753      * the application view receives the application controller as its
15754        `controller` property
15755      * the application view receives the application template as its
15756        `defaultTemplate` property
15757       @private
15758      @method buildRegistry
15759      @static
15760      @param {Ember.Application} namespace the application for which to
15761        build the registry
15762      @return {Ember.Registry} the built registry
15763      @public
15764    */
15765    buildRegistry: function (namespace) {
15766      var registry = new _containerRegistry.default({
15767        resolver: resolverFor(namespace)
15768      });
15769
15770      registry.set = _emberMetalProperty_set.set;
15771
15772      return registry;
15773    },
15774
15775    /**
15776      Set this to provide an alternate class to `Ember.DefaultResolver`
15777        @deprecated Use 'Resolver' instead
15778      @property resolver
15779      @public
15780    */
15781    resolver: null,
15782
15783    /**
15784      Set this to provide an alternate class to `Ember.DefaultResolver`
15785       @property resolver
15786      @public
15787    */
15788    Resolver: null
15789  });
15790
15791  /**
15792    This function defines the default lookup rules for container lookups:
15793  
15794    * templates are looked up on `Ember.TEMPLATES`
15795    * other names are looked up on the application after classifying the name.
15796      For example, `controller:post` looks up `App.PostController` by default.
15797    * if the default lookup fails, look for registered classes on the container
15798  
15799    This allows the application to register default injections in the container
15800    that could be overridden by the normal naming convention.
15801  
15802    @private
15803    @method resolverFor
15804    @param {Ember.Namespace} namespace the namespace to look for classes
15805    @return {*} the resolved value for a given lookup
15806  */
15807  function resolverFor(namespace) {
15808    var ResolverClass = namespace.get('Resolver') || _emberApplicationSystemResolver.default;
15809
15810    return ResolverClass.create({
15811      namespace: namespace
15812    });
15813  }
15814
15815  function buildInitializerMethod(bucketName, humanName) {
15816    return function (initializer) {
15817      // If this is the first initializer being added to a subclass, we are going to reopen the class
15818      // to make sure we have a new `initializers` object, which extends from the parent class' using
15819      // prototypal inheritance. Without this, attempting to add initializers to the subclass would
15820      // pollute the parent class as well as other subclasses.
15821      if (this.superclass[bucketName] !== undefined && this.superclass[bucketName] === this[bucketName]) {
15822        var attrs = {};
15823        attrs[bucketName] = Object.create(this[bucketName]);
15824        this.reopenClass(attrs);
15825      }
15826
15827      _emberMetalDebug.assert('The ' + humanName + ' \'' + initializer.name + '\' has already been registered', !this[bucketName][initializer.name]);
15828      _emberMetalDebug.assert('An ' + humanName + ' cannot be registered without an initialize function', _emberMetalUtils.canInvoke(initializer, 'initialize'));
15829      _emberMetalDebug.assert('An ' + humanName + ' cannot be registered without a name property', initializer.name !== undefined);
15830
15831      this[bucketName][initializer.name] = initializer;
15832    };
15833  }
15834
15835  exports.default = Engine;
15836});
15837enifed('ember-application/system/resolver', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-runtime/system/string', 'ember-runtime/system/object', 'ember-runtime/system/namespace', 'ember-htmlbars/helpers', 'ember-application/utils/validate-type', 'ember-metal/dictionary', 'ember-htmlbars/template_registry'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberRuntimeSystemString, _emberRuntimeSystemObject, _emberRuntimeSystemNamespace, _emberHtmlbarsHelpers, _emberApplicationUtilsValidateType, _emberMetalDictionary, _emberHtmlbarsTemplate_registry) {
15838  /**
15839  @module ember
15840  @submodule ember-application
15841  */
15842
15843  'use strict';
15844
15845  var Resolver = _emberRuntimeSystemObject.default.extend({
15846    /*
15847      This will be set to the Application instance when it is
15848      created.
15849       @property namespace
15850    */
15851    namespace: null,
15852    normalize: null, // required
15853    resolve: null, // required
15854    parseName: null, // required
15855    lookupDescription: null, // required
15856    makeToString: null, // required
15857    resolveOther: null, // required
15858    _logLookup: null // required
15859  });
15860
15861  exports.Resolver = Resolver;
15862  /**
15863    The DefaultResolver defines the default lookup rules to resolve
15864    container lookups before consulting the container for registered
15865    items:
15866  
15867    * templates are looked up on `Ember.TEMPLATES`
15868    * other names are looked up on the application after converting
15869      the name. For example, `controller:post` looks up
15870      `App.PostController` by default.
15871    * there are some nuances (see examples below)
15872  
15873    ### How Resolving Works
15874  
15875    The container calls this object's `resolve` method with the
15876    `fullName` argument.
15877  
15878    It first parses the fullName into an object using `parseName`.
15879  
15880    Then it checks for the presence of a type-specific instance
15881    method of the form `resolve[Type]` and calls it if it exists.
15882    For example if it was resolving 'template:post', it would call
15883    the `resolveTemplate` method.
15884  
15885    Its last resort is to call the `resolveOther` method.
15886  
15887    The methods of this object are designed to be easy to override
15888    in a subclass. For example, you could enhance how a template
15889    is resolved like so:
15890  
15891    ```javascript
15892    App = Ember.Application.create({
15893      Resolver: Ember.DefaultResolver.extend({
15894        resolveTemplate: function(parsedName) {
15895          var resolvedTemplate = this._super(parsedName);
15896          if (resolvedTemplate) { return resolvedTemplate; }
15897          return Ember.TEMPLATES['not_found'];
15898        }
15899      })
15900    });
15901    ```
15902  
15903    Some examples of how names are resolved:
15904  
15905    ```
15906    'template:post'           //=> Ember.TEMPLATES['post']
15907    'template:posts/byline'   //=> Ember.TEMPLATES['posts/byline']
15908    'template:posts.byline'   //=> Ember.TEMPLATES['posts/byline']
15909    'template:blogPost'       //=> Ember.TEMPLATES['blogPost']
15910                              //   OR
15911                              //   Ember.TEMPLATES['blog_post']
15912    'controller:post'         //=> App.PostController
15913    'controller:posts.index'  //=> App.PostsIndexController
15914    'controller:blog/post'    //=> Blog.PostController
15915    'controller:basic'        //=> Ember.Controller
15916    'route:post'              //=> App.PostRoute
15917    'route:posts.index'       //=> App.PostsIndexRoute
15918    'route:blog/post'         //=> Blog.PostRoute
15919    'route:basic'             //=> Ember.Route
15920    'view:post'               //=> App.PostView
15921    'view:posts.index'        //=> App.PostsIndexView
15922    'view:blog/post'          //=> Blog.PostView
15923    'view:basic'              //=> Ember.View
15924    'foo:post'                //=> App.PostFoo
15925    'model:post'              //=> App.Post
15926    ```
15927  
15928    @class DefaultResolver
15929    @namespace Ember
15930    @extends Ember.Object
15931    @public
15932  */
15933
15934  exports.default = _emberRuntimeSystemObject.default.extend({
15935    /**
15936      This will be set to the Application instance when it is
15937      created.
15938       @property namespace
15939      @public
15940    */
15941    namespace: null,
15942
15943    init: function () {
15944      this._parseNameCache = _emberMetalDictionary.default(null);
15945    },
15946    normalize: function (fullName) {
15947      var _fullName$split = fullName.split(':', 2);
15948
15949      var type = _fullName$split[0];
15950      var name = _fullName$split[1];
15951
15952      _emberMetalDebug.assert('Tried to normalize a container name without a colon (:) in it. ' + 'You probably tried to lookup a name that did not contain a type, ' + 'a colon, and a name. A proper lookup name would be `view:post`.', fullName.split(':').length === 2);
15953
15954      if (type !== 'template') {
15955        var result = name;
15956
15957        if (result.indexOf('.') > -1) {
15958          result = result.replace(/\.(.)/g, function (m) {
15959            return m.charAt(1).toUpperCase();
15960          });
15961        }
15962
15963        if (name.indexOf('_') > -1) {
15964          result = result.replace(/_(.)/g, function (m) {
15965            return m.charAt(1).toUpperCase();
15966          });
15967        }
15968
15969        if (name.indexOf('-') > -1) {
15970          result = result.replace(/-(.)/g, function (m) {
15971            return m.charAt(1).toUpperCase();
15972          });
15973        }
15974
15975        return type + ':' + result;
15976      } else {
15977        return fullName;
15978      }
15979    },
15980
15981    /**
15982      This method is called via the container's resolver method.
15983      It parses the provided `fullName` and then looks up and
15984      returns the appropriate template or class.
15985       @method resolve
15986      @param {String} fullName the lookup string
15987      @return {Object} the resolved factory
15988      @public
15989    */
15990    resolve: function (fullName) {
15991      var parsedName = this.parseName(fullName);
15992      var resolveMethodName = parsedName.resolveMethodName;
15993      var resolved;
15994
15995      if (this[resolveMethodName]) {
15996        resolved = this[resolveMethodName](parsedName);
15997      }
15998
15999      resolved = resolved || this.resolveOther(parsedName);
16000
16001      if (parsedName.root && parsedName.root.LOG_RESOLVER) {
16002        this._logLookup(resolved, parsedName);
16003      }
16004
16005      if (resolved) {
16006        _emberApplicationUtilsValidateType.default(resolved, parsedName);
16007      }
16008
16009      return resolved;
16010    },
16011
16012    /**
16013      Convert the string name of the form 'type:name' to
16014      a Javascript object with the parsed aspects of the name
16015      broken out.
16016       @protected
16017      @param {String} fullName the lookup string
16018      @method parseName
16019      @public
16020    */
16021
16022    parseName: function (fullName) {
16023      return this._parseNameCache[fullName] || (this._parseNameCache[fullName] = this._parseName(fullName));
16024    },
16025
16026    _parseName: function (fullName) {
16027      var _fullName$split2 = fullName.split(':');
16028
16029      var type = _fullName$split2[0];
16030      var fullNameWithoutType = _fullName$split2[1];
16031
16032      var name = fullNameWithoutType;
16033      var namespace = _emberMetalProperty_get.get(this, 'namespace');
16034      var root = namespace;
16035      var lastSlashIndex = name.lastIndexOf('/');
16036      var dirname = lastSlashIndex !== -1 ? name.slice(0, lastSlashIndex) : null;
16037
16038      if (type !== 'template' && lastSlashIndex !== -1) {
16039        var parts = name.split('/');
16040        name = parts[parts.length - 1];
16041        var namespaceName = _emberRuntimeSystemString.capitalize(parts.slice(0, -1).join('.'));
16042        root = _emberRuntimeSystemNamespace.default.byName(namespaceName);
16043
16044        _emberMetalDebug.assert('You are looking for a ' + name + ' ' + type + ' in the ' + namespaceName + ' namespace, but the namespace could not be found', root);
16045      }
16046
16047      var resolveMethodName = fullNameWithoutType === 'main' ? 'Main' : _emberRuntimeSystemString.classify(type);
16048
16049      if (!(name && type)) {
16050        throw new TypeError('Invalid fullName: `' + fullName + '`, must be of the form `type:name` ');
16051      }
16052
16053      return {
16054        fullName: fullName,
16055        type: type,
16056        fullNameWithoutType: fullNameWithoutType,
16057        dirname: dirname,
16058        name: name,
16059        root: root,
16060        resolveMethodName: 'resolve' + resolveMethodName
16061      };
16062    },
16063
16064    /**
16065      Returns a human-readable description for a fullName. Used by the
16066      Application namespace in assertions to describe the
16067      precise name of the class that Ember is looking for, rather than
16068      container keys.
16069       @protected
16070      @param {String} fullName the lookup string
16071      @method lookupDescription
16072      @public
16073    */
16074    lookupDescription: function (fullName) {
16075      var parsedName = this.parseName(fullName);
16076      var description;
16077
16078      if (parsedName.type === 'template') {
16079        return 'template at ' + parsedName.fullNameWithoutType.replace(/\./g, '/');
16080      }
16081
16082      description = parsedName.root + '.' + _emberRuntimeSystemString.classify(parsedName.name).replace(/\./g, '');
16083
16084      if (parsedName.type !== 'model') {
16085        description += _emberRuntimeSystemString.classify(parsedName.type);
16086      }
16087
16088      return description;
16089    },
16090
16091    makeToString: function (factory, fullName) {
16092      return factory.toString();
16093    },
16094
16095    /**
16096      Given a parseName object (output from `parseName`), apply
16097      the conventions expected by `Ember.Router`
16098       @protected
16099      @param {Object} parsedName a parseName object with the parsed
16100        fullName lookup string
16101      @method useRouterNaming
16102      @public
16103    */
16104    useRouterNaming: function (parsedName) {
16105      parsedName.name = parsedName.name.replace(/\./g, '_');
16106      if (parsedName.name === 'basic') {
16107        parsedName.name = '';
16108      }
16109    },
16110    /**
16111      Look up the template in Ember.TEMPLATES
16112       @protected
16113      @param {Object} parsedName a parseName object with the parsed
16114        fullName lookup string
16115      @method resolveTemplate
16116      @public
16117    */
16118    resolveTemplate: function (parsedName) {
16119      var templateName = parsedName.fullNameWithoutType.replace(/\./g, '/');
16120
16121      return _emberHtmlbarsTemplate_registry.get(templateName) || _emberHtmlbarsTemplate_registry.get(_emberRuntimeSystemString.decamelize(templateName));
16122    },
16123
16124    /**
16125      Lookup the view using `resolveOther`
16126       @protected
16127      @param {Object} parsedName a parseName object with the parsed
16128        fullName lookup string
16129      @method resolveView
16130      @public
16131    */
16132    resolveView: function (parsedName) {
16133      this.useRouterNaming(parsedName);
16134      return this.resolveOther(parsedName);
16135    },
16136
16137    /**
16138      Lookup the controller using `resolveOther`
16139       @protected
16140      @param {Object} parsedName a parseName object with the parsed
16141        fullName lookup string
16142      @method resolveController
16143      @public
16144    */
16145    resolveController: function (parsedName) {
16146      this.useRouterNaming(parsedName);
16147      return this.resolveOther(parsedName);
16148    },
16149    /**
16150      Lookup the route using `resolveOther`
16151       @protected
16152      @param {Object} parsedName a parseName object with the parsed
16153        fullName lookup string
16154      @method resolveRoute
16155      @public
16156    */
16157    resolveRoute: function (parsedName) {
16158      this.useRouterNaming(parsedName);
16159      return this.resolveOther(parsedName);
16160    },
16161
16162    /**
16163      Lookup the model on the Application namespace
16164       @protected
16165      @param {Object} parsedName a parseName object with the parsed
16166        fullName lookup string
16167      @method resolveModel
16168      @public
16169    */
16170    resolveModel: function (parsedName) {
16171      var className = _emberRuntimeSystemString.classify(parsedName.name);
16172      var factory = _emberMetalProperty_get.get(parsedName.root, className);
16173
16174      if (factory) {
16175        return factory;
16176      }
16177    },
16178    /**
16179      Look up the specified object (from parsedName) on the appropriate
16180      namespace (usually on the Application)
16181       @protected
16182      @param {Object} parsedName a parseName object with the parsed
16183        fullName lookup string
16184      @method resolveHelper
16185      @public
16186    */
16187    resolveHelper: function (parsedName) {
16188      return this.resolveOther(parsedName) || _emberHtmlbarsHelpers.default[parsedName.fullNameWithoutType];
16189    },
16190    /**
16191      Look up the specified object (from parsedName) on the appropriate
16192      namespace (usually on the Application)
16193       @protected
16194      @param {Object} parsedName a parseName object with the parsed
16195        fullName lookup string
16196      @method resolveOther
16197      @public
16198    */
16199    resolveOther: function (parsedName) {
16200      var className = _emberRuntimeSystemString.classify(parsedName.name) + _emberRuntimeSystemString.classify(parsedName.type);
16201      var factory = _emberMetalProperty_get.get(parsedName.root, className);
16202      if (factory) {
16203        return factory;
16204      }
16205    },
16206
16207    resolveMain: function (parsedName) {
16208      var className = _emberRuntimeSystemString.classify(parsedName.type);
16209      return _emberMetalProperty_get.get(parsedName.root, className);
16210    },
16211
16212    /**
16213     @method _logLookup
16214     @param {Boolean} found
16215     @param {Object} parsedName
16216     @private
16217    */
16218    _logLookup: function (found, parsedName) {
16219      var symbol, padding;
16220
16221      if (found) {
16222        symbol = '[✓]';
16223      } else {
16224        symbol = '[ ]';
16225      }
16226
16227      if (parsedName.fullName.length > 60) {
16228        padding = '.';
16229      } else {
16230        padding = new Array(60 - parsedName.fullName.length).join('.');
16231      }
16232
16233      _emberMetalDebug.info(symbol, parsedName.fullName, padding, this.lookupDescription(parsedName.fullName));
16234    },
16235
16236    /**
16237     Used to iterate all items of a given type.
16238      @method knownForType
16239     @param {String} type the type to search for
16240     @private
16241     */
16242    knownForType: function (type) {
16243      var namespace = _emberMetalProperty_get.get(this, 'namespace');
16244      var suffix = _emberRuntimeSystemString.classify(type);
16245      var typeRegexp = new RegExp(suffix + '$');
16246
16247      var known = _emberMetalDictionary.default(null);
16248      var knownKeys = Object.keys(namespace);
16249      for (var index = 0, _length = knownKeys.length; index < _length; index++) {
16250        var _name = knownKeys[index];
16251
16252        if (typeRegexp.test(_name)) {
16253          var containerName = this.translateToContainerFullname(type, _name);
16254
16255          known[containerName] = true;
16256        }
16257      }
16258
16259      return known;
16260    },
16261
16262    /**
16263     Converts provided name from the backing namespace into a container lookup name.
16264      Examples:
16265      App.FooBarHelper -> helper:foo-bar
16266     App.THelper -> helper:t
16267      @method translateToContainerFullname
16268     @param {String} type
16269     @param {String} name
16270     @private
16271     */
16272
16273    translateToContainerFullname: function (type, name) {
16274      var suffix = _emberRuntimeSystemString.classify(type);
16275      var namePrefix = name.slice(0, suffix.length * -1);
16276      var dasherizedName = _emberRuntimeSystemString.dasherize(namePrefix);
16277
16278      return type + ':' + dasherizedName;
16279    }
16280  });
16281});
16282enifed('ember-application/utils/validate-type', ['exports', 'ember-metal/debug'], function (exports, _emberMetalDebug) {
16283  /**
16284  @module ember
16285  @submodule ember-application
16286  */
16287
16288  'use strict';
16289
16290  exports.default = validateType;
16291
16292  var VALIDATED_TYPES = {
16293    route: ['assert', 'isRouteFactory', 'Ember.Route'],
16294    component: ['deprecate', 'isComponentFactory', 'Ember.Component'],
16295    view: ['deprecate', 'isViewFactory', 'Ember.View'],
16296    service: ['deprecate', 'isServiceFactory', 'Ember.Service']
16297  };
16298
16299  function validateType(resolvedType, parsedName) {
16300    var validationAttributes = VALIDATED_TYPES[parsedName.type];
16301
16302    if (!validationAttributes) {
16303      return;
16304    }
16305
16306    var action = validationAttributes[0];
16307    var factoryFlag = validationAttributes[1];
16308    var expectedType = validationAttributes[2];
16309
16310    if (action === 'deprecate') {
16311      _emberMetalDebug.deprecate('In Ember 2.0 ' + parsedName.type + ' factories must have an `' + factoryFlag + '` ' + ('property set to true. You registered ' + resolvedType + ' as a ' + parsedName.type + ' ') + ('factory. Either add the `' + factoryFlag + '` property to this factory or ') + ('extend from ' + expectedType + '.'), !!resolvedType[factoryFlag], { id: 'ember-application.validate-type', until: '3.0.0' });
16312    } else {
16313      _emberMetalDebug.assert('Expected ' + parsedName.fullName + ' to resolve to an ' + expectedType + ' but ' + ('instead it was ' + resolvedType + '.'), !!resolvedType[factoryFlag]);
16314    }
16315  }
16316});
16317enifed('ember-debug/deprecate', ['exports', 'ember-metal/core', 'ember-metal/error', 'ember-metal/logger', 'ember-debug/handlers'], function (exports, _emberMetalCore, _emberMetalError, _emberMetalLogger, _emberDebugHandlers) {
16318  /*global __fail__*/
16319
16320  'use strict';
16321
16322  var _slice = Array.prototype.slice;
16323  exports.registerHandler = registerHandler;
16324  exports.default = deprecate;
16325
16326  function registerHandler(handler) {
16327    _emberDebugHandlers.registerHandler('deprecate', handler);
16328  }
16329
16330  function formatMessage(_message, options) {
16331    var message = _message;
16332
16333    if (options && options.id) {
16334      message = message + (' [deprecation id: ' + options.id + ']');
16335    }
16336
16337    if (options && options.url) {
16338      message += ' See ' + options.url + ' for more details.';
16339    }
16340
16341    return message;
16342  }
16343
16344  registerHandler(function logDeprecationToConsole(message, options) {
16345    var updatedMessage = formatMessage(message, options);
16346
16347    _emberMetalLogger.default.warn('DEPRECATION: ' + updatedMessage);
16348  });
16349
16350  registerHandler(function logDeprecationStackTrace(message, options, next) {
16351    if (_emberMetalCore.default.LOG_STACKTRACE_ON_DEPRECATION) {
16352      var stackStr = '';
16353      var error = undefined,
16354          stack = undefined;
16355
16356      // When using new Error, we can't do the arguments check for Chrome. Alternatives are welcome
16357      try {
16358        __fail__.fail();
16359      } catch (e) {
16360        error = e;
16361      }
16362
16363      if (error.stack) {
16364        if (error['arguments']) {
16365          // Chrome
16366          stack = error.stack.replace(/^\s+at\s+/gm, '').replace(/^([^\(]+?)([\n$])/gm, '{anonymous}($1)$2').replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n');
16367          stack.shift();
16368        } else {
16369          // Firefox
16370          stack = error.stack.replace(/(?:\n@:0)?\s+$/m, '').replace(/^\(/gm, '{anonymous}(').split('\n');
16371        }
16372
16373        stackStr = '\n    ' + stack.slice(2).join('\n    ');
16374      }
16375
16376      var updatedMessage = formatMessage(message, options);
16377
16378      _emberMetalLogger.default.warn('DEPRECATION: ' + updatedMessage + stackStr);
16379    } else {
16380      next.apply(undefined, arguments);
16381    }
16382  });
16383
16384  registerHandler(function raiseOnDeprecation(message, options, next) {
16385    if (_emberMetalCore.default.ENV.RAISE_ON_DEPRECATION) {
16386      var updatedMessage = formatMessage(message);
16387
16388      throw new _emberMetalError.default(updatedMessage);
16389    } else {
16390      next.apply(undefined, arguments);
16391    }
16392  });
16393
16394  var missingOptionsDeprecation = 'When calling `Ember.deprecate` you ' + 'must provide an `options` hash as the third parameter.  ' + '`options` should include `id` and `until` properties.';
16395  exports.missingOptionsDeprecation = missingOptionsDeprecation;
16396  var missingOptionsIdDeprecation = 'When calling `Ember.deprecate` you must provide `id` in options.';
16397  exports.missingOptionsIdDeprecation = missingOptionsIdDeprecation;
16398  var missingOptionsUntilDeprecation = 'When calling `Ember.deprecate` you must provide `until` in options.';
16399
16400  exports.missingOptionsUntilDeprecation = missingOptionsUntilDeprecation;
16401  /**
16402  @module ember
16403  @submodule ember-debug
16404  */
16405
16406  /**
16407    Display a deprecation warning with the provided message and a stack trace
16408    (Chrome and Firefox only).
16409  
16410    * In a production build, this method is defined as an empty function (NOP).
16411    Uses of this method in Ember itself are stripped from the ember.prod.js build.
16412  
16413    @method deprecate
16414    @param {String} message A description of the deprecation.
16415    @param {Boolean} test A boolean. If falsy, the deprecation
16416      will be displayed.
16417    @param {Object} options An object that can be used to pass
16418      in a `url` to the transition guide on the emberjs.com website, and a unique
16419      `id` for this deprecation. The `id` can be used by Ember debugging tools
16420      to change the behavior (raise, log or silence) for that specific deprecation.
16421      The `id` should be namespaced by dots, e.g. "view.helper.select".
16422    @for Ember
16423    @public
16424  */
16425
16426  function deprecate(message, test, options) {
16427    if (!options || !options.id && !options.until) {
16428      deprecate(missingOptionsDeprecation, false, {
16429        id: 'ember-debug.deprecate-options-missing',
16430        until: '3.0.0',
16431        url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options'
16432      });
16433    }
16434
16435    if (options && !options.id) {
16436      deprecate(missingOptionsIdDeprecation, false, {
16437        id: 'ember-debug.deprecate-id-missing',
16438        until: '3.0.0',
16439        url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options'
16440      });
16441    }
16442
16443    if (options && !options.until) {
16444      deprecate(missingOptionsUntilDeprecation, options && options.until, {
16445        id: 'ember-debug.deprecate-until-missing',
16446        until: '3.0.0',
16447        url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options'
16448      });
16449    }
16450
16451    _emberDebugHandlers.invoke.apply(undefined, ['deprecate'].concat(_slice.call(arguments)));
16452  }
16453});
16454enifed('ember-debug/handlers', ['exports', 'ember-debug/is-plain-function', 'ember-debug/deprecate'], function (exports, _emberDebugIsPlainFunction, _emberDebugDeprecate) {
16455  'use strict';
16456
16457  exports.generateTestAsFunctionDeprecation = generateTestAsFunctionDeprecation;
16458  exports.registerHandler = registerHandler;
16459  exports.invoke = invoke;
16460  var HANDLERS = {};
16461
16462  exports.HANDLERS = HANDLERS;
16463
16464  function generateTestAsFunctionDeprecation(source) {
16465    return 'Calling `' + source + '` with a function argument is deprecated. Please ' + 'use `!!Constructor` for constructors, or an `IIFE` to compute the test for deprecation. ' + 'In a future version, functions will be treated as truthy values instead of being executed.';
16466  }
16467
16468  function normalizeTest(test, source) {
16469    if (_emberDebugIsPlainFunction.default(test)) {
16470      _emberDebugDeprecate.default(generateTestAsFunctionDeprecation(source), false, { id: 'ember-debug.deprecate-test-as-function', until: '2.5.0' });
16471
16472      return test();
16473    }
16474
16475    return test;
16476  }
16477
16478  function registerHandler(type, callback) {
16479    var nextHandler = HANDLERS[type] || function () {};
16480
16481    HANDLERS[type] = function (message, options) {
16482      callback(message, options, nextHandler);
16483    };
16484  }
16485
16486  function invoke(type, message, test, options) {
16487    if (normalizeTest(test, 'Ember.' + type)) {
16488      return;
16489    }
16490
16491    var handlerForType = HANDLERS[type];
16492
16493    if (!handlerForType) {
16494      return;
16495    }
16496
16497    if (handlerForType) {
16498      handlerForType(message, options);
16499    }
16500  }
16501});
16502enifed('ember-debug/index', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/error', 'ember-metal/logger', 'ember-metal/environment', 'ember-debug/deprecate', 'ember-debug/warn', 'ember-debug/is-plain-function', 'ember-debug/handlers'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalFeatures, _emberMetalError, _emberMetalLogger, _emberMetalEnvironment, _emberDebugDeprecate, _emberDebugWarn, _emberDebugIsPlainFunction, _emberDebugHandlers) {
16503  'use strict';
16504
16505  exports._warnIfUsingStrippedFeatureFlags = _warnIfUsingStrippedFeatureFlags;
16506
16507  /**
16508  @module ember
16509  @submodule ember-debug
16510  */
16511
16512  /**
16513  @class Ember
16514  @public
16515  */
16516
16517  /**
16518    Define an assertion that will throw an exception if the condition is not met.
16519  
16520    * In a production build, this method is defined as an empty function (NOP).
16521    Uses of this method in Ember itself are stripped from the ember.prod.js build.
16522  
16523    ```javascript
16524    // Test for truthiness
16525    Ember.assert('Must pass a valid object', obj);
16526  
16527    // Fail unconditionally
16528    Ember.assert('This code path should never be run');
16529    ```
16530  
16531    @method assert
16532    @param {String} desc A description of the assertion. This will become
16533      the text of the Error thrown if the assertion fails.
16534    @param {Boolean} test Must be truthy for the assertion to pass. If
16535      falsy, an exception will be thrown.
16536    @public
16537  */
16538  _emberMetalDebug.setDebugFunction('assert', function assert(desc, test) {
16539    var throwAssertion = undefined;
16540
16541    if (_emberDebugIsPlainFunction.default(test)) {
16542      _emberMetalDebug.deprecate(_emberDebugHandlers.generateTestAsFunctionDeprecation('Ember.assert'), false, { id: 'ember-debug.deprecate-test-as-function', until: '2.5.0' });
16543
16544      throwAssertion = !test();
16545    } else {
16546      throwAssertion = !test;
16547    }
16548
16549    if (throwAssertion) {
16550      throw new _emberMetalError.default('Assertion Failed: ' + desc);
16551    }
16552  });
16553
16554  /**
16555    Display a debug notice.
16556  
16557    * In a production build, this method is defined as an empty function (NOP).
16558    Uses of this method in Ember itself are stripped from the ember.prod.js build.
16559  
16560    ```javascript
16561    Ember.debug('I\'m a debug notice!');
16562    ```
16563  
16564    @method debug
16565    @param {String} message A debug message to display.
16566    @public
16567  */
16568  _emberMetalDebug.setDebugFunction('debug', function debug(message) {
16569    _emberMetalLogger.default.debug('DEBUG: ' + message);
16570  });
16571
16572  /**
16573    Display an info notice.
16574  
16575    * In a production build, this method is defined as an empty function (NOP).
16576    Uses of this method in Ember itself are stripped from the ember.prod.js build.
16577  
16578    @method info
16579    @private
16580  */
16581  _emberMetalDebug.setDebugFunction('info', function info() {
16582    _emberMetalLogger.default.info.apply(undefined, arguments);
16583  });
16584
16585  /**
16586    Alias an old, deprecated method with its new counterpart.
16587  
16588    Display a deprecation warning with the provided message and a stack trace
16589    (Chrome and Firefox only) when the assigned method is called.
16590  
16591    * In a production build, this method is defined as an empty function (NOP).
16592  
16593    ```javascript
16594    Ember.oldMethod = Ember.deprecateFunc('Please use the new, updated method', Ember.newMethod);
16595    ```
16596  
16597    @method deprecateFunc
16598    @param {String} message A description of the deprecation.
16599    @param {Object} [options] The options object for Ember.deprecate.
16600    @param {Function} func The new function called to replace its deprecated counterpart.
16601    @return {Function} A new function that wraps the original function with a deprecation warning
16602    @private
16603  */
16604  _emberMetalDebug.setDebugFunction('deprecateFunc', function deprecateFunc() {
16605    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
16606      args[_key] = arguments[_key];
16607    }
16608
16609    if (args.length === 3) {
16610      var _ret = (function () {
16611        var message = args[0];
16612        var options = args[1];
16613        var func = args[2];
16614
16615        return {
16616          v: function () {
16617            _emberMetalDebug.deprecate(message, false, options);
16618            return func.apply(this, arguments);
16619          }
16620        };
16621      })();
16622
16623      if (typeof _ret === 'object') return _ret.v;
16624    } else {
16625      var _ret2 = (function () {
16626        var message = args[0];
16627        var func = args[1];
16628
16629        return {
16630          v: function () {
16631            _emberMetalDebug.deprecate(message);
16632            return func.apply(this, arguments);
16633          }
16634        };
16635      })();
16636
16637      if (typeof _ret2 === 'object') return _ret2.v;
16638    }
16639  });
16640
16641  /**
16642    Run a function meant for debugging.
16643  
16644    * In a production build, this method is defined as an empty function (NOP).
16645    Uses of this method in Ember itself are stripped from the ember.prod.js build.
16646  
16647    ```javascript
16648    Ember.runInDebug(() => {
16649      Ember.Component.reopen({
16650        didInsertElement() {
16651          console.log("I'm happy");
16652        }
16653      });
16654    });
16655    ```
16656  
16657    @method runInDebug
16658    @param {Function} func The function to be executed.
16659    @since 1.5.0
16660    @public
16661  */
16662  _emberMetalDebug.setDebugFunction('runInDebug', function runInDebug(func) {
16663    func();
16664  });
16665
16666  _emberMetalDebug.setDebugFunction('debugSeal', function debugSeal(obj) {
16667    Object.seal(obj);
16668  });
16669
16670  _emberMetalDebug.setDebugFunction('deprecate', _emberDebugDeprecate.default);
16671
16672  _emberMetalDebug.setDebugFunction('warn', _emberDebugWarn.default);
16673
16674  /**
16675    Will call `Ember.warn()` if ENABLE_OPTIONAL_FEATURES or
16676    any specific FEATURES flag is truthy.
16677  
16678    This method is called automatically in debug canary builds.
16679  
16680    @private
16681    @method _warnIfUsingStrippedFeatureFlags
16682    @return {void}
16683  */
16684
16685  function _warnIfUsingStrippedFeatureFlags(FEATURES, knownFeatures, featuresWereStripped) {
16686    if (featuresWereStripped) {
16687      _emberMetalDebug.warn('Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds.', !_emberMetalCore.default.ENV.ENABLE_OPTIONAL_FEATURES, { id: 'ember-debug.feature-flag-with-features-stripped' });
16688
16689      var keys = Object.keys(FEATURES || {});
16690      for (var i = 0; i < keys.length; i++) {
16691        var key = keys[i];
16692        if (key === 'isEnabled' || !(key in knownFeatures)) {
16693          continue;
16694        }
16695
16696        _emberMetalDebug.warn('FEATURE["' + key + '"] is set as enabled, but FEATURE flags are only available in canary builds.', !FEATURES[key], { id: 'ember-debug.feature-flag-with-features-stripped' });
16697      }
16698    }
16699  }
16700
16701  if (!_emberMetalCore.default.testing) {
16702    // Complain if they're using FEATURE flags in builds other than canary
16703    _emberMetalFeatures.FEATURES['features-stripped-test'] = true;
16704    var featuresWereStripped = true;
16705
16706    delete _emberMetalFeatures.FEATURES['features-stripped-test'];
16707    _warnIfUsingStrippedFeatureFlags(_emberMetalCore.default.ENV.FEATURES, _emberMetalFeatures.KNOWN_FEATURES, featuresWereStripped);
16708
16709    // Inform the developer about the Ember Inspector if not installed.
16710    var isFirefox = _emberMetalEnvironment.default.isFirefox;
16711    var isChrome = _emberMetalEnvironment.default.isChrome;
16712
16713    if (typeof window !== 'undefined' && (isFirefox || isChrome) && window.addEventListener) {
16714      window.addEventListener('load', function () {
16715        if (document.documentElement && document.documentElement.dataset && !document.documentElement.dataset.emberExtension) {
16716          var downloadURL;
16717
16718          if (isChrome) {
16719            downloadURL = 'https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi';
16720          } else if (isFirefox) {
16721            downloadURL = 'https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/';
16722          }
16723
16724          _emberMetalDebug.debug('For more advanced debugging, install the Ember Inspector from ' + downloadURL);
16725        }
16726      }, false);
16727    }
16728  }
16729  /**
16730    @public
16731    @class Ember.Debug
16732  */
16733  _emberMetalCore.default.Debug = {};
16734
16735  /**
16736    Allows for runtime registration of handler functions that override the default deprecation behavior.
16737    Deprecations are invoked by calls to [Ember.deprecate](http://emberjs.com/api/classes/Ember.html#method_deprecate).
16738    The following example
16738 demonstrates its usage by registering a handler that throws an error if the
16739    message contains the word "should", otherwise defers to the default handler.
16740     ```javascript
16741    Ember.Debug.registerDeprecationHandler((message, options, next) => {
16742      if (message.indexOf('should') !== -1) {
16743        throw new Error(`Deprecation message with should: ${message}`);
16744      } else {
16745        // defer to whatever handler was registered before this one
16746        next(message, options);
16747      }
16748    }
16749    ```
16750     The handler function takes the following arguments:
16751     <ul>
16752      <li> <code>message</code> - The message received from the deprecation call.</li>
16753      <li> <code>options</code> - An object passed in with the deprecation call containing additional information including:</li>
16754        <ul>
16755          <li> <code>id</code> - An id of the deprecation in the form of <code>package-name.specific-deprecation</code>.</li>
16756          <li> <code>until</code> - The Ember version number the feature and deprecation will be removed in.</li>
16757        </ul>
16758      <li> <code>next</code> - A function that calls into the previously registered handler.</li>
16759    </ul>
16760     @public
16761    @static
16762    @method registerDeprecationHandler
16763    @param handler {Function} A function to handle deprecation calls.
16764    @since 2.1.0
16765  */
16766  _emberMetalCore.default.Debug.registerDeprecationHandler = _emberDebugDeprecate.registerHandler;
16767  /**
16768    Allows for runtime registration of handler functions that override the default warning behavior.
16769    Warnings are invoked by calls made to [Ember.warn](http://emberjs.com/api/classes/Ember.html#method_warn).
16770    The following example demonstrates its usage by registering a handler that does nothing overriding Ember's
16771    default warning behavior.
16772     ```javascript
16773    // next is not called, so no warnings get the default behavior
16774    Ember.Debug.registerWarnHandler(() => {});
16775    ```
16776     The handler function takes the following arguments:
16777     <ul>
16778      <li> <code>message</code> - The message received from the warn call. </li>
16779      <li> <code>options</code> - An object passed in with the warn call containing additional information including:</li>
16780        <ul>
16781          <li> <code>id</code> - An id of the warning in the form of <code>package-name.specific-warning</code>.</li>
16782        </ul>
16783      <li> <code>next</code> - A function that calls into the previously registered handler.</li>
16784    </ul>
16785     @public
16786    @static
16787    @method registerWarnHandler
16788    @param handler {Function} A function to handle warnings.
16789    @since 2.1.0
16790  */
16791  _emberMetalCore.default.Debug.registerWarnHandler = _emberDebugWarn.registerHandler;
16792
16793  /*
16794    We are transitioning away from `ember.js` to `ember.debug.js` to make
16795    it much clearer that it is only for local development purposes.
16796  
16797    This flag value is changed by the tooling (by a simple string replacement)
16798    so that if `ember.js` (which must be output for backwards compat reasons) is
16799    used a nice helpful warning message will be printed out.
16800  */
16801  var runningNonEmberDebugJS = false;
16802  exports.runningNonEmberDebugJS = runningNonEmberDebugJS;
16803  if (runningNonEmberDebugJS) {
16804    _emberMetalDebug.warn('Please use `ember.debug.js` instead of `ember.js` for development and debugging.');
16805  }
16806});
16807enifed('ember-debug/is-plain-function', ['exports'], function (exports) {
16808  'use strict';
16809
16810  exports.default = isPlainFunction;
16811
16812  function isPlainFunction(test) {
16813    return typeof test === 'function' && test.PrototypeMixin === undefined;
16814  }
16815});
16816enifed('ember-debug/warn', ['exports', 'ember-metal/logger', 'ember-metal/debug', 'ember-debug/handlers'], function (exports, _emberMetalLogger, _emberMetalDebug, _emberDebugHandlers) {
16817  'use strict';
16818
16819  var _slice = Array.prototype.slice;
16820  exports.registerHandler = registerHandler;
16821  exports.default = warn;
16822
16823  function registerHandler(handler) {
16824    _emberDebugHandlers.registerHandler('warn', handler);
16825  }
16826
16827  registerHandler(function logWarning(message, options) {
16828    _emberMetalLogger.default.warn('WARNING: ' + message);
16829    if ('trace' in _emberMetalLogger.default) {
16830      _emberMetalLogger.default.trace();
16831    }
16832  });
16833
16834  var missingOptionsDeprecation = 'When calling `Ember.warn` you ' + 'must provide an `options` hash as the third parameter.  ' + '`options` should include an `id` property.';
16835  exports.missingOptionsDeprecation = missingOptionsDeprecation;
16836  var missingOptionsIdDeprecation = 'When calling `Ember.warn` you must provide `id` in options.';
16837
16838  exports.missingOptionsIdDeprecation = missingOptionsIdDeprecation;
16839  /**
16840  @module ember
16841  @submodule ember-debug
16842  */
16843
16844  /**
16845    Display a warning with the provided message.
16846  
16847    * In a production build, this method is defined as an empty function (NOP).
16848    Uses of this method in Ember itself are stripped from the ember.prod.js build.
16849  
16850    @method warn
16851    @param {String} message A warning to display.
16852    @param {Boolean} test An optional boolean. If falsy, the warning
16853      will be displayed.
16854    @param {Object} options An object that can be used to pass a unique
16855      `id` for this warning.  The `id` can be used by Ember debugging tools
16856      to change the behavior (raise, log, or silence) for that specific warning.
16857      The `id` should be namespaced by dots, e.g. "ember-debug.feature-flag-with-features-stripped"
16858    @for Ember
16859    @public
16860  */
16861
16862  function warn(message, test, options) {
16863    if (!options) {
16864      _emberMetalDebug.deprecate(missingOptionsDeprecation, false, {
16865        id: 'ember-debug.warn-options-missing',
16866        until: '3.0.0',
16867        url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options'
16868      });
16869    }
16870
16871    if (options && !options.id) {
16872      _emberMetalDebug.deprecate(missingOptionsIdDeprecation, false, {
16873        id: 'ember-debug.warn-id-missing',
16874        until: '3.0.0',
16875        url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options'
16876      });
16877    }
16878
16879    _emberDebugHandlers.invoke.apply(undefined, ['warn'].concat(_slice.call(arguments)));
16880  }
16881});
16882enifed('ember-extension-support/container_debug_adapter', ['exports', 'ember-metal/core', 'ember-runtime/system/native_array', 'ember-runtime/utils', 'ember-runtime/system/string', 'ember-runtime/system/namespace', 'ember-runtime/system/object'], function (exports, _emberMetalCore, _emberRuntimeSystemNative_array, _emberRuntimeUtils, _emberRuntimeSystemString, _emberRuntimeSystemNamespace, _emberRuntimeSystemObject) {
16883  'use strict';
16884
16885  /**
16886  @module ember
16887  @submodule ember-extension-support
16888  */
16889
16890  /**
16891    The `ContainerDebugAdapter` helps the container and resolver interface
16892    with tools that debug Ember such as the
16893    [Ember Extension](https://github.com/tildeio/ember-extension)
16894    for Chrome and Firefox.
16895  
16896    This class can be extended by a custom resolver implementer
16897    to override some of the methods with library-specific code.
16898  
16899    The methods likely to be overridden are:
16900  
16901    * `canCatalogEntriesByType`
16902    * `catalogEntriesByType`
16903  
16904    The adapter will need to be registered
16905    in the application's container as `container-debug-adapter:main`.
16906  
16907    Example:
16908  
16909    ```javascript
16910    Application.initializer({
16911      name: "containerDebugAdapter",
16912  
16913      initialize: function(application) {
16914        application.register('container-debug-adapter:main', require('app/container-debug-adapter'));
16915      }
16916    });
16917    ```
16918  
16919    @class ContainerDebugAdapter
16920    @namespace Ember
16921    @extends Ember.Object
16922    @since 1.5.0
16923    @public
16924  */
16925  exports.default = _emberRuntimeSystemObject.default.extend({
16926    /**
16927      The resolver instance of the application
16928      being debugged. This property will be injected
16929      on creation.
16930       @property resolver
16931      @default null
16932      @public
16933    */
16934    resolver: null,
16935
16936    /**
16937      Returns true if it is possible to catalog a list of available
16938      classes in the resolver for a given type.
16939       @method canCatalogEntriesByType
16940      @param {String} type The type. e.g. "model", "controller", "route".
16941      @return {boolean} whether a list is available for this type.
16942      @public
16943    */
16944    canCatalogEntriesByType: function (type) {
16945      if (type === 'model' || type === 'template') {
16946        return false;
16947      }
16948
16949      return true;
16950    },
16951
16952    /**
16953      Returns the available classes a given type.
16954       @method catalogEntriesByType
16955      @param {String} type The type. e.g. "model", "controller", "route".
16956      @return {Array} An array of strings.
16957      @public
16958    */
16959    catalogEntriesByType: function (type) {
16960      var namespaces = _emberRuntimeSystemNative_array.A(_emberRuntimeSystemNamespace.default.NAMESPACES);
16961      var types = _emberRuntimeSystemNative_array.A();
16962      var typeSuffixRegex = new RegExp(_emberRuntimeSystemString.classify(type) + '$');
16963
16964      namespaces.forEach(function (namespace) {
16965        if (namespace !== _emberMetalCore.default) {
16966          for (var key in namespace) {
16967            if (!namespace.hasOwnProperty(key)) {
16968              continue;
16969            }
16970            if (typeSuffixRegex.test(key)) {
16971              var klass = namespace[key];
16972              if (_emberRuntimeUtils.typeOf(klass) === 'class') {
16973                types.push(_emberRuntimeSystemString.dasherize(key.replace(typeSuffixRegex, '')));
16974              }
16975            }
16976          }
16977        }
16978      });
16979      return types;
16980    }
16981  });
16982});
16983enifed('ember-extension-support/data_adapter', ['exports', 'ember-metal/property_get', 'ember-metal/run_loop', 'ember-runtime/system/string', 'ember-runtime/system/namespace', 'ember-runtime/system/object', 'ember-runtime/system/native_array', 'ember-application/system/application', 'container/owner', 'ember-runtime/mixins/array'], function (exports, _emberMetalProperty_get, _emberMetalRun_loop, _emberRuntimeSystemString, _emberRuntimeSystemNamespace, _emberRuntimeSystemObject, _emberRuntimeSystemNative_array, _emberApplicationSystemApplication, _containerOwner, _emberRuntimeMixinsArray) {
16984  'use strict';
16985
16986  /**
16987  @module ember
16988  @submodule ember-extension-support
16989  */
16990
16991  /**
16992    The `DataAdapter` helps a data persistence library
16993    interface with tools that debug Ember such
16994    as the [Ember Extension](https://github.com/tildeio/ember-extension)
16995    for Chrome and Firefox.
16996  
16997    This class will be extended by a persistence library
16998    which will override some of the methods with
16999    library-specific code.
17000  
17001    The methods likely to be overridden are:
17002  
17003    * `getFilters`
17004    * `detect`
17005    * `columnsForType`
17006    * `getRecords`
17007    * `getRecordColumnValues`
17008    * `getRecordKeywords`
17009    * `getRecordFilterValues`
17010    * `getRecordColor`
17011    * `observeRecord`
17012  
17013    The adapter will need to be registered
17014    in the application's container as `dataAdapter:main`.
17015  
17016    Example:
17017  
17018    ```javascript
17019    Application.initializer({
17020      name: "data-adapter",
17021  
17022      initialize: function(application) {
17023        application.register('data-adapter:main', DS.DataAdapter);
17024      }
17025    });
17026    ```
17027  
17028    @class DataAdapter
17029    @namespace Ember
17030    @extends EmberObject
17031    @public
17032  */
17033  exports.default = _emberRuntimeSystemObject.default.extend({
17034    init: function () {
17035      this._super.apply(this, arguments);
17036      this.releaseMethods = _emberRuntimeSystemNative_array.A();
17037    },
17038
17039    /**
17040      The container-debug-adapter which is used
17041      to list all models.
17042       @property containerDebugAdapter
17043      @default undefined
17044      @since 1.5.0
17045      @public
17046    **/
17047    containerDebugAdapter: undefined,
17048
17049    /**
17050      The number of attributes to send
17051      as columns. (Enough to make the record
17052      identifiable).
17053       @private
17054      @property attributeLimit
17055      @default 3
17056      @since 1.3.0
17057    */
17058    attributeLimit: 3,
17059
17060    /**
17061       Ember Data >
17061 v1.0.0-beta.18
17062       requires string model names to be passed
17063       around instead of the actual factories.
17064        This is a stamp for the Ember Inspector
17065       to differentiate between the versions
17066       to be able to support older versions too.
17067        @public
17068       @property acceptsModelName
17069     */
17070    acceptsModelName: true,
17071
17072    /**
17073      Stores all methods that clear observers.
17074      These methods will be called on destruction.
17075       @private
17076      @property releaseMethods
17077      @since 1.3.0
17078    */
17079    releaseMethods: _emberRuntimeSystemNative_array.A(),
17080
17081    /**
17082      Specifies how records can be filtered.
17083      Records returned will need to have a `filterValues`
17084      property with a key for every name in the returned array.
17085       @public
17086      @method getFilters
17087      @return {Array} List of objects defining filters.
17088       The object should have a `name` and `desc` property.
17089    */
17090    getFilters: function () {
17091      return _emberRuntimeSystemNative_array.A();
17092    },
17093
17094    /**
17095      Fetch the model types and observe them for changes.
17096       @public
17097      @method watchModelTypes
17098       @param {Function} typesAdded Callback to call to add types.
17099      Takes an array of objects containing wrapped types (returned from `wrapModelType`).
17100       @param {Function} typesUpdated Callback to call when a type has changed.
17101      Takes an array of objects containing wrapped types.
17102       @return {Function} Method to call to remove all observers
17103    */
17104    watchModelTypes: function (typesAdded, typesUpdated) {
17105      var _this = this;
17106
17107      var modelTypes = this.getModelTypes();
17108      var releaseMethods = _emberRuntimeSystemNative_array.A();
17109      var typesToSend;
17110
17111      typesToSend = modelTypes.map(function (type) {
17112        var klass = type.klass;
17113        var wrapped = _this.wrapModelType(klass, type.name);
17114        releaseMethods.push(_this.observeModelType(type.name, typesUpdated));
17115        return wrapped;
17116      });
17117
17118      typesAdded(typesToSend);
17119
17120      var release = function () {
17121        releaseMethods.forEach(function (fn) {
17122          return fn();
17123        });
17124        _this.releaseMethods.removeObject(release);
17125      };
17126      this.releaseMethods.pushObject(release);
17127      return release;
17128    },
17129
17130    _nameToClass: function (type) {
17131      if (typeof type === 'string') {
17132        type = _containerOwner.getOwner(this)._lookupFactory('model:' + type);
17133      }
17134      return type;
17135    },
17136
17137    /**
17138      Fetch the records of a given type and observe them for changes.
17139       @public
17140      @method watchRecords
17141       @param {String} modelName The model name.
17142       @param {Function} recordsAdded Callback to call to add records.
17143      Takes an array of objects containing wrapped records.
17144      The object should have the following properties:
17145        columnValues: {Object} The key and value of a table cell.
17146        object: {Object} The actual record object.
17147       @param {Function} recordsUpdated Callback to call when a record has changed.
17148      Takes an array of objects containing wrapped records.
17149       @param {Function} recordsRemoved Callback to call when a record has removed.
17150      Takes the following parameters:
17151        index: The array index where the records were removed.
17152        count: The number of records removed.
17153       @return {Function} Method to call to remove all observers.
17154    */
17155    watchRecords: function (modelName, recordsAdded, recordsUpdated, recordsRemoved) {
17156      var _this2 = this;
17157
17158      var releaseMethods = _emberRuntimeSystemNative_array.A();
17159      var klass = this._nameToClass(modelName);
17160      var records = this.getRecords(klass, modelName);
17161      var release;
17162
17163      var recordUpdated = function (updatedRecord) {
17164        recordsUpdated([updatedRecord]);
17165      };
17166
17167      var recordsToSend = records.map(function (record) {
17168        releaseMethods.push(_this2.observeRecord(record, recordUpdated));
17169        return _this2.wrapRecord(record);
17170      });
17171
17172      var contentDidChange = function (array, idx, removedCount, addedCount) {
17173        for (var i = idx; i < idx + addedCount; i++) {
17174          var record = _emberRuntimeMixinsArray.objectAt(array, i);
17175          var wrapped = _this2.wrapRecord(record);
17176          releaseMethods.push(_this2.observeRecord(record, recordUpdated));
17177          recordsAdded([wrapped]);
17178        }
17179
17180        if (removedCount) {
17181          recordsRemoved(idx, removedCount);
17182        }
17183      };
17184
17185      var observer = { didChange: contentDidChange, willChange: function () {
17186          return this;
17187        } };
17188      _emberRuntimeMixinsArray.addArrayObserver(records, this, observer);
17189
17190      release = function () {
17191        releaseMethods.forEach(function (fn) {
17192          fn();
17193        });
17194        _emberRuntimeMixinsArray.removeArrayObserver(records, _this2, observer);
17195        _this2.releaseMethods.removeObject(release);
17196      };
17197
17198      recordsAdded(recordsToSend);
17199
17200      this.releaseMethods.pushObject(release);
17201      return release;
17202    },
17203
17204    /**
17205      Clear all observers before destruction
17206      @private
17207      @method willDestroy
17208    */
17209    willDestroy: function () {
17210      this._super.apply(this, arguments);
17211      this.releaseMethods.forEach(function (fn) {
17212        fn();
17213      });
17214    },
17215
17216    /**
17217      Detect whether a class is a model.
17218       Test that against the model class
17219      of your persistence library.
17220       @private
17221      @method detect
17222      @param {Class} klass The class to test.
17223      @return boolean Whether the class is a model class or not.
17224    */
17225    detect: function (klass) {
17226      return false;
17227    },
17228
17229    /**
17230      Get the columns for a given model type.
17231       @private
17232      @method columnsForType
17233      @param {Class} type The model type.
17234      @return {Array} An array of columns of the following format:
17235       name: {String} The name of the column.
17236       desc: {String} Humanized description (what would show in a table column name).
17237    */
17238    columnsForType: function (type) {
17239      return _emberRuntimeSystemNative_array.A();
17240    },
17241
17242    /**
17243      Adds observers to a model type class.
17244       @private
17245      @method observeModelType
17246      @param {String} modelName The model type name.
17247      @param {Function} typesUpdated Called when a type is modified.
17248      @return {Function} The function to call to remove observers.
17249    */
17250
17251    observeModelType: function (modelName, typesUpdated) {
17252      var _this3 = this;
17253
17254      var klass = this._nameToClass(modelName);
17255      var records = this.getRecords(klass, modelName);
17256
17257      var onChange = function () {
17258        typesUpdated([_this3.wrapModelType(klass, modelName)]);
17259      };
17260      var observer = {
17261        didChange: function () {
17262          _emberMetalRun_loop.default.scheduleOnce('actions', this, onChange);
17263        },
17264        willChange: function () {
17265          return this;
17266        }
17267      };
17268
17269      _emberRuntimeMixinsArray.addArrayObserver(records, this, observer);
17270
17271      var release = function () {
17272        _emberRuntimeMixinsArray.removeArrayObserver(records, _this3, observer);
17273      };
17274
17275      return release;
17276    },
17277
17278    /**
17279      Wraps a given model type and observes changes to it.
17280       @private
17281      @method wrapModelType
17282      @param {Class} klass A model class.
17283      @param {String} modelName Name of the class.
17284      @return {Object} Contains the wrapped type and the function to remove observers
17285      Format:
17286        type: {Object} The wrapped type.
17287          The wrapped type has the following format:
17288            name: {String} The name of the type.
17289            count: {Integer} The number of records available.
17290            columns: {Columns} An array of columns to describe the record.
17291            object: {Class} The actual Model type class.
17292        release: {Function} The function to remove observers.
17293    */
17294    wrapModelType: function (klass, name) {
17295      var records = this.getRecords(klass, name);
17296      var typeToSend;
17297
17298      typeToSend = {
17299        name: name,
17300        count: _emberMetalProperty_get.get(records, 'length'),
17301        columns: this.columnsForType(klass),
17302        object: klass
17303      };
17304
17305      return typeToSend;
17306    },
17307
17308    /**
17309      Fetches all models defined in the application.
17310       @private
17311      @method getModelTypes
17312      @return {Array} Array of model types.
17313    */
17314    getModelTypes: function () {
17315      var _this4 = this;
17316
17317      var containerDebugAdapter = this.get('containerDebugAdapter');
17318      var types;
17319
17320      if (containerDebugAdapter.canCatalogEntriesByType('model')) {
17321        types = containerDebugAdapter.catalogEntriesByType('model');
17322      } else {
17323        types = this._getObjectsOnNamespaces();
17324      }
17325
17326      // New adapters return strings instead of classes.
17327      types = _emberRuntimeSystemNative_array.A(types).map(function (name) {
17328        return {
17329          klass: _this4._nameToClass(name),
17330          name: name
17331        };
17332      });
17333      types = _emberRuntimeSystemNative_array.A(types).filter(function (type) {
17334        return _this4.detect(type.klass);
17335      });
17336
17337      return _emberRuntimeSystemNative_array.A(types);
17338    },
17339
17340    /**
17341      Loops over all namespaces and all objects
17342      attached to them.
17343       @private
17344      @method _getObjectsOnNamespaces
17345      @return {Array} Array of model type strings.
17346    */
17347    _getObjectsOnNamespaces: function () {
17348      var _this5 = this;
17349
17350      var namespaces = _emberRuntimeSystemNative_array.A(_emberRuntimeSystemNamespace.default.NAMESPACES);
17351      var types = _emberRuntimeSystemNative_array.A();
17352
17353      namespaces.forEach(function (namespace) {
17354        for (var key in namespace) {
17355          if (!namespace.hasOwnProperty(key)) {
17356            continue;
17357          }
17358          // Even though we will filter again in `getModelTypes`,
17359          // we should not call `lookupFactory` on non-models
17360          // (especially when `Ember.MODEL_FACTORY_INJECTIONS` is `true`)
17361          if (!_this5.detect(namespace[key])) {
17362            continue;
17363          }
17364          var name = _emberRuntimeSystemString.dasherize(key);
17365          if (!(namespace instanceof _emberApplicationSystemApplication.default) && namespace.toString()) {
17366            name = namespace + '/' + name;
17367          }
17368          types.push(name);
17369        }
17370      });
17371      return types;
17372    },
17373
17374    /**
17375      Fetches all loaded records for a given type.
17376       @private
17377      @method getRecords
17378      @return {Array} An array of records.
17379       This array will be observed for changes,
17380       so it should update when new records are added/removed.
17381    */
17382    getRecords: function (type) {
17383      return _emberRuntimeSystemNative_array.A();
17384    },
17385
17386    /**
17387      Wraps a record and observers changes to it.
17388       @private
17389      @method wrapRecord
17390      @param {Object}
17390 record The record instance.
17391      @return {Object} The wrapped record. Format:
17392      columnValues: {Array}
17393      searchKeywords: {Array}
17394    */
17395    wrapRecord: function (record) {
17396      var recordToSend = { object: record };
17397
17398      recordToSend.columnValues = this.getRecordColumnValues(record);
17399      recordToSend.searchKeywords = this.getRecordKeywords(record);
17400      recordToSend.filterValues = this.getRecordFilterValues(record);
17401      recordToSend.color = this.getRecordColor(record);
17402
17403      return recordToSend;
17404    },
17405
17406    /**
17407      Gets the values for each column.
17408       @private
17409      @method getRecordColumnValues
17410      @return {Object} Keys should match column names defined
17411      by the model type.
17412    */
17413    getRecordColumnValues: function (record) {
17414      return {};
17415    },
17416
17417    /**
17418      Returns keywords to match when searching records.
17419       @private
17420      @method getRecordKeywords
17421      @return {Array} Relevant keywords for search.
17422    */
17423    getRecordKeywords: function (record) {
17424      return _emberRuntimeSystemNative_array.A();
17425    },
17426
17427    /**
17428      Returns the values of filters defined by `getFilters`.
17429       @private
17430      @method getRecordFilterValues
17431      @param {Object} record The record instance.
17432      @return {Object} The filter values.
17433    */
17434    getRecordFilterValues: function (record) {
17435      return {};
17436    },
17437
17438    /**
17439      Each record can have a color that represents its state.
17440       @private
17441      @method getRecordColor
17442      @param {Object} record The record instance
17443      @return {String} The records color.
17444        Possible options: black, red, blue, green.
17445    */
17446    getRecordColor: function (record) {
17447      return null;
17448    },
17449
17450    /**
17451      Observes all relevant properties and re-sends the wrapped record
17452      when a change occurs.
17453       @private
17454      @method observerRecord
17455      @param {Object} record The record instance.
17456      @param {Function} recordUpdated The callback to call when a record is updated.
17457      @return {Function} The function to call to remove all observers.
17458    */
17459    observeRecord: function (record, recordUpdated) {
17460      return function () {};
17461    }
17462  });
17463});
17464enifed('ember-extension-support/index', ['exports', 'ember-metal/core', 'ember-extension-support/data_adapter', 'ember-extension-support/container_debug_adapter'], function (exports, _emberMetalCore, _emberExtensionSupportData_adapter, _emberExtensionSupportContainer_debug_adapter) {
17465  /**
17466  @module ember
17467  @submodule ember-extension-support
17468  */
17469
17470  'use strict';
17471
17472  _emberMetalCore.default.DataAdapter = _emberExtensionSupportData_adapter.default;
17473  _emberMetalCore.default.ContainerDebugAdapter = _emberExtensionSupportContainer_debug_adapter.default;
17474});
17475enifed('ember-htmlbars/compat', ['exports', 'ember-metal/core', 'ember-htmlbars/utils/string'], function (exports, _emberMetalCore, _emberHtmlbarsUtilsString) {
17476  'use strict';
17477
17478  var EmberHandlebars = _emberMetalCore.default.Handlebars = _emberMetalCore.default.Handlebars || {};
17479
17480  EmberHandlebars.SafeString = _emberHtmlbarsUtilsString.SafeString;
17481  EmberHandlebars.Utils = {
17482    escapeExpression: _emberHtmlbarsUtilsString.escapeExpression
17483  };
17484
17485  exports.default = EmberHandlebars;
17486});
17487enifed('ember-htmlbars/env', ['exports', 'ember-metal', 'ember-metal/environment', 'htmlbars-runtime', 'ember-metal/assign', 'ember-htmlbars/hooks/subexpr', 'ember-htmlbars/hooks/concat', 'ember-htmlbars/hooks/link-render-node', 'ember-htmlbars/hooks/create-fresh-scope', 'ember-htmlbars/hooks/bind-shadow-scope', 'ember-htmlbars/hooks/bind-self', 'ember-htmlbars/hooks/bind-scope', 'ember-htmlbars/hooks/bind-local', 'ember-htmlbars/hooks/bind-block', 'ember-htmlbars/hooks/update-self', 'ember-htmlbars/hooks/get-root', 'ember-htmlbars/hooks/get-child', 'ember-htmlbars/hooks/get-block', 'ember-htmlbars/hooks/get-value', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-htmlbars/hooks/cleanup-render-node', 'ember-htmlbars/hooks/destroy-render-node', 'ember-htmlbars/hooks/did-render-node', 'ember-htmlbars/hooks/will-cleanup-tree', 'ember-htmlbars/hooks/did-cleanup-tree', 'ember-htmlbars/hooks/classify', 'ember-htmlbars/hooks/component', 'ember-htmlbars/hooks/lookup-helper', 'ember-htmlbars/hooks/has-helper', 'ember-htmlbars/hooks/invoke-helper', 'ember-htmlbars/hooks/element', 'ember-htmlbars/helpers', 'ember-htmlbars/keywords', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/keywords/debugger', 'ember-htmlbars/keywords/with', 'ember-htmlbars/keywords/outlet', 'ember-htmlbars/keywords/unbound', 'ember-htmlbars/keywords/view', 'ember-htmlbars/keywords/component', 'ember-htmlbars/keywords/element-component', 'ember-htmlbars/keywords/partial', 'ember-htmlbars/keywords/input', 'ember-htmlbars/keywords/textarea', 'ember-htmlbars/keywords/collection', 'ember-htmlbars/keywords/yield', 'ember-htmlbars/keywords/legacy-yield', 'ember-htmlbars/keywords/mut', 'ember-htmlbars/keywords/each', 'ember-htmlbars/keywords/readonly', 'ember-htmlbars/keywords/get'], function (exports, _emberMetal, _emberMetalEnvironment, _htmlbarsRuntime, _emberMetalAssign, _emberHtmlbarsHooksSubexpr, _emberHtmlbarsHooksConcat, _emberHtmlbarsHooksLinkRenderNode, _emberHtmlbarsHooksCreateFreshScope, _emberHtmlbarsHooksBindShadowScope, _emberHtmlbarsHooksBindSelf, _emberHtmlbarsHooksBindScope, _emberHtmlbarsHooksBindLocal, _emberHtmlbarsHooksBindBlock, _emberHtmlbarsHooksUpdateSelf, _emberHtmlbarsHooksGetRoot, _emberHtmlbarsHooksGetChild, _emberHtmlbarsHooksGetBlock, _emberHtmlbarsHooksGetValue, _emberHtmlbarsHooksGetCellOrValue, _emberHtmlbarsHooksCleanupRenderNode, _emberHtmlbarsHooksDestroyRenderNode, _emberHtmlbarsHooksDidRenderNode, _emberHtmlbarsHooksWillCleanupTree, _emberHtmlbarsHooksDidCleanupTree, _emberHtmlbarsHooksClassify, _emberHtmlbarsHooksComponent, _emberHtmlbarsHooksLookupHelper, _emberHtmlbarsHooksHasHelper, _emberHtmlbarsHooksInvokeHelper, _emberHtmlbarsHooksElement, _emberHtmlbarsHelpers, _emberHtmlbarsKeywords, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsKeywordsDebugger, _emberHtmlbarsKeywordsWith, _emberHtmlbarsKeywordsOutlet, _emberHtmlbarsKeywordsUnbound, _emberHtmlbarsKeywordsView, _emberHtmlbarsKeywordsComponent, _emberHtmlbarsKeywordsElementComponent, _emberHtmlbarsKeywordsPartial, _emberHtmlbarsKeywordsInput, _emberHtmlbarsKeywordsTextarea, _emberHtmlbarsKeywordsCollection, _emberHtmlbarsKeywordsYield, _emberHtmlbarsKeywordsLegacyYield, _emberHtmlbarsKeywordsMut, _emberHtmlbarsKeywordsEach, _emberHtmlbarsKeywordsReadonly, _emberHtmlbarsKeywordsGet) {
17488  'use strict';
17489
17490  var emberHooks = _emberMetalAssign.default({}, _htmlbarsRuntime.hooks);
17491  emberHooks.keywords = _emberHtmlbarsKeywords.default;
17492
17493  _emberMetalAssign.default(emberHooks, {
17494    linkRenderNode: _emberHtmlbarsHooksLinkRenderNode.default,
17495    createFreshScope: _emberHtmlbarsHooksCreateFreshScope.default,
17496    createChildScope: _emberHtmlbarsHooksCreateFreshScope.createChildScope,
17497    bindShadowScope: _emberHtmlbarsHooksBindShadowScope.default,
17498    bindSelf: _emberHtmlbarsHooksBindSelf.default,
17499    bindScope: _emberHtmlbarsHooksBindScope.default,
17500    bindLocal: _emberHtmlbarsHooksBindLocal.default,
17501    bindBlock: _emberHtmlbarsHooksBindBlock.default,
17502    updateSelf: _emberHtmlbarsHooksUpdateSelf.default,
17503    getBlock: _emberHtmlbarsHooksGetBlock.default,
17504    getRoot: _emberHtmlbarsHooksGetRoot.default,
17505    getChild: _emberHtmlbarsHooksGetChild.default,
17506    getValue: _emberHtmlbarsHooksGetValue.default,
17507    getCellOrValue: _emberHtmlbarsHooksGetCellOrValue.default,
17508    subexpr: _emberHtmlbarsHooksSubexpr.default,
17509    concat: _emberHtmlbarsHooksConcat.default,
17510    cleanupRenderNode: _emberHtmlbarsHooksCleanupRenderNode.default,
17511    destroyRenderNode: _emberHtmlbarsHooksDestroyRenderNode.default,
17512    willCleanupTree: _emberHtmlbarsHooksWillCleanupTree.default,
17513    didCleanupTree: _emberHtmlbarsHooksDidCleanupTree.default,
17514    didRenderNode: _emberHtmlbarsHooksDidRenderNode.default,
17515    classify: _emberHtmlbarsHooksClassify.default,
17516    component: _emberHtmlbarsHooksComponent.default,
17517    lookupHelper: _emberHtmlbarsHooksLookupHelper.default,
17518    hasHelper: _emberHtmlbarsHooksHasHelper.default,
17519    invokeHelper: _emberHtmlbarsHooksInvokeHelper.default,
17520    element: _emberHtmlbarsHooksElement.default
17521  });
17522
17523  _emberHtmlbarsKeywords.registerKeyword('debugger', _emberHtmlbarsKeywordsDebugger.default);
17524  _emberHtmlbarsKeywords.registerKeyword('with', _emberHtmlbarsKeywordsWith.default);
17525  _emberHtmlbarsKeywords.registerKeyword('outlet', _emberHtmlbarsKeywordsOutlet.default);
17526  _emberHtmlbarsKeywords.registerKeyword('unbound', _emberHtmlbarsKeywordsUnbound.default);
17527  _emberHtmlbarsKeywords.registerKeyword('component', _emberHtmlbarsKeywordsComponent.default);
17528  _emberHtmlbarsKeywords.registerKeyword('@element_component', _emberHtmlbarsKeywordsElementComponent.default);
17529  _emberHtmlbarsKeywords.registerKeyword('partial', _emberHtmlbarsKeywordsPartial.default);
17530  _emberHtmlbarsKeywords.registerKeyword('input', _emberHtmlbarsKeywordsInput.default);
17531  _emberHtmlbarsKeywords.registerKeyword('textarea', _emberHtmlbarsKeywordsTextarea.default);
17532  _emberHtmlbarsKeywords.registerKeyword('yield', _emberHtmlbarsKeywordsYield.default);
17533  _emberHtmlbarsKeywords.registerKeyword('legacy-yield', _emberHtmlbarsKeywordsLegacyYield.default);
17534  _emberHtmlbarsKeywords.registerKeyword('mut', _emberHtmlbarsKeywordsMut.default);
17535  _emberHtmlbarsKeywords.registerKeyword('@mut', _emberHtmlbarsKeywordsMut.privateMut);
17536  _emberHtmlbarsKeywords.registerKeyword('each', _emberHtmlbarsKeywordsEach.default);
17537  _emberHtmlbarsKeywords.registerKeyword('readonly', _emberHtmlbarsKeywordsReadonly.default);
17538  _emberHtmlbarsKeywords.registerKeyword('get', _emberHtmlbarsKeywordsGet.default);
17539
17540  if (_emberMetal.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
17541    _emberHtmlbarsKeywords.registerKeyword('collection', _emberHtmlbarsKeywordsCollection.default);
17542    _emberHtmlbarsKeywords.registerKeyword('view', _emberHtmlbarsKeywordsView.default);
17543  }
17544
17545  exports.default = {
17546    hooks: emberHooks,
17547    helpers: _emberHtmlbarsHelpers.default,
17548    useFragmentCache: true
17549  };
17550
17551  var domHelper = _emberMetalEnvironment.default.hasDOM ? new _emberHtmlbarsSystemDomHelper.default() : null;
17552
17553  exports.domHelper = domHelper;
17554});
17555enifed('ember-htmlbars/glimmer-component', ['exports', 'ember-views/views/core_view', 'ember-views/mixins/view_child_views_support', 'ember-views/mixins/view_state_support', 'ember-views/mixins/template_rendering_support', 'ember-views/mixins/class_names_support', 'ember-views/mixins/instrumentation_support', 'ember-views/mixins/aria_role_support', 'ember-views/mixins/view_support', 'ember-views/views/view'], function (exports, _emberViewsViewsCore_view, _emberViewsMixinsView_child_views_support, _emberViewsMixinsView_state_support, _emberViewsMixinsTemplate_rendering_support, _emberViewsMixinsClass_names_support, _emberViewsMixinsInstrumentation_support, _emberViewsMixinsAria_role_support, _emberViewsMixinsView_support, _emberViewsViewsView) {
17556  'use strict';
17557
17558  exports.default = _emberViewsViewsCore_view.default.extend(_emberViewsMixinsView_child_views_support.default, _emberViewsMixinsView_state_support.default, _emberViewsMixinsTemplate_rendering_support.default, _emberViewsMixinsClass_names_support.default, _emberViewsMixinsInstrumentation_support.default, _emberViewsMixinsAria_role_support.default, _emberViewsMixinsView_support.default, {
17559    isComponent: true,
17560    isGlimmerComponent: true,
17561
17562    init: function () {
17563      this._super.apply(this, arguments);
17564      this._viewRegistry = this._viewRegistry || _emberViewsViewsView.default.views;
17565    }
17566  });
17567});
17568enifed('ember-htmlbars/helper', ['exports', 'ember-runtime/system/object'], function (exports, _emberRuntimeSystemObject) {
17569  /**
17570  @module ember
17571  @submodule ember-templates
17572  */
17573
17574  'use strict';
17575
17576  exports.helper = helper;
17577
17578  /**
17579    Ember Helpers are functions that can compute values, and are used in templates.
17580    For example, this code calls a helper named `format-currency`:
17581  
17582    ```handlebars
17583    <div>{{format-currency cents currency="$"}}</div>
17584    ```
17585  
17586    Additionally, a helper can be called as a nested helper (sometimes called a
17587    subexpression). In this example, the computed value of a helper is passed
17588    to a component named `show-money`:
17589  
17590    ```handlebars
17591    {{show-money amount=(format-currency cents currency="$")}}
17592    ```
17593  
17594    Helpers defined using a class must provide a `compute` function. For example:
17595  
17596    ```js
17597    export default Ember.Helper.extend({
17598      compute(params, hash) {
17599        let cents = params[0];
17600        let currency = hash.currency;
17601        return `${currency}${cents * 0.01}`;
17602      }
17603    });
17604    ```
17605  
17606    Each time the input to a helper changes, the `compute` function will be
17607    called again.
17608  
17609    As instances, these helpers also have access to the container and will accept
17610    injected dependencies.
17611  
17612    Additionally, class helpers can call `recompute` to force a new computation.
17613  
17614    @class Ember.Helper
17615    @public
17616    @since 1.13.0
17617  */
17618  var Helper = _emberRuntimeSystemObject.default.extend({
17619    isHelperInstance: true,
17620
17621    /**
17622      On a class-based helper, it may be useful to force a recomputation of that
17623      helpers value. This is akin to `rerender` on a component.
17624       For example, this component will rerender when the `currentUser` on a
17625      session service changes:
17626       ```js
17627      
17627// app/helpers/current-user-email.js
17628      export default Ember.Helper.extend({
17629        session: Ember.inject.service(),
17630        onNewUser: Ember.observer('session.currentUser', function() {
17631          this.recompute();
17632        }),
17633        compute() {
17634          return this.get('session.currentUser.email');
17635        }
17636      });
17637      ```
17638       @method recompute
17639      @public
17640      @since 1.13.0
17641    */
17642    recompute: function () {
17643      this._stream.notify();
17644    }
17645
17646    /**
17647      Override this function when writing a class-based helper.
17648       @method compute
17649      @param {Array} params The positional arguments to the helper
17650      @param {Object} hash The named arguments to the helper
17651      @public
17652      @since 1.13.0
17653    */
17654  });
17655
17656  Helper.reopenClass({
17657    isHelperFactory: true
17658  });
17659
17660  /**
17661    In many cases, the ceremony of a full `Ember.Helper` class is not required.
17662    The `helper` method creates pure-function helpers without instances. For
17663    example:
17664  
17665    ```js
17666    
17666// app/helpers/format-currency.js
17667    export default Ember.Helper.helper(function(params, hash) {
17668      let cents = params[0];
17669      let currency = hash.currency;
17670      return `${currency}${cents * 0.01}`;
17671    });
17672    ```
17673  
17674    @static
17675    @param {Function} helper The helper function
17676    @method helper
17677    @public
17678    @since 1.13.0
17679  */
17680
17681  function helper(helperFn) {
17682    return {
17683      isHelperInstance: true,
17684      compute: helperFn
17685    };
17686  }
17687
17688  exports.default = Helper;
17689});
17690enifed('ember-htmlbars/helpers/-html-safe', ['exports', 'htmlbars-util/safe-string'], function (exports, _htmlbarsUtilSafeString) {
17691  'use strict';
17692
17693  exports.default = htmlSafeHelper;
17694
17695  /**
17696   This private helper is used internally to handle `isVisible: false` for
17697   Ember.View and Ember.Component.
17698  
17699   @private
17700   */
17701
17702  function htmlSafeHelper(_ref) {
17703    var value = _ref[0];
17704
17705    return new _htmlbarsUtilSafeString.default(value);
17706  }
17707});
17708enifed('ember-htmlbars/helpers/-join-classes', ['exports'], function (exports) {
17709  /*
17710    This private helper is used to join and compact a list of class names.
17711  
17712    @private
17713  */
17714
17715  'use strict';
17716
17717  exports.default = joinClasses;
17718
17719  function joinClasses(classNames) {
17720    var result = [];
17721
17722    for (var i = 0, l = classNames.length; i < l; i++) {
17723      var className = classNames[i];
17724
17725      if (className) {
17726        result.push(className);
17727      }
17728    }
17729
17730    return result.join(' ');
17731  }
17732});
17733enifed('ember-htmlbars/helpers/-legacy-each-with-controller', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-htmlbars/utils/normalize-self', 'ember-htmlbars/utils/decode-each-key'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberHtmlbarsUtilsNormalizeSelf, _emberHtmlbarsUtilsDecodeEachKey) {
17734  'use strict';
17735
17736  exports.default = legacyEachWithControllerHelper;
17737
17738  function legacyEachWithControllerHelper(params, hash, blocks) {
17739    var list = params[0];
17740    var keyPath = hash.key;
17741
17742    // TODO: Correct falsy semantics.
17743    if (!list || _emberMetalProperty_get.get(list, 'length') === 0) {
17744      if (blocks.inverse.yield) {
17745        blocks.inverse.yield();
17746      }
17747      return;
17748    }
17749
17750    list.forEach(function (item, i) {
17751      var self;
17752
17753      if (blocks.template.arity === 0) {
17754        _emberMetalDebug.deprecate(deprecation, false, { id: 'ember-htmlbars.each-with-controller-helper', until: '2.4.0' });
17755        self = _emberHtmlbarsUtilsNormalizeSelf.default(item);
17756        self = bindController(self, true);
17757      }
17758
17759      var key = _emberHtmlbarsUtilsDecodeEachKey.default(item, keyPath, i);
17760      blocks.template.yieldItem(key, [item, i], self);
17761    });
17762  }
17763
17764  function bindController(controller, isSelf) {
17765    return {
17766      controller: controller,
17767      hasBoundController: true,
17768      self: controller ? controller : undefined
17769    };
17770  }
17771
17772  var deprecation = 'Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each items as |item|}}`) instead.';
17773  exports.deprecation = deprecation;
17774});
17775enifed('ember-htmlbars/helpers/-legacy-each-with-keyword', ['exports', 'ember-views/streams/should_display', 'ember-htmlbars/utils/decode-each-key'], function (exports, _emberViewsStreamsShould_display, _emberHtmlbarsUtilsDecodeEachKey) {
17776  'use strict';
17777
17778  exports.default = legacyEachWithKeywordHelper;
17779
17780  function legacyEachWithKeywordHelper(params, hash, blocks) {
17781    var list = params[0];
17782    var keyPath = hash.key;
17783    var legacyKeyword = hash['-legacy-keyword'];
17784
17785    if (_emberViewsStreamsShould_display.default(list)) {
17786      list.forEach(function (item, i) {
17787        var self;
17788        if (legacyKeyword) {
17789          self = bindKeyword(self, legacyKeyword, item);
17790        }
17791
17792        var key = _emberHtmlbarsUtilsDecodeEachKey.default(item, keyPath, i);
17793        blocks.template.yieldItem(key, [item, i], self);
17794      });
17795    } else if (blocks.inverse.yield) {
17796      blocks.inverse.yield();
17797    }
17798  }
17799
17800  function bindKeyword(self, keyword, item) {
17801    var _ref;
17802
17803    return _ref = {
17804      self: self
17805    }, _ref[keyword] = item, _ref;
17806  }
17807
17808  var deprecation = 'Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each items as |item|}}`) instead.';
17809  exports.deprecation = deprecation;
17810});
17811enifed('ember-htmlbars/helpers/-normalize-class', ['exports', 'ember-runtime/system/string', 'ember-metal/path_cache'], function (exports, _emberRuntimeSystemString, _emberMetalPath_cache) {
17812  'use strict';
17813
17814  exports.default = normalizeClass;
17815
17816  /*
17817    This private helper is used by ComponentNode to convert the classNameBindings
17818    microsyntax into a class name.
17819  
17820    When a component or view is created, we normalize class name bindings into a
17821    series of attribute nodes that use this helper.
17822  
17823    @private
17824  */
17825
17826  function normalizeClass(params, hash) {
17827    var propName = params[0];
17828    var value = params[1];
17829    var activeClass = hash.activeClass;
17830    var inactiveClass = hash.inactiveClass;
17831
17832    // When using the colon syntax, evaluate the truthiness or falsiness
17833    // of the value to determine which className to return.
17834    if (activeClass || inactiveClass) {
17835      if (!!value) {
17836        return activeClass;
17837      } else {
17838        return inactiveClass;
17839      }
17840
17841      // If value is a Boolean and true, return the dasherized property
17842      // name.
17843    } else if (value === true) {
17844        // Only apply to last segment in the path.
17845        if (propName && _emberMetalPath_cache.isPath(propName)) {
17846          var segments = propName.split('.');
17847          propName = segments[segments.length - 1];
17848        }
17849
17850        return _emberRuntimeSystemString.dasherize(propName);
17851
17852        // If the value is not false, undefined, or null, return the current
17853        // value of the property.
17854      } else if (value !== false && value != null) {
17855          return value;
17856
17857          // Nothing to display. Return null so that the old class is removed
17858          // but no new class is added.
17859        } else {
17860            return null;
17861          }
17862  }
17863});
17864enifed('ember-htmlbars/helpers/concat', ['exports'], function (exports) {
17865  /**
17866  @module ember
17867  @submodule ember-templates
17868  */
17869
17870  /**
17871    Concatenates the given arguments into a string.
17872  
17873    Example:
17874  
17875    ```handlebars
17876    {{some-component name=(concat firstName " " lastName)}}
17877  
17878    {{! would pass name="<first name value> <last name value>" to the component}}
17879    ```
17880  
17881    @public
17882    @method concat
17883    @for Ember.Templates.helpers
17884    @since 1.13.0
17885  */
17886  'use strict';
17887
17888  exports.default = concat;
17889
17890  function concat(args) {
17891    return args.join('');
17892  }
17893});
17894enifed('ember-htmlbars/helpers/each-in', ['exports', 'ember-views/streams/should_display'], function (exports, _emberViewsStreamsShould_display) {
17895  /**
17896  @module ember
17897  @submodule ember-templates
17898  */
17899
17900  'use strict';
17901
17902  /**
17903    The `{{each-in}}` helper loops over properties on an object. It is unbound,
17904    in that new (or removed) properties added to the target object will not be
17905    rendered.
17906  
17907    For example, given a `user` object that looks like:
17908  
17909    ```javascript
17910    {
17911      "name": "Shelly Sails",
17912      "age": 42
17913    }
17914    ```
17915  
17916    This template would display all properties on the `user`
17917    object in a list:
17918  
17919    ```handlebars
17920    <ul>
17921    {{#each-in user as |key value|}}
17922      <li>{{key}}: {{value}}</li>
17923    {{/each-in}}
17924    </ul>
17925    ```
17926  
17927    Outputting their name and age.
17928  
17929    @method each-in
17930    @for Ember.Templates.helpers
17931    @public
17932    @since 2.1.0
17933  */
17934  var eachInHelper = function (_ref, hash, blocks) {
17935    var object = _ref[0];
17936
17937    var objKeys, prop, i;
17938    objKeys = object ? Object.keys(object) : [];
17939    if (_emberViewsStreamsShould_display.default(objKeys)) {
17940      for (i = 0; i < objKeys.length; i++) {
17941        prop = objKeys[i];
17942        blocks.template.yieldItem(prop, [prop, object[prop]]);
17943      }
17944    } else if (blocks.inverse.yield) {
17945      blocks.inverse.yield();
17946    }
17947  };
17948
17949  exports.default = eachInHelper;
17950});
17951enifed('ember-htmlbars/helpers/each', ['exports', 'ember-views/streams/should_display', 'ember-htmlbars/utils/decode-each-key'], function (exports, _emberViewsStream
17951sShould_display, _emberHtmlbarsUtilsDecodeEachKey) {
17952  /**
17953  @module ember
17954  @submodule ember-templates
17955  */
17956
17957  'use strict';
17958
17959  exports.default = eachHelper;
17960
17961  /**
17962    The `{{#each}}` helper loops over elements in a collection. It is an extension
17963    of the base Handlebars `{{#each}}` helper.
17964  
17965    The default behavior of `{{#each}}` is to yield its inner block once for every
17966    item in an array passing the item as the first block parameter.
17967  
17968    ```javascript
17969    var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}];
17970    ```
17971  
17972    ```handlebars
17973    {{#each developers key="name" as |person|}}
17974      {{person.name}}
17975      {{! `this` is whatever it was outside the #each }}
17976    {{/each}}
17977    ```
17978  
17979    The same rules apply to arrays of primitives.
17980  
17981    ```javascript
17982    var developerNames = ['Yehuda', 'Tom', 'Paul']
17983    ```
17984  
17985    ```handlebars
17986    {{#each developerNames key="@index" as |name|}}
17987      {{name}}
17988    {{/each}}
17989    ```
17990  
17991    During iteration, the index of each item in the array is provided as a second block parameter.
17992  
17993    ```handlebars
17994    <ul>
17995      {{#each people as |person index|}}
17996        <li>Hello, {{person.name}}! You're number {{index}} in line</li>
17997      {{/each}}
17998    </ul>
17999    ```
18000  
18001    ### Specifying Keys
18002  
18003    The `key` option is used to tell Ember how to determine if the array being
18004    iterated over with `{{#each}}` has changed between renders. By helping Ember
18005    detect that some elements in the array are the same, DOM elements can be
18006    re-used, significantly improving rendering speed.
18007  
18008    For example, here's the `{{#each}}` helper with its `key` set to `id`:
18009  
18010    ```handlebars
18011    {{#each model key="id" as |item|}}
18012    {{/each}}
18013    ```
18014  
18015    When this `{{#each}}` re-renders, Ember will match up the previously rendered
18016    items (and reorder the generated DOM elements) based on each item's `id`
18017    property.
18018  
18019    By default the item's own reference is used.
18020  
18021    ### {{else}} condition
18022  
18023    `{{#each}}` can have a matching `{{else}}`. The contents of this block will render
18024    if the collection is empty.
18025  
18026    ```handlebars
18027    {{#each developers as |person|}}
18028      {{person.name}}
18029    {{else}}
18030      <p>Sorry, nobody is available for this task.</p>
18031    {{/each}}
18032    ```
18033  
18034    @method each
18035    @for Ember.Templates.helpers
18036    @public
18037  */
18038
18039  function eachHelper(params, hash, blocks) {
18040    var list = params[0];
18041    var keyPath = hash.key;
18042
18043    if (_emberViewsStreamsShould_display.default(list)) {
18044      forEach(list, function (item, i) {
18045        var key = _emberHtmlbarsUtilsDecodeEachKey.default(item, keyPath, i);
18046
18047        blocks.template.yieldItem(key, [item, i]);
18048      });
18049    } else if (blocks.inverse.yield) {
18050      blocks.inverse.yield();
18051    }
18052  }
18053
18054  function forEach(iterable, cb) {
18055    return iterable.forEach ? iterable.forEach(cb) : Array.prototype.forEach.call(iterable, cb);
18056  }
18057});
18058enifed("ember-htmlbars/helpers/hash", ["exports"], function (exports) {
18059   /**
18060   @module ember
18061   @submodule ember-templates
18062   */
18063
18064   /**
18065      Use the `{{hash}}` helper to create a hash to pass as an option to your
18066      components. This is specially useful for contextual components where you can
18067      just yield a hash:
18068   
18069      ```handlebars
18070      {{yield (hash
18071         name='Sarah'
18072         title=office
18073      )}}
18074      ```
18075   
18076      Would result in an object such as:
18077   
18078      ```js
18079      { name: 'Sarah', title: this.get('office') }
18080      ```
18081   
18082      Where the `title` is bound to updates of the `office` property.
18083   
18084      @method hash
18085      @for Ember.Templates.helpers
18086      @param {Object} options
18087      @return {Object} Hash
18088      @public
18089    */
18090
18091   "use strict";
18092
18093   exports.default = hashHelper;
18094
18095   function hashHelper(params, hash, options) {
18096      return hash;
18097   }
18098});
18099enifed('ember-htmlbars/helpers/if_unless', ['exports', 'ember-metal/debug', 'ember-views/streams/should_display'], function (exports, _emberMetalDebug, _emberViewsStreamsShould_display) {
18100  /**
18101  @module ember
18102  @submodule ember-templates
18103  */
18104
18105  'use strict';
18106
18107  /**
18108    Use the `if` block helper to conditionally render a block depending on a
18109    property. If the property is "falsey", for example: `false`, `undefined`,
18110   `null`, `""`, `0`, `NaN` or an empty array, the block will not be rendered.
18111  
18112   ```handlebars
18113    {{! will not render if foo is falsey}}
18114    {{#if foo}}
18115      Welcome to the {{foo.bar}}
18116    {{/if}}
18117    ```
18118  
18119    You can also specify a template to show if the property is falsey by using
18120    the `else` helper.
18121  
18122    ```handlebars
18123    {{! is it raining outside?}}
18124    {{#if isRaining}}
18125      Yes, grab an umbrella!
18126    {{else}}
18127      No, it's lovely outside!
18128    {{/if}}
18129    ```
18130  
18131    You are also able to combine `else` and `if` helpers to create more complex
18132    conditional logic.
18133  
18134    ```handlebars
18135    {{#if isMorning}}
18136      Good morning
18137    {{else if isAfternoon}}
18138      Good afternoon
18139    {{else}}
18140      Good night
18141    {{/if}}
18142    ```
18143  
18144    You can use `if` inline to conditionally render a single property or string.
18145    This helper acts like a ternary operator. If the first property is truthy,
18146    the second argument will be displayed, if not, the third argument will be
18147    displayed
18148  
18149    ```handlebars
18150    {{if useLongGreeting "Hello" "Hi"}} Dave
18151    ```
18152  
18153    Finally, you can use the `if` helper inside another helper as a subexpression.
18154  
18155    ```handlebars
18156    {{some-component height=(if isBig "100" "10")}}
18157    ```
18158  
18159    @method if
18160    @for Ember.Templates.helpers
18161    @public
18162  */
18163  function ifHelper(params, hash, options) {
18164    return ifUnless(params, hash, options, _emberViewsStreamsShould_display.default(params[0]));
18165  }
18166
18167  /**
18168    The `unless` helper is the inverse of the `if` helper. Its block will be
18169    rendered if the expression contains a falsey value.  All forms of the `if`
18170    helper can also be used with `unless`.
18171  
18172    @method unless
18173    @for Ember.Templates.helpers
18174    @public
18175  */
18176  function unlessHelper(params, hash, options) {
18177    return ifUnless(params, hash, options, !_emberViewsStreamsShould_display.default(params[0]));
18178  }
18179
18180  function ifUnless(params, hash, options, truthy) {
18181    _emberMetalDebug.assert('The block form of the `if` and `unless` helpers expect exactly one ' + 'argument, e.g. `{{#if newMessages}} You have new messages. {{/if}}.`', !options.template.yield || params.length === 1);
18182
18183    _emberMetalDebug.assert('The inline form of the `if` and `unless` helpers expect two or ' + 'three arguments, e.g. `{{if trialExpired \'Expired\' expiryDate}}` ' + 'or `{{unless isFirstLogin \'Welcome back!\'}}`.', !!options.template.yield || params.length === 2 || params.length === 3);
18184
18185    if (truthy) {
18186      if (options.template.yield) {
18187        options.template.yield();
18188      } else {
18189        return params[1];
18190      }
18191    } else {
18192      if (options.inverse.yield) {
18193        options.inverse.yield();
18194      } else {
18195        return params[2];
18196      }
18197    }
18198  }
18199
18200  exports.ifHelper = ifHelper;
18201  exports.unlessHelper = unlessHelper;
18202});
18203enifed('ember-htmlbars/helpers/loc', ['exports', 'ember-runtime/system/string'], function (exports, _emberRuntimeSystemString) {
18204  'use strict';
18205
18206  exports.default = locHelper;
18207
18208  /**
18209  @module ember
18210  @submodule ember-templates
18211  */
18212
18213  /**
18214    Calls [Ember.String.loc](/api/classes/Ember.String.html#method_loc) with the
18215    provided string. This is a convenient way to localize text within a template.
18216    For example:
18217  
18218    ```javascript
18219    Ember.STRINGS = {
18220      '_welcome_': 'Bonjour'
18221    };
18222    ```
18223  
18224    ```handlebars
18225    <div class='message'>
18226      {{loc '_welcome_'}}
18227    </div>
18228    ```
18229  
18230    ```html
18231    <div class='message'>
18232      Bonjour
18233    </div>
18234    ```
18235  
18236    See [Ember.String.loc](/api/classes/Ember.String.html#method_loc) for how to
18237    set up localized string references.
18238  
18239    @method loc
18240    @for Ember.Templates.helpers
18241    @param {String} str The string to format.
18242    @see {Ember.String#loc}
18243    @public
18244  */
18245
18246  function locHelper(params) {
18247    return _emberRuntimeSystemString.loc.apply(null, params);
18248  }
18249});
18250enifed('ember-htmlbars/helpers/log', ['exports', 'ember-metal/logger'], function (exports, _emberMetalLogger) {
18251  /**
18252  @module ember
18253  @submodule ember-templates
18254  */
18255
18256  'use strict';
18257
18258  exports.default = logHelper;
18259
18260  /**
18261    `log` allows you to output the value of variables in the current rendering
18262    context. `log` also accepts primitive types such as strings or numbers.
18263  
18264    ```handlebars
18265    {{log "myVariable:" myVariable }}
18266    ```
18267  
18268    @method log
18269    @for Ember.Templates.helpers
18270    @param {*} values
18271    @public
18272  */
18273
18274  function logHelper(values) {
18275    _emberMetalLogger.default.log.apply(null, values);
18276  }
18277});
18278enifed('ember-htmlbars/helpers/with', ['exports', 'ember-views/streams/should_display'], function (exports, _emberViewsStreamsShould_display) {
18279  /**
18280  @module ember
18281  @submodule ember-templates
18282  */
18283
18284  'use strict';
18285
18286  exports.default = withHelper;
18287
18288  /**
18289    Use the `{{with}}` helper when you want to alias a property to a new name. This is helpful
18290    for semantic clarity as it allows you to retain default scope or to reference a property from another
18291    `{{with}}` block.
18292  
18293    If the aliased property is "falsey", for example: `false`, `undefined` `null`, `""`, `0`, NaN or
18294    an empty array, the block will not be rendered.
18295  
18296    ```handlebars
18297    {{! Will only render if user.posts contains items}}
18298    {{#with user.posts as |blogPosts|}}
18299      <div class="notice">
18300        There are {{blogPosts.length}}
18300 blog posts written by {{user.name}}.
18301      </div>
18302      {{#each blogPosts as |post|}}
18303        <li>{{post.title}}</li>
18304      {{/each}}
18305    {{/with}}
18306    ```
18307  
18308    Without the `as` operator, it would be impossible to reference `user.name` in the example above.
18309  
18310    NOTE: The alias should not reuse a name from the bound property path.
18311    For example: `{{#with foo.bar as |foo|}}` is not supported because it attempts to alias using
18312    the first part of the property path, `foo`. Instead, use `{{#with foo.bar as |baz|}}`.
18313  
18314    @method with
18315    @for Ember.Templates.helpers
18316    @param {Object} options
18317    @return {String} HTML string
18318    @public
18319  */
18320
18321  function withHelper(params, hash, options) {
18322    if (_emberViewsStreamsShould_display.default(params[0])) {
18323      options.template.yield([params[0]]);
18324    } else if (options.inverse && options.inverse.yield) {
18325      options.inverse.yield([]);
18326    }
18327  }
18328});
18329enifed('ember-htmlbars/helpers', ['exports', 'ember-metal/empty_object'], function (exports, _emberMetalEmpty_object) {
18330  /**
18331  @module ember
18332  @submodule ember-htmlbars
18333  */
18334
18335  /**
18336   @private
18337   @property helpers
18338  */
18339  'use strict';
18340
18341  exports.registerHelper = registerHelper;
18342
18343  var helpers = new _emberMetalEmpty_object.default();
18344
18345  /**
18346  @module ember
18347  @submodule ember-htmlbars
18348  */
18349
18350  /**
18351    @private
18352    @method _registerHelper
18353    @for Ember.HTMLBars
18354    @param {String} name
18355    @param {Object|Function} helperFunc The helper function to add.
18356  */
18357
18358  function registerHelper(name, helperFunc) {
18359    helpers[name] = helperFunc;
18360  }
18361
18362  exports.default = helpers;
18363});
18364enifed('ember-htmlbars/hooks/bind-block', ['exports'], function (exports) {
18365  'use strict';
18366
18367  exports.default = bindBlock;
18368
18369  function bindBlock(env, scope, block) {
18370    var name = arguments.length <= 3 || arguments[3] === undefined ? 'default' : arguments[3];
18371
18372    scope.bindBlock(name, block);
18373  }
18374});
18375enifed('ember-htmlbars/hooks/bind-local', ['exports', 'ember-metal/streams/stream', 'ember-metal/streams/proxy-stream'], function (exports, _emberMetalStreamsStream, _emberMetalStreamsProxyStream) {
18376  /**
18377  @module ember
18378  @submodule ember-htmlbars
18379  */
18380
18381  'use strict';
18382
18383  exports.default = bindLocal;
18384
18385  function bindLocal(env, scope, key, value) {
18386    // TODO: What is the cause of these cases?
18387    if (scope.hasOwnLocal(key)) {
18388      var existing = scope.getLocal(key);
18389      if (existing !== value) {
18390        existing.setSource(value);
18391      }
18392    } else {
18393      var newValue = _emberMetalStreamsStream.wrap(value, _emberMetalStreamsProxyStream.default, key);
18394      scope.bindLocal(key, newValue);
18395    }
18396  }
18397});
18398enifed("ember-htmlbars/hooks/bind-scope", ["exports"], function (exports) {
18399  "use strict";
18400
18401  exports.default = bindScope;
18402
18403  function bindScope(env, scope) {}
18404});
18405enifed('ember-htmlbars/hooks/bind-self', ['exports', 'ember-metal', 'ember-metal/streams/proxy-stream'], function (exports, _emberMetal, _emberMetalStreamsProxyStream) {
18406  /**
18407  @module ember
18408  @submodule ember-htmlbars
18409  */
18410
18411  'use strict';
18412
18413  exports.default = bindSelf;
18414
18415  function bindSelf(env, scope, _self) {
18416    var self = _self;
18417
18418    if (self && self.hasBoundController) {
18419      var _self2 = self;
18420      var controller = _self2.controller;
18421
18422      self = self.self;
18423
18424      if (!!_emberMetal.default.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT) {
18425        scope.bindLocal('controller', newStream(controller || self));
18426      }
18427    }
18428
18429    if (self && self.isView) {
18430      if (!!_emberMetal.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
18431        scope.bindLocal('view', newStream(self, 'view'));
18432      }
18433
18434      if (!!_emberMetal.default.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT) {
18435        scope.bindLocal('controller', newStream(self, '').getKey('controller'));
18436      }
18437
18438      var _selfStream = newStream(self, '');
18439
18440      if (self.isGlimmerComponent) {
18441        scope.bindSelf(_selfStream);
18442      } else {
18443        scope.bindSelf(newStream(_selfStream.getKey('context'), ''));
18444      }
18445
18446      return;
18447    }
18448
18449    var selfStream = newStream(self, '');
18450    scope.bindSelf(selfStream);
18451
18452    if (!!_emberMetal.default.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT) {
18453      if (!scope.hasLocal('controller')) {
18454        scope.bindLocal('controller', selfStream);
18455      }
18456    }
18457  }
18458
18459  function newStream(newValue, key) {
18460    return new _emberMetalStreamsProxyStream.default(newValue, key);
18461  }
18462});
18463enifed('ember-htmlbars/hooks/bind-shadow-scope', ['exports', 'ember-metal/stream
18463s/proxy-stream'], function (exports, _emberMetalStreamsProxyStream) {
18464  /**
18465  @module ember
18466  @submodule ember-htmlbars
18467  */
18468
18469  'use strict';
18470
18471  exports.default = bindShadowScope;
18472
18473  function bindShadowScope(env, parentScope, shadowScope, options) {
18474    if (!options) {
18475      return;
18476    }
18477
18478    var didOverrideController = false;
18479
18480    if (parentScope && parentScope.overrideController) {
18481      didOverrideController = true;
18482      shadowScope.bindLocal('controller', parentScope.getLocal('controller'));
18483    }
18484
18485    var view = options.view;
18486    if (view && !view.isComponent) {
18487      shadowScope.bindLocal('view', newStream(view, 'view'));
18488
18489      if (!didOverrideController) {
18490        shadowScope.bindLocal('controller', newStream(shadowScope.getLocal('view').getKey('controller')));
18491      }
18492
18493      if (view.isView) {
18494        shadowScope.bindSelf(newStream(shadowScope.getLocal('view').getKey('context'), ''));
18495      }
18496    }
18497
18498    shadowScope.bindView(view);
18499
18500    if (view && options.attrs) {
18501      shadowScope.bindComponent(view);
18502    }
18503
18504    if ('attrs' in options) {
18505      shadowScope.bindAttrs(options.attrs);
18506    }
18507
18508    return shadowScope;
18509  }
18510
18511  function newStream(newValue, key) {
18512    return new _emberMetalStreamsProxyStream.default(newValue, key);
18513  }
18514});
18515enifed('ember-htmlbars/hooks/classify', ['exports', 'ember-htmlbars/utils/is-component'], function (exports, _emberHtmlbarsUtilsIsComponent) {
18516  /**
18517  @module ember
18518  @submodule ember-htmlbars
18519  */
18520
18521  'use strict';
18522
18523  exports.default = classify;
18524
18525  function classify(env, scope, path) {
18526    if (_emberHtmlbarsUtilsIsComponent.default(env, scope, path)) {
18527      return 'component';
18528    }
18529
18530    return null;
18531  }
18532});
18533enifed("ember-htmlbars/hooks/cleanup-render-node", ["exports"], function (exports) {
18534  /**
18535  @module ember
18536  @submodule ember-htmlbars
18537  */
18538
18539  "use strict";
18540
18541  exports.default = cleanupRenderNode;
18542
18543  function cleanupRenderNode(renderNode) {
18544    if (renderNode.cleanup) {
18545      renderNode.cleanup();
18546    }
18547  }
18548});
18549enifed('ember-htmlbars/hooks/component', ['exports', 'ember-metal/features', 'ember-metal/debug', 'ember-htmlbars/node-managers/component-node-manager', 'ember-views/system/build-component-template', 'ember-htmlbars/utils/lookup-component', 'ember-metal/assign', 'ember-metal/empty_object', 'ember-metal/cache', 'ember-htmlbars/system/lookup-helper', 'ember-htmlbars/keywords/closure-component'], function (exports, _emberMetalFeatures, _emberMetalDebug, _emberHtmlbarsNodeManagersComponentNodeManager, _emberViewsSystemBuildComponentTemplate, _emberHtmlbarsUtilsLookupComponent, _emberMetalAssign, _emberMetalEmpty_object, _emberMetalCache, _emberHtmlbarsSystemLookupHelper, _emberHtmlbarsKeywordsClosureComponent) {
18550  'use strict';
18551
18552  exports.default = componentHook;
18553
18554  var IS_ANGLE_CACHE = new _emberMetalCache.default(1000, function (key) {
18555    return key.match(/^(@?)<(.*)>$/);
18556  });
18557
18558  function componentHook(renderNode, env, scope, _tagName, params, attrs, templates, visitor) {
18559    var state = renderNode.getState();
18560
18561    var tagName = _tagName;
18562    if (_emberHtmlbarsSystemLookupHelper.CONTAINS_DOT_CACHE.get(tagName)) {
18563      var stream = env.hooks.get(env, scope, tagName);
18564      var componentCell = stream.value();
18565      if (_emberHtmlbarsKeywordsClosureComponent.isComponentCell(componentCell)) {
18566        tagName = componentCell[_emberHtmlbarsKeywordsClosureComponent.COMPONENT_PATH];
18567
18568        /*
18569         * Processing positional params before merging into a hash must be done
18570         * here to avoid problems with rest positional parameters rendered using
18571         * the dot notation.
18572         *
18573         * Closure components (for the contextual component feature) do not
18574         * actually keep the positional params, but process them at each level.
18575         * Therefore, when rendering a closure component with the component
18576         * helper we process the parameters and attributes and then merge those
18577         * on top of the closure component attributes.
18578         *
18579         */
18580        var newAttrs = _emberMetalAssign.default(new _emberMetalEmpty_object.default(), attrs);
18581        _emberHtmlbarsKeywordsClosureComponent.processPositionalParamsFromCell(componentCell, params, newAttrs);
18582        params = [];
18583        attrs = _emberHtmlbarsKeywordsClosureComponent.mergeInNewHash(componentCell[_emberHtmlbarsKeywordsClosureComponent.COMPONENT_HASH], newAttrs);
18584      }
18585    }
18586
18587    // Determine if this is an initial render or a re-render.
18588    if (state.manager) {
18589      state.manager.rerender(env, attrs, visitor);
18590      return;
18591    }
18592
18593    var isAngleBracket = false;
18594    var isTopLevel = false;
18595    var isDasherized = false;
18596
18597    var angles = IS_ANGLE_CACHE.get(tagName);
18598
18599    if (angles) {
18600      tagName = angles[2];
18601      isAngleBracket = true;
18602      isTopLevel = !!angles[1];
18603    }
18604
18605    if (_emberHtmlbarsSystemLookupHelper.CONTAINS_DASH_CACHE.get(tagName)) {
18606      isDasherized = true;
18607    }
18608
18609    var parentView = env.view;
18610
18611    // | Top-level    | Invocation: <foo-bar>    | Invocation: {{foo-bar}}  |
18612    // ----------------------------------------------------------------------
18613    // | <div>        | <div> is component el    | no special semantics (a) |
18614    // | <foo-bar>    | <foo-bar> is identity el | EWTF                     |
18615    // | <bar-baz>    | recursive invocation     | no special semantics     |
18616    // | {{anything}} | EWTF                     | no special semantics     |
18617    //
18618    // (a) needs to be implemented specially, because the usual semantics of
18619    //     <div> are defined by the compiled template, and we need to emulate
18620    //     those semantics.
18621
18622    var currentComponent = env.view;
18623    var isInvokedWithAngles = currentComponent && currentComponent._isAngleBracket;
18624    var isInvokedWithCurlies = currentComponent && !currentComponent._isAngleBracket;
18625
18626    // <div> at the top level of a <foo-bar> invocation.
18627    var isComponentHTMLElement = isAngleBracket && !isDasherized && isInvokedWithAngles;
18628
18629    // <foo-bar> at the top level of a <foo-bar> invocation.
18630    var isComponentIdentityElement = isAngleBracket && isTopLevel && tagName === env.view.tagName;
18631
18632    // <div> at the top level of a {{foo-bar}} invocation.
18633    var isNormalHTMLElement = isAngleBracket && !isDasherized && isInvokedWithCurlies;
18634
18635    var component = undefined,
18636        layout = undefined;
18637    if (isDasherized || !isAngleBracket) {
18638      var options = {};
18639
18640      var moduleName = env.meta && env.meta.moduleName;
18641
18642      if (moduleName) {
18643        options.source = 'template:' + moduleName;
18644      }
18645
18646      var result = _emberHtmlbarsUtilsLookupComponent.default(env.owner, tagName, options);
18647
18648      component = result.component;
18649      layout = result.layout;
18650
18651      if (isAngleBracket && isDasherized && !component && !layout) {
18652        isComponentHTMLElement = true;
18653      } else {
18654        _emberMetalDebug.assert('HTMLBars error: Could not find component named "' + tagName + '" (no component or template with that name was found)', !!(component || layout));
18655      }
18656    }
18657
18658    if (isComponentIdentityElement || isComponentHTMLElement) {
18659      // Inside the layout for <foo-bar> invoked with angles, this is the top-level element
18660      // for the component. It can either be `<foo-bar>` (the "identity element") or any
18661      // normal HTML element (non-dasherized).
18662      var templateOptions = {
18663        component: currentComponent,
18664        tagName: tagName,
18665        isAngleBracket: true,
18666        isComponentElement: true,
18667        outerAttrs: scope.getAttrs(),
18668        parentScope: scope
18669      };
18670
18671      var contentOptions = { templates: templates, scope: scope };
18672
18673      var _buildComponentTemplate = _emberViewsSystemBuildComponentTemplate.default(templateOptions, attrs, contentOptions);
18674
18675      var block = _buildComponentTemplate.block;
18676
18677      block.invoke(env, [], undefined, renderNode, scope, visitor);
18678    } else if (isNormalHTMLElement) {
18679      var block = _emberViewsSystemBuildComponentTemplate.buildHTMLTemplate(tagName, attrs, { templates: templates, scope: scope });
18680      block.invoke(env, [], undefined, renderNode, scope, visitor);
18681    } else {
18682      // Invoking a component from the outside (either via <foo-bar> angle brackets
18683      // or {{foo-bar}} legacy curlies).
18684
18685      var manager = _emberHtmlbarsNodeManagersComponentNodeManager.default.create(renderNode, env, {
18686        tagName: tagName,
18687        params: params,
18688        attrs: attrs,
18689        parentView: parentView,
18690        templates: templates,
18691        isAngleBracket: isAngleBracket,
18692        isTopLevel: isTopLevel,
18693        component: component,
18694        layout: layout,
18695        parentScope: scope
18696      });
18697
18698      state.manager = manager;
18699      manager.render(env, visitor);
18700    }
18701  }
18702});
18703enifed('ember-htmlbars/hooks/concat', ['exports', 'ember-metal/stream
18703s/utils'], function (exports, _emberMetalStreamsUtils) {
18704  /**
18705  @module ember
18706  @submodule ember-htmlbars
18707  */
18708
18709  'use strict';
18710
18711  exports.default = concat;
18712
18713  function concat(env, parts) {
18714    return _emberMetalStreamsUtils.concat(parts, '');
18715  }
18716});
18717enifed('ember-htmlbars/hooks/create-fresh-scope', ['exports', 'ember-metal/streams/proxy-stream', 'ember-metal/empty_object'], function (exports, _emberMetalStreamsProxyStream, _emberMetalEmpty_object) {
18718  'use strict';
18719
18720  exports.default = createFreshScope;
18721  exports.createChildScope = createChildScope;
18722
18723  /*
18724    Ember's implementation of HTMLBars creates an enriched scope.
18725  
18726    * self: same as HTMLBars, this field represents the dynamic lookup
18727      of root keys that are not special keywords or block arguments.
18728    * blocks: same as HTMLBars, a bundle of named blocks the layout
18729      can yield to.
18730    * component: indicates that the scope is the layout of a component,
18731      which is used to trigger lifecycle hooks for the component when
18732      one of the streams in its layout fires.
18733    * attrs: a map of key-value attributes sent in by the invoker of
18734      a template, and available in the component's layout.
18735    * locals: a map of locals, produced by block params (`as |a b|`)
18736    * localPresent: a map of available locals to avoid expensive
18737      `hasOwnProperty` checks.
18738  
18739    The `self` field has two special meanings:
18740  
18741    * If `self` is a view (`isView`), the actual HTMLBars `self` becomes
18742      the view's `context`. This is legacy semantics; components always
18743      use the component itself as the `this`.
18744    * If `self` is a view, two special locals are created: `view` and
18745      `controller`. These locals are legacy semantics.
18746    * If self has a `hasBoundController` property, it is coming from
18747      a legacy form of #with or #each
18748      (`{{#with something controller=someController}}`). This has
18749      the special effect of giving the child scope the supplied
18750      `controller` keyword, with an unrelated `self`. This is
18751      legacy functionality, as both the `view` and `controller`
18752      keywords have been deprecated.
18753  
18754    **IMPORTANT**: There are two places in Ember where the ambient
18755    controller is looked up. Both of those places use the presence
18756    of `scope.locals.view` to indicate that the controller lookup
18757    should be dynamic off of the ambient view. If `scope.locals.view`
18758    does not exist, the code assumes that it is inside of a top-level
18759    template (without a view) and uses the `self` itself as the
18760    controller. This means that if you remove `scope.locals.view`
18761    (perhaps because we are finally ready to shed the view keyword),
18762    there may be unexpected consequences on controller semantics.
18763    If this happens to you, I hope you find this comment. - YK & TD
18764  
18765    In practice, this means that with the exceptions of top-level
18766    view-less templates and the legacy `controller=foo` semantics,
18767    the controller hierarchy is managed dynamically by looking at
18768    the current view's `controller`.
18769  */
18770
18771  function Scope(parent) {
18772    this._self = undefined;
18773    this._blocks = undefined;
18774    this._component = undefined;
18775    this._view = undefined;
18776    this._attrs = undefined;
18777    this._locals = undefined;
18778    this._localPresent = undefined;
18779    this.overrideController = undefined;
18780    this.parent = parent;
18781  }
18782
18783  var proto = Scope.prototype;
18784
18785  proto.getSelf = function () {
18786    return this._self || this.parent.getSelf();
18787  };
18788
18789  proto.bindSelf = function (self) {
18790    this._self = self;
18791  };
18792
18793  proto.updateSelf = function (self, key) {
18794    var existing = this._self;
18795
18796    if (existing) {
18797      existing.setSource(self);
18798    } else {
18799      this._self = new _emberMetalStreamsProxyStream.default(self, key);
18800    }
18801  };
18802
18803  proto.getBlock = function (name) {
18804    if (!this._blocks) {
18805      return this.parent.getBlock(name);
18806    }
18807    return this._blocks[name] || this.parent.getBlock(name);
18808  };
18809
18810  proto.hasBlock = function (name) {
18811    if (!this._blocks) {
18812      return this.parent.hasBlock(name);
18813    }
18814    return !!(this._blocks[name] || this.parent.hasBlock(name));
18815  };
18816
18817  proto.bindBlock = function (name, block) {
18818    if (!this._blocks) {
18819      this._blocks = new _emberMetalEmpty_object.default();
18820    }
18821    this._blocks[name] = block;
18822  };
18823
18824  proto.getComponent = function () {
18825    return this._component || this.parent.getComponent();
18826  };
18827
18828  proto.bindComponent = function (component) {
18829    this._component = component;
18830  };
18831
18832  proto.getView = function () {
18833    return this._view || this.parent.getView();
18834  };
18835
18836  proto.bindView = function (view) {
18837    this._view = view;
18838  };
18839
18840  proto.getAttrs = function () {
18841    return this._attrs || this.parent.getAttrs();
18842  };
18843
18844  proto.bindAttrs = function (attrs) {
18845    this._attrs = attrs;
18846  };
18847
18848  proto.hasLocal = function (name) {
18849    if (!this._localPresent) {
18850      return this.parent.hasLocal(name);
18851    }
18852    return this._localPresent[name] || this.parent.hasLocal(name);
18853  };
18854
18855  proto.hasOwnLocal = function (name) {
18856    return this._localPresent && this._localPresent[name];
18857  };
18858
18859  proto.getLocal = function (name) {
18860    if (!this._localPresent) {
18861      return this.parent.getLocal(name);
18862    }
18863    return this._localPresent[name] ? this._locals[name] : this.parent.getLocal(name);
18864  };
18865
18866  proto.bindLocal = function (name, value) {
18867    if (!this._localPresent) {
18868      this._localPresent = new _emberMetalEmpty_object.default();
18869      this._locals = new _emberMetalEmpty_object.default();
18870    }
18871
18872    this._localPresent[name] = true;
18873    this._locals[name] = value;
18874  };
18875
18876  var EMPTY = {
18877    _self: undefined,
18878    _blocks: undefined,
18879    _component: undefined,
18880    _view: undefined,
18881    _attrs: undefined,
18882    _locals: undefined,
18883    _localPresent: undefined,
18884    overrideController: undefined,
18885
18886    getSelf: function () {
18887      return null;
18888    },
18889    bindSelf: function (self) {
18890      return null;
18891    },
18892    updateSelf: function (self, key) {
18893      return null;
18894    },
18895    getBlock: function (name) {
18896      return null;
18897    },
18898    bindBlock: function (name, block) {
18899      return null;
18900    },
18901    hasBlock: function (name) {
18902      return false;
18903    },
18904    getComponent: function () {
18905      return null;
18906    },
18907    bindComponent: function () {
18908      return null;
18909    },
18910    getView: function () {
18911      return null;
18912    },
18913    bindView: function (view) {
18914      return null;
18915    },
18916    getAttrs: function () {
18917      return null;
18918    },
18919    bindAttrs: function (attrs) {
18920      return null;
18921    },
18922    hasLocal: function (name) {
18923      return false;
18924    },
18925    hasOwnLocal: function (name) {
18926      return false;
18927    },
18928    getLocal: function (name) {
18929      return null;
18930    },
18931    bindLocal: function (name, value) {
18932      return null;
18933    }
18934  };
18935
18936  function createFreshScope() {
18937    return new Scope(EMPTY);
18938  }
18939
18940  function createChildScope(parent) {
18941    return new Scope(parent);
18942  }
18943});
18944enifed("ember-htmlbars/hooks/destroy-render-node", ["exports"], function (exports) {
18945  /**
18946  @module ember
18947  @submodule ember-htmlbars
18948  */
18949
18950  "use strict";
18951
18952  exports.default = destroyRenderNode;
18953
18954  function destroyRenderNode(renderNode) {
18955    if (renderNode.emberView) {
18956      renderNode.emberView.destroy();
18957    }
18958
18959    var streamUnsubscribers = renderNode.streamUnsubscribers;
18960    if (streamUnsubscribers) {
18961      for (var i = 0, l = streamUnsubscribers.length; i < l; i++) {
18962        streamUnsubscribers[i]();
18963      }
18964    }
18965  }
18966});
18967enifed("ember-htmlbars/hooks/did-cleanup-tree", ["exports"], function (exports) {
18968  "use strict";
18969
18970  exports.default = didCleanupTree;
18971
18972  function didCleanupTree(env) {
18973    // Once we have finsihed cleaning up the render node and sub-nodes, reset
18974    // state tracking which view those render nodes belonged to.
18975    env.view.ownerView._destroyingSubtreeForView = null;
18976  }
18977});
18978enifed("ember-htmlbars/hooks/did-render-node", ["exports"], function (exports) {
18979  "use strict";
18980
18981  exports.default = didRenderNode;
18982
18983  function didRenderNode(morph, env) {
18984    env.renderedNodes.add(morph);
18985  }
18986});
18987enifed('ember-htmlbars/hooks/element', ['exports', 'ember-htmlbars/system/lookup-helper', 'htmlbars-runtime/hooks', 'ember-htmlbars/system/invoke-helper'], function (exports, _emberHtmlbarsSystemLookupHelper, _htmlbarsRuntimeHooks, _emberHtmlbarsSystemInvokeHelper) {
18988  /**
18989  @module ember
18990  @submodule ember-htmlbars
18991  */
18992
18993  'use strict';
18994
18995  exports.default = emberElement;
18996
18997  function emberElement(morph, env, scope, path, params, hash, visitor) {
18998    if (_htmlbarsRuntimeHooks.handleRedirect(morph, env, scope, path, params, hash, null, null, visitor)) {
18999      return;
19000    }
19001
19002    var result;
19003    var helper = _emberHtmlbarsSystemLookupHelper.findHelper(path, scope.getSelf(), env);
19004    if (helper) {
19005      var helperStream = _emberHtmlbarsSystemInvokeHelper.buildHelperStream(helper, params, hash, { element: morph.element }, env, scope, path);
19006      result = helperStream.value();
19007    } else {
19008      result = env.hooks.get(env, scope, path);
19009    }
19010
19011    env.hooks.getValue(result);
19012  }
19013});
19014enifed("ember-htmlbars/hooks/get-block", ["exports"], function (exports) {
19015  "use strict";
19016
19017  exports.default = getBlock;
19018
19019  function getBlock(scope, key) {
19020    return scope.getBlock(key);
19021  }
19022});
19023enifed('ember-htmlbars/hooks/get-cell-or-value', ['exports', 'ember-metal/streams/utils', 'ember-htmlbars/keywords/mut'], function (exports, _emberMetalStreamsUtils, _emberHtmlbarsKeywordsMut) {
19024  'use strict';
19025
19026  exports.default = getCellOrValue;
19027
19028  function getCellOrValue(ref) {
19029    if (ref && ref[_emberHtmlbarsKeywordsMut.MUTABLE_REFERENCE]) {
19030      // Reify the mutable reference into a mutable cell.
19031      return ref.cell();
19032    }
19033
19034    // Get the value out of the reference.
19035    return _emberMetalStreamsUtils.read(ref);
19036  }
19037});
19038enifed('ember-htmlbars/hooks/get-child', ['exports', 'ember-metal/streams/utils'], function (exports, _emberMetalStreamsUtils) {
19039  /**
19040  @module ember
19041  @submodule ember-htmlbars
19042  */
19043
19044  'use strict';
19045
19046  exports.default = getChild;
19047
19048  function getChild(parent, key) {
19049    if (_emberMetalStreamsUtils.isStream(parent)) {
19050      return parent.getKey(key);
19051    }
19052
19053    // This should only happen when we are looking at an `attrs` hash.
19054    // That might change if it is possible to pass object literals
19055    // through the templating system.
19056    return parent[key];
19057  }
19058});
19059enifed('ember-htmlbars/hooks/get-root', ['exports'], function (exports) {
19060  /**
19061  @module ember
19062  @submodule ember-htmlbars
19063  */
19064
19065  'use strict';
19066
19067  exports.default = getRoot;
19068
19069  function getRoot(scope, key) {
19070    if (key === 'this') {
19071      return [scope.getSelf()];
19072    } else if (key === 'hasBlock') {
19073      return [!!scope.hasBlock('default')];
19074    } else if (key === 'hasBlockParams') {
19075      var block = scope.getBlock('default');
19076      return [!!block && block.arity];
19077    } else if (scope.hasLocal(key)) {
19078      return [scope.getLocal(key)];
19079    } else {
19080      return [getKey(scope, key)];
19081    }
19082  }
19083
19084  function getKey(scope, key) {
19085    if (key === 'attrs') {
19086      var _attrs = scope.getAttrs();
19087      if (_attrs) {
19088        return _attrs;
19089      }
19090    }
19091
19092    var self = scope.getSelf() || scope.getLocal('view');
19093
19094    if (self) {
19095      return self.getKey(key);
19096    }
19097
19098    var attrs = scope.getAttrs();
19099    if (attrs && key in attrs) {
19100      // TODO: attrs
19101      // deprecate("You accessed the `" + key + "` attribute directly. Please use `attrs." + key + "` instead.");
19102      return attrs[key];
19103    }
19104  }
19105});
19106enifed('ember-htmlbars/hooks/get-value', ['exports', 'ember-metal/stream
19106s/utils', 'ember-views/compat/attrs-proxy'], function (exports, _emberMetalStreamsUtils, _emberViewsCompatAttrsProxy) {
19107  /**
19108  @module ember
19109  @submodule ember-htmlbars
19110  */
19111
19112  'use strict';
19113
19114  exports.default = getValue;
19115
19116  function getValue(ref) {
19117    var value = _emberMetalStreamsUtils.read(ref);
19118
19119    if (value && value[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) {
19120      return value.value;
19121    }
19122
19123    return value;
19124  }
19125});
19126enifed('ember-htmlbars/hooks/has-helper', ['exports', 'ember-htmlbars/system/lookup-helper'], function (exports, _emberHtmlbarsSystemLookupHelper) {
19127  'use strict';
19128
19129  exports.default = hasHelperHook;
19130
19131  function hasHelperHook(env, scope, helperName) {
19132    if (env.helpers[helperName]) {
19133      return true;
19134    }
19135
19136    var owner = env.owner;
19137    if (_emberHtmlbarsSystemLookupHelper.validateLazyHelperName(helperName, owner, env.hooks.keywords)) {
19138      var registrationName = 'helper:' + helperName;
19139      if (owner.hasRegistration(registrationName)) {
19140        return true;
19141      }
19142
19143      var options = {};
19144      var moduleName = env.meta && env.meta.moduleName;
19145      if (moduleName) {
19146        options.source = 'template:' + moduleName;
19147      }
19148
19149      if (owner.hasRegistration(registrationName, options)) {
19150        return true;
19151      }
19152    }
19153
19154    return false;
19155  }
19156});
19157enifed('ember-htmlbars/hooks/invoke-helper', ['exports', 'ember-htmlbars/system/invoke-helper', 'ember-htmlbars/utils/subscribe'], function (exports, _emberHtmlbarsSystemInvokeHelper, _emberHtmlbarsUtilsSubscribe) {
19158  'use strict';
19159
19160  exports.default = invokeHelper;
19161
19162  function invokeHelper(morph, env, scope, visitor, params, hash, helper, templates, context) {
19163    var helperStream = _emberHtmlbarsSystemInvokeHelper.buildHelperStream(helper, params, hash, templates, env, scope);
19164
19165    // Ember.Helper helpers are pure values, thus linkable.
19166    if (helperStream.linkable) {
19167      if (morph) {
19168        // When processing an inline expression, the params and hash have already
19169        // been linked. Thus, HTMLBars will not link the returned helperStream.
19170        // We subscribe the morph to the helperStream here, and also subscribe
19171        // the helperStream to any params.
19172        var addedDependency = false;
19173        for (var i = 0, l = params.length; i < l; i++) {
19174          addedDependency = true;
19175          helperStream.addDependency(params[i]);
19176        }
19177        for (var key in hash) {
19178          addedDependency = true;
19179          helperStream.addDependency(hash[key]);
19180        }
19181        if (addedDependency) {
19182          _emberHtmlbarsUtilsSubscribe.default(morph, env, scope, helperStream);
19183        }
19184      }
19185
19186      return { link: true, value: helperStream };
19187    }
19188
19189    // Built-in helpers are not linkable. They must run on every rerender.
19190    return { value: helperStream.value() };
19191  }
19192});
19193enifed('ember-htmlbars/hooks/link-render-node', ['exports', 'ember-htmlbars/utils/subscribe', 'ember-runtime/utils', 'ember-metal/streams/utils', 'ember-htmlbars/system/lookup-helper', 'ember-htmlbars/keywords/closure-component'], function (exports, _emberHtmlbarsUtilsSubscribe, _emberRuntimeUtils, _emberMetalStreamsUtils, _emberHtmlbarsSystemLookupHelper, _emberHtmlbarsKeywordsClosureComponent) {
19194  /**
19195  @module ember
19196  @submodule ember-htmlbars
19197  */
19198
19199  'use strict';
19200
19201  exports.default = linkRenderNode;
19202
19203  function linkRenderNode(renderNode, env, scope, path, params, hash) {
19204    if (renderNode.streamUnsubscribers) {
19205      return true;
19206    }
19207
19208    var keyword = env.hooks.keywords[path];
19209    if (keyword && keyword.link) {
19210      keyword.link(renderNode.getState(), params, hash);
19211    } else {
19212      switch (path) {
19213        case 'unbound':
19214          return true;
19215        case 'unless':
19216        case 'if':
19217          params[0] = shouldDisplay(params[0], toBool);break;
19218        case 'each':
19219          params[0] = eachParam(params[0]);break;
19220        case 'with':
19221          params[0] = shouldDisplay(params[0], identity);break;
19222      }
19223    }
19224
19225    // If there is a dot in the path, we need to subscribe to the arguments in the
19226    // closure component as well.
19227
19228    if (_emberHtmlbarsSystemLookupHelper.CONTAINS_DOT_CACHE.get(path)) {
19229      var stream = env.hooks.get(env, scope, path);
19230      var componentCell = stream.value();
19231
19232      if (_emberHtmlbarsKeywordsClosureComponent.isComponentCell(componentCell)) {
19233        var closureAttrs = _emberHtmlbarsKeywordsClosureComponent.mergeInNewHash(componentCell[_emberHtmlbarsKeywordsClosureComponent.COMPONENT_HASH], hash);
19234
19235        for (var key in closureAttrs) {
19236          _emberHtmlbarsUtilsSubscribe.default(renderNode, env, scope, closureAttrs[key]);
19237        }
19238      }
19239    }
19240
19241    if (params && params.length) {
19242      for (var i = 0; i < params.length; i++) {
19243        _emberHtmlbarsUtilsSubscribe.default(renderNode, env, scope, params[i]);
19244      }
19245    }
19246
19247    if (hash) {
19248      for (var key in hash) {
19249        _emberHtmlbarsUtilsSubscribe.default(renderNode, env, scope, hash[key]);
19250      }
19251    }
19252
19253    // The params and hash can be reused. They don't need to be
19254    // recomputed on subsequent re-renders because they are
19255    // streams.
19256    return true;
19257  }
19258
19259  function eachParam(list) {
19260    var listChange = getKey(list, '[]');
19261
19262    var stream = _emberMetalStreamsUtils.chain(list, function () {
19263      _emberMetalStreamsUtils.read(listChange);
19264      return _emberMetalStreamsUtils.read(list);
19265    }, 'each');
19266
19267    stream.addDependency(listChange);
19268    return stream;
19269  }
19270
19271  function shouldDisplay(predicate, coercer) {
19272    var length = getKey(predicate, 'length');
19273    var isTruthy = getKey(predicate, 'isTruthy');
19274
19275    var stream = _emberMetalStreamsUtils.chain(predicate, function () {
19276      var predicateVal = _emberMetalStreamsUtils.read(predicate);
19277      var lengthVal = _emberMetalStreamsUtils.read(length);
19278      var isTruthyVal = _emberMetalStreamsUtils.read(isTruthy);
19279
19280      if (_emberRuntimeUtils.isArray(predicateVal)) {
19281        return lengthVal > 0 ? coercer(predicateVal) : false;
19282      }
19283
19284      if (typeof isTruthyVal === 'boolean') {
19285        return isTruthyVal ? coercer(predicateVal) : false;
19286      }
19287
19288      return coercer(predicateVal);
19289    }, 'ShouldDisplay');
19290
19291    _emberMetalStreamsUtils.addDependency(stream, length);
19292    _emberMetalStreamsUtils.addDependency(stream, isTruthy);
19293
19294    return stream;
19295  }
19296
19297  function toBool(value) {
19298    return !!value;
19299  }
19300
19301  function identity(value) {
19302    return value;
19303  }
19304
19305  function getKey(obj, key) {
19306    if (_emberMetalStreamsUtils.isStream(obj)) {
19307      return obj.getKey(key);
19308    } else {
19309      return obj && obj[key];
19310    }
19311  }
19312});
19313enifed('ember-htmlbars/hooks/lookup-helper', ['exports', 'ember-htmlbars/system/lookup-helper'], function (exports, _emberHtmlbarsSystemLookupHelper) {
19314  'use strict';
19315
19316  exports.default = lookupHelperHook;
19317
19318  function lookupHelperHook(env, scope, helperName) {
19319    return _emberHtmlbarsSystemLookupHelper.default(helperName, scope.getSelf(), env);
19320  }
19321});
19322enifed('ember-htmlbars/hooks/subexpr', ['exports', 'ember-htmlbars/system/lookup-helper', 'ember-htmlbars/system/invoke-helper', 'ember-metal/streams/utils'], function (exports, _emberHtmlbarsSystemLookupHelper, _emberHtmlbarsSystemInvokeHelper, _emberMetalStreamsUtils) {
19323  /**
19324  @module ember
19325  @submodule ember-htmlbars
19326  */
19327
19328  'use strict';
19329
19330  exports.default = subexpr;
19331  exports.labelForSubexpr = labelForSubexpr;
19332
19333  function subexpr(env, scope, helperName, params, hash) {
19334    // TODO: Keywords and helper invocation should be integrated into
19335    // the subexpr hook upstream in HTMLBars.
19336    var keyword = env.hooks.keywords[helperName];
19337    if (keyword) {
19338      return keyword(null, env, scope, params, hash, null, null);
19339    }
19340
19341    var label = labelForSubexpr(params, hash, helperName);
19342    var helper = _emberHtmlbarsSystemLookupHelper.default(helperName, scope.getSelf(), env);
19343
19344    var helperStream = _emberHtmlbarsSystemInvokeHelper.buildHelperStream(helper, params, hash, null, env, scope, label);
19345
19346    for (var i = 0, l = params.length; i < l; i++) {
19347      helperStream.addDependency(params[i]);
19348    }
19349
19350    for (var key in hash) {
19351      helperStream.addDependency(hash[key]);
19352    }
19353
19354    return helperStream;
19355  }
19356
19357  function labelForSubexpr(params, hash, helperName) {
19358    var paramsLabels = labelsForParams(params);
19359    var hashLabels = labelsForHash(hash);
19360    var label = '(' + helperName;
19361
19362    if (paramsLabels) {
19363      label += ' ' + paramsLabels;
19364    }
19365    if (hashLabels) {
19366      label += ' ' + hashLabels;
19367    }
19368
19369    return label + ')';
19370  }
19371
19372  function labelsForParams(params) {
19373    return _emberMetalStreamsUtils.labelsFor(params).join(' ');
19374  }
19375
19376  function labelsForHash(hash) {
19377    var out = [];
19378
19379    for (var prop in hash) {
19380      out.push(prop + '=' + _emberMetalStreamsUtils.labelFor(hash[prop]));
19381    }
19382
19383    return out.join(' ');
19384  }
19385});
19386enifed('ember-htmlbars/hooks/update-self', ['exports', 'ember-metal/debug', 'ember-metal/property_get'], function (exports, _emberMetalDebug, _emberMetalProperty_get) {
19387  /**
19388  @module ember
19389  @submodule ember-htmlbars
19390  */
19391
19392  'use strict';
19393
19394  exports.default = updateSelf;
19395
19396  function updateSelf(env, scope, _self) {
19397    var self = _self;
19398
19399    if (self && self.hasBoundController) {
19400      var _self2 = self;
19401      var controller = _self2.controller;
19402
19403      self = self.self;
19404
19405      scope.updateLocal('controller', controller || self);
19406    }
19407
19408    _emberMetalDebug.assert('BUG: scope.attrs and self.isView should not both be true', !(scope.attrs && self.isView));
19409
19410    if (self && self.isView) {
19411      scope.updateLocal('view', self);
19412      scope.updateSelf(_emberMetalProperty_get.get(self, 'context'), '');
19413      return;
19414    }
19415
19416    scope.updateSelf(self);
19417  }
19418});
19419enifed("ember-htmlbars/hooks/will-cleanup-tree", ["exports"], function (exports) {
19420  "use strict";
19421
19422  exports.default = willCleanupTree;
19423
19424  function willCleanupTree(env) {
19425    var view = env.view;
19426
19427    // When we go to clean up the render node and all of its children, we may
19428    // encounter views/components associated with those nodes along the way. In
19429    // those cases, we need to sever the link between the
19430    // existing view hierarchy and those views.
19431    //
19432    // However, we do *not* need to remove the child views of child views, since
19433    // severing the connection to their parent effectively severs them from the
19434    // view graph.
19435    //
19436    // For example, imagine the following view graph:
19437    //
19438    //    A
19439    //   / \
19440    //  B  C
19441    //    / \
19442    //   D  E
19443    //
19444    // If we are cleaning up the node for view C, we need to remove that view
19445    // from A's child views. However, we do not need to remove D and E from C's
19446    // child views, since removing C transitively removes D and E as well.
19447    //
19448    // To accomplish this, we track the nearest view to this render node on the
19449    // owner view, the root-most view in the graph (A in the example above). If
19450    // we detect a view that is a direct child of that view, we remove it from
19451    // the `childViews` array. Other parent/child view relationships are
19452    // untouched.  This view is then cleared once cleanup is complete in
19453    // `didCleanupTree`.
19454    view.ownerView._destroyingSubtreeForView = view;
19455  }
19456});
19457enifed('ember-htmlbars/index', ['exports', 'ember-metal/core', 'ember-metal/features', 'ember-template-compiler', 'ember-htmlbars/system/make_bound_helper', 'ember-htmlbars/helpers', 'ember-htmlbars/helpers/if_unless', 'ember-htmlbars/helpers/with', 'ember-htmlbars/helpers/loc', 'ember-htmlbars/helpers/log', 'ember-htmlbars/helpers/each', 'ember-htmlbars/helpers/each-in', 'ember-htmlbars/helpers/-normalize-class', 'ember-htmlbars/helpers/concat', 'ember-htmlbars/helpers/-join-classes', 'ember-htmlbars/helpers/-legacy-each-with-controller', 'ember-htmlbars/helpers/-legacy-each-with-keyword', 'ember-htmlbars/helpers/-html-safe', 'ember-htmlbars/helpers/hash', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/helper', 'ember-htmlbars/template_registry', 'ember-htmlbars/system/bootstrap', 'ember-htmlbars/compat'], function (exports, _emberMetalCore, _emberMetalFeatures, _emberTemplateCompiler, _emberHtmlbarsSystemMake_bound_helper, _emberHtmlbarsHelpers, _emberHtmlbarsHelpersIf_unless, _emberHtmlbarsHelpersWith, _emberHtmlbarsHelpersLoc, _emberHtmlbarsHelpersLog, _emberHtmlbarsHelpersEach, _emberHtmlbarsHelpersEachIn, _emberHtmlbarsHelpersNormalizeClass, _emberHtmlbarsHelpersConcat, _emberHtmlbarsHelpersJoinClasses, _emberHtmlbarsHelpersLegacyEachWithController, _emberHtmlbarsHelpersLegacyEachWithKeyword, _emberHtmlbarsHelpersHtmlSafe, _emberHtmlbarsHelpersHash, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsHelper, _emberHtmlbarsTemplate_registry, _emberHtmlbarsSystemBootstrap, _emberHtmlbarsCompat) {
19458  /**
19459    Ember templates are executed by [HTMLBars](https://github.com/tildeio/htmlbars),
19460    an HTML-friendly version of [Handlebars](http://handlebarsjs.com/). Any valid Handlebars syntax is valid in an Ember template.
19461  
19462    ### Showing a property
19463  
19464    Templates manage the flow of an application's UI, and display state (through
19465    the DOM) to a user. For example, given a component with the property "name",
19466    that component's template can use the name in several ways:
19467  
19468    ```javascript
19469    
19469// app/components/person.js
19470    export default Ember.Component.extend({
19471      name: 'Jill'
19472    });
19473    ```
19474  
19475    ```handlebars
19476    {{! app/components/person.hbs }}
19477    {{name}}
19478    <div>{{name}}</div>
19479    <span data-name={{name}}></span>
19480    ```
19481  
19482    Any time the "name" property on the component changes, the DOM will be
19483    updated.
19484  
19485    Properties can be chained as well:
19486  
19487    ```handlebars
19488    {{aUserModel.name}}
19489    <div>{{listOfUsers.firstObject.name}}</div>
19490    ```
19491  
19492    ### Using Ember helpers
19493  
19494    When content is passed in mustaches `{{}}`, Ember will first try to find a helper
19495    or component with that name. For example, the `if` helper:
19496  
19497    ```handlebars
19498    {{if name "I have a name" "I have no name"}}
19499    <span data-has-name={{if name true}}></span>
19500    ```
19501  
19502    The returned value is placed where the `{{}}` is called. The above style is
19503    called "inline". A second style of helper usage is called "block". For example:
19504  
19505    ```handlebars
19506    {{#if name}}
19507      I have a name
19508    {{else}}
19509      I have no name
19510    {{/if}}
19511    ```
19512  
19513    The block form of helpers allows you to control how the UI is created based
19514    on the values of properties.
19515  
19516    A third form of helper is called "nested". For example here the concat
19517    helper will add " Doe" to a displayed name if the person has no last name:
19518  
19519    ```handlebars
19520    <span data-name={{concat firstName (
19521     if lastName (concat " " lastName) "Doe"
19522    )}}></span>
19523    ```
19524  
19525    Ember's built-in helpers are described under the [Ember.Templates.helpers](/api/classes/Ember.Templates.helpers.html)
19526    namespace. Documentation on creating custom helpers can be found under
19527    [Ember.Helper](/api/classes/Ember.Helper.html).
19528  
19529    ### Invoking a Component
19530  
19531    Ember components represent state to the UI of an application. Further
19532    reading on components can be found under [Ember.Component](/api/classes/Ember.Component.html).
19533  
19534    @module ember
19535    @submodule ember-templates
19536    @main ember-templates
19537    @public
19538  */
19539
19540  /**
19541  
19542    [HTMLBars](https://github.com/tildeio/htmlbars) is a [Handlebars](http://handlebarsjs.com/)
19543    compatible templating engine used by Ember.js. The classes and namespaces
19544    covered by this documentation attempt to focus on APIs for interacting
19545    with HTMLBars itself. For more general guidance on Ember.js templates and
19546    helpers, please see the [ember-templates](/api/modules/ember-templates.html)
19547    package.
19548  
19549    @module ember
19550    @submodule ember-htmlbars
19551    @main ember-htmlbars
19552    @public
19553  */
19554  'use strict';
19555
19556  _emberHtmlbarsHelpers.registerHelper('if', _emberHtmlbarsHelpersIf_unless.ifHelper);
19557  _emberHtmlbarsHelpers.registerHelper('unless', _emberHtmlbarsHelpersIf_unless.unlessHelper);
19558  _emberHtmlbarsHelpers.registerHelper('with', _emberHtmlbarsHelpersWith.default);
19559  _emberHtmlbarsHelpers.registerHelper('loc', _emberHtmlbarsHelpersLoc.default);
19560  _emberHtmlbarsHelpers.registerHelper('log', _emberHtmlbarsHelpersLog.default);
19561  _emberHtmlbarsHelpers.registerHelper('each', _emberHtmlbarsHelpersEach.default);
19562  _emberHtmlbarsHelpers.registerHelper('each-in', _emberHtmlbarsHelpersEachIn.default);
19563  _emberHtmlbarsHelpers.registerHelper('-normalize-class', _emberHtmlbarsHelpersNormalizeClass.default);
19564  _emberHtmlbarsHelpers.registerHelper('concat', _emberHtmlbarsHelpersConcat.default);
19565  _emberHtmlbarsHelpers.registerHelper('-join-classes', _emberHtmlbarsHelpersJoinClasses.default);
19566  _emberHtmlbarsHelpers.registerHelper('-html-safe', _emberHtmlbarsHelpersHtmlSafe.default);
19567
19568  _emberHtmlbarsHelpers.registerHelper('hash', _emberHtmlbarsHelpersHash.default);
19569
19570  if (_emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
19571    _emberHtmlbarsHelpers.registerHelper('-legacy-each-with-controller', _emberHtmlbarsHelpersLegacyEachWithController.default);
19572    _emberHtmlbarsHelpers.registerHelper('-legacy-each-with-keyword', _emberHtmlbarsHelpersLegacyEachWithKeyword.default);
19573  }
19574
19575  _emberMetalCore.default.HTMLBars = {
19576    template: _emberTemplateCompiler.template,
19577    compile: _emberTemplateCompiler.compile,
19578    precompile: _emberTemplateCompiler.precompile,
19579    makeBoundHelper: _emberHtmlbarsSystemMake_bound_helper.default,
19580    registerPlugin: _emberTemplateCompiler.registerPlugin,
19581    DOMHelper: _emberHtmlbarsSystemDomHelper.default
19582  };
19583
19584  _emberHtmlbarsHelper.default.helper = _emberHtmlbarsHelper.helper;
19585  _emberMetalCore.default.Helper = _emberHtmlbarsHelper.default;
19586
19587  /**
19588    Global hash of shared templates. This will automatically be populated
19589    by the build tools so that you can store your Handlebars templates in
19590    separate files that get loaded into JavaScript at buildtime.
19591  
19592    @property TEMPLATES
19593    @for Ember
19594    @type Object
19595    @private
19596  */
19597  Object.defineProperty(_emberMetalCore.default, 'TEMPLATES', {
19598    configurable: false,
19599    get: _emberHtmlbarsTemplate_registry.getTemplates,
19600    set: _emberHtmlbarsTemplate_registry.setTemplates
19601  });
19602});
19603
19604// Importing adds template bootstrapping
19605// initializer to enable embedded templates.
19606
19607// Importing ember-htmlbars/compat updates the
19608// Ember.Handlebars global if htmlbars is enabled.
19609enifed('ember-htmlbars/keywords/closure-component', ['exports', 'ember-metal/debug', 'ember-metal/is_none', 'ember-metal/symbol', 'ember-metal/stream
19609s/stream', 'ember-metal/empty_object', 'ember-metal/streams/utils', 'ember-htmlbars/hooks/subexpr', 'ember-metal/assign', 'ember-htmlbars/utils/extract-positional-params', 'ember-htmlbars/utils/lookup-component'], function (exports, _emberMetalDebug, _emberMetalIs_none, _emberMetalSymbol, _emberMetalStreamsStream, _emberMetalEmpty_object, _emberMetalStreamsUtils, _emberHtmlbarsHooksSubexpr, _emberMetalAssign, _emberHtmlbarsUtilsExtractPositionalParams, _emberHtmlbarsUtilsLookupComponent) {
19610  /**
19611  @module ember
19612  @submodule ember-templates
19613  */
19614
19615  'use strict';
19616
19617  exports.default = closureComponent;
19618  exports.isComponentCell = isComponentCell;
19619  exports.processPositionalParamsFromCell = processPositionalParamsFromCell;
19620  exports.mergeInNewHash = mergeInNewHash;
19621  var COMPONENT_REFERENCE = _emberMetalSymbol.default('COMPONENT_REFERENCE');
19622  exports.COMPONENT_REFERENCE = COMPONENT_REFERENCE;
19623  var COMPONENT_CELL = _emberMetalSymbol.default('COMPONENT_CELL');
19624  exports.COMPONENT_CELL = COMPONENT_CELL;
19625  var COMPONENT_PATH = _emberMetalSymbol.default('COMPONENT_PATH');
19626  exports.COMPONENT_PATH = COMPONENT_PATH;
19627  var COMPONENT_POSITIONAL_PARAMS = _emberMetalSymbol.default('COMPONENT_POSITIONAL_PARAMS');
19628  exports.COMPONENT_POSITIONAL_PARAMS = COMPONENT_POSITIONAL_PARAMS;
19629  var COMPONENT_HASH = _emberMetalSymbol.default('COMPONENT_HASH');
19630
19631  exports.COMPONENT_HASH = COMPONENT_HASH;
19632  var ClosureComponentStream = _emberMetalStreamsStream.default.extend({
19633    init: function (env, path, params, hash) {
19634      this._env = env;
19635      this._path = path;
19636      this._params = params;
19637      this._hash = hash;
19638      this.label = _emberHtmlbarsHooksSubexpr.labelForSubexpr([path].concat(params), hash, 'component');
19639      this[COMPONENT_REFERENCE] = true;
19640    },
19641    compute: function () {
19642      return createClosureComponentCell(this._env, this._path, this._params, this._hash, this.label);
19643    }
19644  });
19645
19646  function closureComponent(env, _ref3, hash) {
19647    var path = _ref3[0];
19648
19649    var params = _ref3.slice(1);
19650
19651    var s = new ClosureComponentStream(env, path, params, hash);
19652
19653    s.addDependency(path);
19654
19655    // FIXME: If the stream invalidates on every params or hash change, then
19656    // the {{component helper will be forced to re-render the whole component
19657    // each time. Instead, these dependencies should not be required and the
19658    // element component keyword should add the params and hash as dependencies.
19659    params.forEach(function (item) {
19660      return s.addDependency(item);
19661    });
19662    Object.keys(hash).forEach(function (key) {
19663      return s.addDependency(hash[key]);
19664    });
19665
19666    return s;
19667  }
19668
19669  function createClosureComponentCell(env, originalComponentPath, params, hash, label) {
19670    var componentPath = _emberMetalStreamsUtils.read(originalComponentPath);
19671
19672    _emberMetalDebug.assert('Component path cannot be null in ' + label, !_emberMetalIs_none.default(componentPath));
19673
19674    var newHash = _emberMetalAssign.default(new _emberMetalEmpty_object.default(), hash);
19675
19676    if (isComponentCell(componentPath)) {
19677      return createNestedClosureComponentCell(componentPath, params, newHash);
19678    } else {
19679      _emberMetalDebug.assert('The component helper cannot be used without a valid component name. You used "' + componentPath + '" via ' + label, isValidComponentPath(env, componentPath));
19680      return createNewClosureComponentCell(env, componentPath, params, newHash);
19681    }
19682  }
19683
19684  function isValidComponentPath(env, path) {
19685    var result = _emberHtmlbarsUtilsLookupComponent.default(env.owner, path);
19686
19687    return !!(result.component || result.layout);
19688  }
19689
19690  function isComponentCell(component) {
19691    return component && component[COMPONENT_CELL];
19692  }
19693
19694  function createNestedClosureComponentCell(componentCell, params, hash) {
19695    var _ref;
19696
19697    // This needs to be done in each nesting level to avoid raising assertions.
19698    processPositionalParamsFromCell(componentCell, params, hash);
19699
19700    return _ref = {}, _ref[COMPONENT_PATH] = componentCell[COMPONENT_PATH], _ref[COMPONENT_HASH] = mergeInNewHash(componentCell[COMPONENT_HASH], hash), _ref[COMPONENT_POSITIONAL_PARAMS] = componentCell[COMPONENT_POSITIONAL_PARAMS], _ref[COMPONENT_CELL] = true, _ref;
19701  }
19702
19703  function processPositionalParamsFromCell(componentCell, params, hash) {
19704    var positionalParams = componentCell[COMPONENT_POSITIONAL_PARAMS];
19705
19706    _emberHtmlbarsUtilsExtractPositionalParams.processPositionalParams(null, positionalParams, params, hash);
19707  }
19708
19709  function createNewClosureComponentCell(env, componentPath, params, hash) {
19710    var _ref2;
19711
19712    var positionalParams = getPositionalParams(env.owner, componentPath);
19713
19714    // This needs to be done in each nesting level to avoid raising assertions.
19715    _emberHtmlbarsUtilsExtractPositionalParams.processPositionalParams(null, positionalParams, params, hash);
19716
19717    return _ref2 = {}, _ref2[COMPONENT_PATH] = componentPath, _ref2[COMPONENT_HASH] = hash, _ref2[COMPONENT_POSITIONAL_PARAMS] = positionalParams, _ref2[COMPONENT_CELL] = true, _ref2;
19718  }
19719
19720  /*
19721   Returns the positional parameters for component `componentPath`.
19722   If it has no positional parameters, it returns the empty array.
19723   */
19724  function getPositionalParams(container, componentPath) {
19725    if (!componentPath) {
19726      return [];
19727    }
19728    var result = _emberHtmlbarsUtilsLookupComponent.default(container, componentPath);
19729    var component = result.component;
19730
19731    if (component && component.positionalParams) {
19732      return component.positionalParams;
19733    } else {
19734      return [];
19735    }
19736  }
19737
19738  function mergeInNewHash(original, updates) {
19739    return _emberMetalAssign.default({}, original, updates);
19740  }
19741});
19742enifed('ember-htmlbars/keywords/collection', ['exports', 'ember-views/streams/utils', 'ember-views/views/collection_view', 'ember-htmlbars/node-managers/view-node-manager', 'ember-metal/assign'], function (exports, _emberViewsStreamsUtils, _emberViewsViewsCollection_view, _emberHtmlbarsNodeManagersViewNodeManager, _emberMetalAssign) {
19743  /**
19744  @module ember
19745  @submodule ember-templates
19746  */
19747
19748  'use strict';
19749
19750  /**
19751    `{{collection}}` is a template helper for adding instances of
19752    `Ember.CollectionView` to a template. See [Ember.CollectionView](/api/classes/Ember.CollectionView.html)
19753     for additional information on how a `CollectionView` functions.
19754  
19755    `{{collection}}`'s primary use is as a block helper with a `contentBinding`
19756    option pointing towards an `Ember.Array`-compatible object. An `Ember.View`
19757    instance will be created for each item in its `content` property. Each view
19758    will have its own `content` property set to the appropriate item in the
19759    collection.
19760  
19761    The provided block will be applied as the template for each item's view.
19762  
19763    Given an empty `<body>` the following template:
19764  
19765    ```handlebars
19766    {{! application.hbs }}
19767    {{#collection content=model}}
19768      Hi {{view.content.name}}
19769    {{/collection}}
19770    ```
19771  
19772    And the following application code
19773  
19774    ```javascript
19775    App = Ember.Application.create();
19776    App.ApplicationRoute = Ember.Route.extend({
19777      model() {
19778        return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}];
19779      }
19780    });
19781    ```
19782  
19783    The following HTML will result:
19784  
19785    ```html
19786    <div class="ember-view">
19787      <div class="ember-view">Hi Yehuda</div>
19788      <div class="ember-view">Hi Tom</div>
19789      <div class="ember-view">Hi Peter</div>
19790    </div>
19791    ```
19792  
19793    ### Non-block version of collection
19794  
19795    If you provide an `itemViewClass` option that has its own `template`,
19796    then you may omit the block.
19797  
19798    The following template:
19799  
19800    ```handlebars
19801    {{! application.hbs }}
19802    {{collection content=model itemViewClass="an-item"}}
19803    ```
19804  
19805    And application code
19806  
19807    ```javascript
19808    App = Ember.Application.create();
19809    App.ApplicationRoute = Ember.Route.extend({
19810      model() {
19811        return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}];
19812      }
19813    });
19814  
19815    App.AnItemView = Ember.View.extend({
19816      template: Ember.Handlebars.compile("Greetings {{view.content.name}}")
19817    });
19818    ```
19819  
19820    Will result in the HTML structure below
19821  
19822    ```html
19823    <div class="ember-view">
19824      <div class="ember-view">Greetings Yehuda</div>
19825      <div class="ember-view">Greetings Tom</div>
19826      <div class="ember-view">Greetings Peter</div>
19827    </div>
19828    ```
19829  
19830    ### Specifying a CollectionView subclass
19831  
19832    By default the `{{collection}}` helper will create an instance of
19833    `Ember.CollectionView`. You can supply a `Ember.CollectionView` subclass to
19834    the helper by passing it as the first argument:
19835  
19836    ```handlebars
19837    {{#collection "my-custom-collection" content=model}}
19838      Hi {{view.content.name}}
19839    {{/collection}}
19840    ```
19841  
19842    This example would look for the class `App.MyCustomCollection`.
19843  
19844    ### Forwarded `item.*`-named Options
19845  
19846    As with the `{{view}}`, helper options passed to the `{{collection}}` will be
19847    set on the resulting `Ember.CollectionView` as properties. Additionally,
19848    options prefixed with `item` will be applied to the views rendered for each
19849    item (note the camelcasing):
19850  
19851    ```handlebars
19852    {{#collection content=model
19853                  itemTagName="p"
19854                  itemClassNames="greeting"}}
19855      Howdy {{view.content.name}}
19856    {{/collection}}
19857    ```
19858  
19859    Will result in the following HTML structure:
19860  
19861    ```html
19862    <div class="ember-view">
19863      <p class="ember-view greeting">Howdy Yehuda</p>
19864      <p class="ember-view greeting">Howdy Tom</p>
19865      <p class="ember-view greeting">Howdy Peter</p>
19866    </div>
19867    ```
19868  
19869    @method collection
19870    @for Ember.Templates.helpers
19871    @deprecated Use `{{each}}` helper instead.
19872    @public
19873  */
19874  exports.default = {
19875    setupState: function (state, env, scope, params, hash) {
19876      var read = env.hooks.getValue;
19877
19878      return _emberMetalAssign.default({}, state, {
19879        parentView: env.view,
19880        viewClassOrInstance: getView(read(params[0]), env.owner)
19881      });
19882    },
19883
19884    rerender: function (morph, env, scope, params, hash, template, inverse, visitor) {
19885      // If the hash is empty, the component cannot have extracted a part
19886      // of a mutable param and used it in its layout, because there are
19887      // no params at all.
19888      if (Object.keys(hash).length) {
19889        return morph.getState().manager.rerender(env, hash, visitor, true);
19890      }
19891    },
19892
19893    render: function (node, env, scope, params, hash, template, inverse, visitor) {
19894      var state = node.getState();
19895      var parentView = state.parentView;
19896
19897      var options = { component: state.viewClassOrInstance, layout: null };
19898      if (template) {
19899        options.createOptions = {
19900          _itemViewTemplate: template && { raw: template },
19901          _itemViewInverse: inverse && { raw: inverse }
19902        };
19903      }
19904
19905      if (hash.itemView) {
19906        hash.itemViewClass = hash.itemView;
19907      }
19908
19909      if (hash.emptyView) {
19910        hash.emptyViewClass = hash.emptyView;
19911      }
19912
19913      var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(node, env, hash, options, parentView, null, scope, template);
19914      state.manager = nodeManager;
19915
19916      nodeManager.render(env, hash, visitor);
19917    }
19918  };
19919
19920  function getView(viewPath, container) {
19921    var viewClassOrInstance;
19922
19923    if (!viewPath) {
19924      viewClassOrInstance = _emberViewsViewsCollection_view.default;
19925    } else {
19926      viewClassOrInstance = _emberViewsStreamsUtils.readViewFactory(viewPath, container);
19927    }
19928
19929    return viewClassOrInstance;
19930  }
19931});
19932enifed('ember-htmlbars/keywords/component', ['exports', 'htmlbars-runtime/hooks', 'ember-htmlbars/keywords/closure-component', 'ember-metal/features', 'ember-metal/empty_object', 'ember-metal/assign'], function (exports, _htmlbarsRuntimeHooks, _emberHtmlbarsKeywordsClosureComponent, _emberMetalFeatures, _emberMetalEmpty_object, _emberMetalAssign) {
19933  /**
19934    @module ember
19935    @submodule ember-templates
19936    @public
19937  */
19938  'use strict';
19939
19940  /**
19941    The `{{component}}` helper lets you add instances of `Ember.Component` to a
19942    template. See [Ember.Component](/api/classes/Ember.Component.html) for
19943    additional information on how a `Component` functions.
19944    `{{component}}`'s primary use is for cases where you want to dynamically
19945    change which type of component is rendered as the state of your application
19946    changes. The provided block will be applied as the template for the component.
19947    Given an empty `<body>` the following template:
19948  
19949    ```handlebars
19950    {{! application.hbs }}
19951    {{component infographicComponentName}}
19952    ```
19953  
19954    And the following application code:
19955  
19956    ```javascript
19957    export default Ember.Controller.extend({
19958      infographicComponentName: computed('isMarketOpen', {
19959        get() {
19960          if (this.get('isMarketOpen')) {
19961            return 'live-updating-chart';
19962          } else {
19963            return 'market-close-summary';
19964          }
19965        }
19966      })
19967    });
19968    ```
19969  
19970    The `live-updating-chart` component will be appended when `isMarketOpen` is
19971    `true`, and the `market-close-summary` component will be appended when
19972    `isMarketOpen` is `false`. If the value changes while the app is running,
19973    the component will be automatically swapped out accordingly.
19974    Note: You should not use this helper when you are consistently rendering the same
19975    component. In that case, use standard component syntax, for example:
19976  
19977    ```handlebars
19978    {{! application.hbs }}
19979    {{live-updating-chart}}
19980    ```
19981  
19982    ## Nested Usage
19983  
19984    The `component` helper can be used to package a component path with initial attrs.
19985    The included attrs can then be merged during the final invocation.
19986  
19987    For example, given a `person-form` component with the following template:
19988  
19989    ```handlebars
19990    {{yield (hash
19991        nameInput=(component "my-input-component" value=model.name placeholder="First Name"))}}
19992    ```
19993  
19994    The following snippet:
19995  
19996    ```
19997    {{#person-form as |form|}}
19998      {{component form.nameInput placeholder="Username"}}
19999    {{/person-form}}
20000    ```
20001  
20002    would output an input whose value is already bound to `model.name` and `placeholder`
20003    is "Username".
20004  
20005    @method component
20006    @since 1.11.0
20007    @for Ember.Templates.helpers
20008    @public
20009  */
20010
20011  exports.default = function (morph, env, scope, params, hash, template, inverse, visitor) {
20012    if (!morph) {
20013      return _emberHtmlbarsKeywordsClosureComponent.default(env, params, hash);
20014    }
20015
20016    var newHash = _emberMetalAssign.default(new _emberMetalEmpty_object.default(), hash);
20017
20018    _htmlbarsRuntimeHooks.keyword('@element_component', morph, env, scope, params, newHash, template, inverse, visitor);
20019    return true;
20020  };
20021});
20022enifed('ember-htmlbars/keywords/debugger', ['exports', 'ember-metal/debug'], function (exports, _emberMetalDebug) {
20023  /*jshint debug:true*/
20024
20025  /**
20026  @module ember
20027  @submodule ember-htmlbars
20028  */
20029
20030  'use strict';
20031
20032  exports.default = debuggerKeyword;
20033
20034  /**
20035    Execute the `debugger` statement in the current template's context.
20036  
20037    ```handlebars
20038    {{debugger}}
20039    ```
20040  
20041    When using the debugger helper you will have access to a `get` function. This
20042    function retrieves values available in the context of the template.
20043    For example, if you're wondering why a value `{{foo}}` isn't rendering as
20044    expected within a template, you could place a `{{debugger}}` statement and,
20045    when the `debugger;` breakpoint is hit, you can attempt to retrieve this value:
20046  
20047    ```
20048    > get('foo')
20049    ```
20050  
20051    `get` is also aware of keywords. So in this situation
20052  
20053    ```handlebars
20054    {{#each items as |item|}}
20055      {{debugger}}
20056    {{/each}}
20057    ```
20058  
20059    You'll be able to get values from the current item:
20060  
20061    ```
20062    > get('item.name')
20063    ```
20064  
20065    You can also access the context of the view to make sure it is the object that
20066    you expect:
20067  
20068    ```
20069    > context
20070    ```
20071  
20072    @method debugger
20073    @for Ember.Templates.helpers
20074    @public
20075  */
20076
20077  function debuggerKeyword(morph, env, scope) {
20078    /* jshint unused: false, debug: true */
20079
20080    var view = env.hooks.getValue(scope.getLocal('view'));
20081    var context = env.hooks.getValue(scope.getSelf());
20082
20083    function get(path) {
20084      return env.hooks.getValue(env.hooks.get(env, scope, path));
20085    }
20086
20087    _emberMetalDebug.info('Use `view`, `context`, and `get(<path>)` to debug this template.');
20088
20089    debugger;
20090
20091    return true;
20092  }
20093});
20094enifed('ember-htmlbars/keywords/each', ['exports'], function (exports) {
20095  /**
20096  @module ember
20097  @submodule ember-htmlbars
20098  */
20099
20100  'use strict';
20101
20102  exports.default = each;
20103
20104  function each(morph, env, scope, params, hash, template, inverse, visitor) {
20105    var getValue = env.hooks.getValue;
20106    var keyword = hash['-legacy-keyword'] && getValue(hash['-legacy-keyword']);
20107
20108    /* START: Support of legacy ArrayController. TODO: Remove after 1st 2.0 TLS release */
20109    var firstParam = params[0] && getValue(params[0]);
20110    if (firstParam && firstParam._isArrayController) {
20111      env.hooks.block(morph, env, scope, '-legacy-each-with-controller', params, hash, template, inverse, visitor);
20112      return true;
20113    }
20114    /* END: Support of legacy ArrayController */
20115
20116    if (keyword) {
20117      env.hooks.block(morph, env, scope, '-legacy-each-with-keyword', params, hash, template, inverse, visitor);
20118      return true;
20119    }
20120
20121    return false;
20122  }
20123});
20124enifed('ember-htmlbars/keywords/element-component', ['exports', 'ember-metal/assign', 'ember-htmlbars/keywords/closure-component', 'ember-htmlbars/utils/lookup-component', 'ember-htmlbars/utils/extract-positional-params'], function (exports, _emberMetalAssign, _emberHtmlbarsKeywordsClosureComponent, _emberHtmlbarsUtilsLookupComponent, _emberHtmlbarsUtilsExtractPositionalParams) {
20125  'use strict';
20126
20127  exports.default = {
20128    setupState: function (lastState, env, scope, params, hash) {
20129      var componentPath = getComponentPath(params[0], env);
20130      return _emberMetalAssign.default({}, lastState, {
20131        componentPath: componentPath,
20132        isComponentHelper: true
20133      });
20134    },
20135
20136    render: function (morph) {
20137      var state = morph.getState();
20138
20139      if (state.manager) {
20140        state.manager.destroy();
20141      }
20142
20143      // Force the component hook to treat this as a first-time render,
20144      // because normal components (`<foo-bar>`) cannot change at runtime,
20145      // but the `{{component}}` helper can.
20146      state.manager = null;
20147
20148      for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
20149        rest[_key - 1] = arguments[_key];
20150      }
20151
20152      render.apply(undefined, [morph].concat(rest));
20153    },
20154
20155    rerender: render
20156  };
20157
20158  function getComponentPath(param, env) {
20159    var path = env.hooks.getValue(param);
20160    if (_emberHtmlbarsKeywordsClosureComponent.isComponentCell(path)) {
20161      path = path[_emberHtmlbarsKeywordsClosureComponent.COMPONENT_PATH];
20162    }
20163    return path;
20164  }
20165
20166  function render(morph, env, scope, _ref, hash, template, inverse, visitor) {
20167    var path = _ref[0];
20168
20169    var params = _ref.slice(1);
20170
20171    var isRerender = arguments.length <= 8 || arguments[8] === undefined ? false : arguments[8];
20172
20173    var _morph$getState = morph.getState();
20174
20175    var componentPath = _morph$getState.componentPath;
20176
20177    // If the value passed to the {{component}} helper is undefined or null,
20178    // don't create a new ComponentNode.
20179    if (componentPath === undefined || componentPath === null) {
20180      return;
20181    }
20182
20183    path = env.hooks.getValue(path);
20184
20185    if (isRerender) {
20186      var result = _emberHtmlbarsUtilsLookupComponent.default(env.owner, componentPath);
20187      var component = result.component;
20188
20189      _emberHtmlbarsUtilsExtractPositionalParams.default(null, component, params, hash);
20190    }
20191
20192    if (_emberHtmlbarsKeywordsClosureComponent.isComponentCell(path)) {
20193      var closureComponent = env.hooks.getValue(path);
20194
20195      // This needs to be done in each nesting level to avoid raising assertions
20196      _emberHtmlbarsKeywordsClosureComponent.processPositionalParamsFromCell(closureComponent, params, hash);
20197      params = [];
20198      hash = _emberHtmlbarsKeywordsClosureComponent.mergeInNewHash(closureComponent[_emberHtmlbarsKeywordsClosureComponent.COMPONENT_HASH], hash);
20199    }
20200
20201    var templates = { default: template, inverse: inverse };
20202    env.hooks.component(morph, env, scope, componentPath, params, hash, templates, visitor);
20203  }
20204});
20205enifed('ember-htmlbars/keywords/get', ['exports', 'ember-metal/debug', 'ember-metal/streams/stream', 'ember-metal/streams/utils', 'ember-htmlbars/utils/subscribe', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/observer'], function (exports, _emberMetalDebug, _emberMetalStreamsStream, _emberMetalStreamsUtils, _emberHtmlbarsUtilsSubscribe, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalObserver) {
20206  /**
20207  @module ember
20208  @submodule ember-templates
20209  */
20210
20211  'use strict';
20212
20213  function labelFor(source, key) {
20214    var sourceLabel = source.label ? source.label : '';
20215    var keyLabel = key.label ? key.label : '';
20216    return '(get ' + sourceLabel + ' ' + keyLabel + ')';
20217  }
20218
20219  var DynamicKeyStream = _emberMetalStreamsStream.default.extend({
20220    init: function (source, keySource) {
20221      // Used to get the original path for debugging purposes.
20222      var label = labelFor(source, keySource);
20223
20224      this.label = label;
20225      this.path = label;
20226      this.sourceDep = this.addMutableDependency(source);
20227      this.keyDep = this.addMutableDependency(keySource);
20228      this.observedObject = null;
20229      this.observedKey = null;
20230    },
20231
20232    key: function () {
20233      var key = this.keyDep.getValue();
20234      if (typeof key === 'string') {
20235        return key;
20236      }
20237    },
20238
20239    compute: function () {
20240      var object = this.sourceDep.getValue();
20241      var key = this.key();
20242      if (object && key) {
20243        return _emberMetalProperty_get.get(object, key);
20244      }
20245    },
20246
20247    setValue: function (value) {
20248      var object = this.sourceDep.getValue();
20249      var key = this.key();
20250      if (object) {
20251        _emberMetalProperty_set.set(object, key, value);
20252      }
20253    },
20254
20255    _super$revalidate: _emberMetalStreamsStream.default.prototype.revalidate,
20256
20257    revalidate: function (value) {
20258      this._super$revalidate(value);
20259
20260      var object = this.sourceDep.getValue();
20261      var key = this.key();
20262      if (object !== this.observedObject || key !== this.observedKey) {
20263        this._clearObservedObject();
20264
20265        if (object && typeof object === 'object' && key) {
20266          _emberMetalObserver.addObserver(object, key, this, this.notify);
20267          this.observedObject = object;
20268          this.observedKey = key;
20269        }
20270      }
20271    },
20272
20273    _clearObservedObject: function () {
20274      if (this.observedObject) {
20275        _emberMetalObserver.removeObserver(this.observedObject, this.observedKey, this, this.notify);
20276        this.observedObject = null;
20277        this.observedKey = null;
20278      }
20279    }
20280  });
20281
20282  var buildStream = function buildStream(params) {
20283    var objRef = params[0];
20284    var pathRef = params[1];
20285
20286    _emberMetalDebug.assert('The first argument to {{get}} must be a stream', _emberMetalStreamsUtils.isStream(objRef));
20287    _emberMetalDebug.assert('{{get}} requires at least two arguments', params.length > 1);
20288
20289    var stream = buildDynamicKeyStream(objRef, pathRef);
20290
20291    return stream;
20292  };
20293
20294  function buildDynamicKeyStream(source, keySource) {
20295    if (!_emberMetalStreamsUtils.isStream(keySource)) {
20296      return source.get(keySource);
20297    } else {
20298      return new DynamicKeyStream(source, keySource);
20299    }
20300  }
20301
20302  /**
20303    Dynamically look up a property on an object. The second argument to `{{get}}`
20304    should have a string value, although it can be bound.
20305  
20306    For example, these two usages are equivilent:
20307  
20308    ```handlebars
20309    {{person.height}}
20310    {{get person "height"}}
20311    ```
20312  
20313    If there were several facts about a person, the `{{get}}` helper can dynamically
20314    pick one:
20315  
20316    ```handlebars
20317    {{get person factName}}
20318    ```
20319  
20320    For a more complex example, this template would allow the user to switch
20321    between showing the user's height and weight with a click:
20322  
20323    ```handlebars
20324    {{get person factName}}
20325    <button {{action (mut factName) "height"}}>Show height</button>
20326    <button {{action (mut factName) "weight"}}>Show weight</button>
20327    ```
20328  
20329    The `{{get}}` helper can also respect mutable values itself. For example:
20330  
20331    ```handlebars
20332    {{input value=(mut (get person factName)) type="text"}}
20333    <button {{action (mut factName) "height"}}>Show height</button>
20334    <button {{action (mut factName) "weight"}}>Show weight</button>
20335    ```
20336  
20337    Would allow the user to swap what fact is being displayed, and also edit
20338    that fact via a two-way mutable binding.
20339  
20340    @public
20341    @method get
20342    @for Ember.Templates.helpers
20343    @since 2.1.0
20344  */
20345  function getKeyword(morph, env, scope, params, hash, template, inverse, visitor) {
20346    if (morph === null) {
20347      return buildStream(params);
20348    } else {
20349      var stream = undefined;
20350      if (morph.linkedResult) {
20351        stream = morph.linkedResult;
20352      } else {
20353        stream = buildStream(params);
20354
20355        _emberHtmlbarsUtilsSubscribe.default(morph, env, scope, stream);
20356        env.hooks.linkRenderNode(morph, env, scope, null, params, hash);
20357
20358        morph.linkedResult = stream;
20359      }
20360      env.hooks.range(morph, env, scope, null, stream, visitor);
20361    }
20362
20363    return true;
20364  }
20365
20366  exports.default = getKeyword;
20367});
20368enifed('ember-htmlbars/keywords/input', ['exports', 'ember-metal/debug', 'ember-metal/assign'], function (exports, _emberMetalDebug, _emberMetalAssign) {
20369  /**
20370  @module ember
20371  @submodule ember-templates
20372  */
20373  'use strict';
20374
20375  /**
20376    The `{{input}}` helper lets you create an HTML `<input />` component.
20377    It causes an `Ember.TextField` component to be rendered.  For more info,
20378    see the [Ember.TextField](/api/classes/Ember.TextField.html) docs and
20379    the [templates guide](http://emberjs.com/guides/templates/input-helpers/).
20380  
20381    ```handlebars
20382    {{input value="987"}}
20383    ```
20384  
20385    renders as:
20386  
20387    ```HTML
20388    <input type="text" value="987" />
20389    ```
20390  
20391    ### Text field
20392  
20393    If no `type` option is specified, a default of type 'text' is used.
20394  
20395    Many of the standard HTML attributes may be passed to this helper.
20396  
20397    <table>
20398      <tr><td>`readonly`</td><td>`required`</td><td>`autofocus`</td></tr>
20399      <tr><td>`value`</td><td>`placeholder`</td><td>`disabled`</td></tr>
20400      <tr><td>`size`</td><td>`tabindex`</td><td>`maxlength`</td></tr>
20401      <tr><td>`name`</td><td>`min`</td><td>`max`</td></tr>
20402      <tr><td>`pattern`</td><td>`accept`</td><td>`autocomplete`</td></tr>
20403      <tr><td>`autosave`</td><td>`formaction`</td><td>`formenctype`</td></tr>
20404      <tr><td>`formmethod`</td><td>`formnovalidate`</td><td>`formtarget`</td></tr>
20405      <tr><td>`height`</td><td>`inputmode`</td><td>`multiple`</td></tr>
20406      <tr><td>`step`</td><td>`width`</td><td>`form`</td></tr>
20407      <tr><td>`selectionDirection`</td><td>`spellcheck`</td><td>&nbsp;</td></tr>
20408    </table>
20409  
20410  
20411    When set to a quoted string, these values will be directly applied to the HTML
20412    element. When left unquoted, these values will be bound to a property on the
20413    template's current rendering context (most typically a controller instance).
20414  
20415  
20416    A very common use of this helper is to bind the `value` of an input to an Object's attribute:
20417  
20418    ```handlebars
20419    Search:
20420    {{input value=searchWord}}
20421    ```
20422  
20423    In this example, the inital value in the `<input />` will be set to the value of `searchWord`.
20424    If the user changes the text, the value of `searchWord` will also be updated.
20425  
20426    ### Actions
20427    The helper can send multiple actions based on user events.
20428    The action property defines the action which is sent when
20429    the user presses the return key.
20430  
20431    ```handlebars
20432    {{input action="submit"}}
20433    ```
20434  
20435    The helper allows some user events to send actions.
20436  
20437    * `enter`
20438    * `insert-newline`
20439    * `escape-press`
20440    * `focus-in`
20441    * `focus-out`
20442    * `key-press`
20443    * `key-up`
20444  
20445  
20446    For example, if you desire an action to be sent when the input is blurred,
20447    you only need to setup the action name to the event name property.
20448  
20449    ```handlebars
20450    {{input focus-out="alertMessage"}}
20451    ```
20452  
20453    See more about [Text Support Actions](/api/classes/Ember.TextField.html)
20454  
20455  
20456    ### Extending `Ember.TextField`
20457  
20458    Internally, `{{input type="text"}}` creates an instance of `Ember.TextField`, passing
20459    arguments from the helper to `Ember.TextField`'s `create` method. You can extend the
20460    capabilities of text inputs in your applications by reopening this class. For example,
20461    if you are building a Bootstrap project where `data-*` attributes are used, you
20462    can add one to the `TextField`'s `attributeBindings` property:
20463  
20464  
20465    ```javascript
20466    Ember.TextField.reopen({
20467      attributeBindings: ['data-error']
20468    });
20469    ```
20470  
20471    Keep in mind when writing `Ember.TextField` subclasses that `Ember.TextField`
20472    itself extends `Ember.Component`. Expect isolated component semantics, not
20473    legacy 1.x view semantics (like `controller` being present).
20474  
20475    See more about [Ember components](/api/classes/Ember.Component.html)
20476  
20477  
20478    ### Checkbox
20479  
20480    Checkboxes are special forms of the `{{input}}` helper.  To create a `<checkbox />`:
20481  
20482    ```handlebars
20483    Emberize Everything:
20484    {{input type="checkbox" name="isEmberized" checked=isEmberized}}
20485    ```
20486  
20487    This will bind checked state of this checkbox to the value of `isEmberized`  -- if either one changes,
20488    it will be reflected in the other.
20489  
20490  
20491    The following HTML attributes can be set via the helper:
20492  
20493    * `checked`
20494    * `disabled`
20495    * `tabindex`
20496    * `indeterminate`
20497    * `name`
20498    * `autofocus`
20499    * `form`
20500  
20501  
20502    ### Extending `Ember.Checkbox`
20503  
20504    Internally, `{{input type="checkbox"}}` creates an instance of `Ember.Checkbox`, passing
20505    arguments from the helper to `Ember.Checkbox`'s `create` method. You can extend the
20506    capablilties of checkbox inputs in your applications by reopening this class. For example,
20507    if you wanted to add a css class to all checkboxes in your application:
20508  
20509    ```javascript
20510    Ember.Checkbox.reopen({
20511      classNames: ['my-app-checkbox']
20512    });
20513    ```
20514  
20515  
20516    @method input
20517    @for Ember.Templates.helpers
20518    @param {Hash} options
20519    @public
20520  */
20521  exports.default = {
20522    setupState: function (lastState, env, scope, params, hash) {
20523      var type = env.hooks.getValue(hash.type);
20524      var componentName = componentNameMap[type] || defaultComponentName;
20525
20526      _emberMetalDebug.assert('{{input type=\'checkbox\'}} does not support setting `value=someBooleanValue`; ' + 'you must use `checked=someBooleanValue` instead.', !(type === 'checkbox' && hash.hasOwnProperty('value')));
20527
20528      return _emberMetalAssign.default({}, lastState, { componentName: componentName });
20529    },
20530
20531    render: function (morph, env, scope, params, hash, template, inverse, visitor) {
20532      env.hooks.component(morph, env, scope, morph.getState().componentName, params, hash, { default: template, inverse: inverse }, visitor);
20533    },
20534
20535    rerender: function () {
20536      this.render.apply(this, arguments);
20537    }
20538  };
20539
20540  var defaultComponentName = '-text-field';
20541
20542  var componentNameMap = {
20543    'checkbox': '-checkbox'
20544  };
20545});
20546enifed('ember-htmlbars/keywords/legacy-yield', ['exports', 'ember-metal/stream
20546s/proxy-stream'], function (exports, _emberMetalStreamsProxyStream) {
20547  'use strict';
20548
20549  exports.default = legacyYield;
20550
20551  function legacyYield(morph, env, _scope, params, hash, template, inverse, visitor) {
20552    var scope = _scope;
20553    var block = scope.getBlock('default');
20554
20555    if (block.arity === 0) {
20556      // Typically, the `controller` local persists through lexical scope.
20557      // However, in this case, the `{{legacy-yield}}` in the legacy each view
20558      // needs to override the controller local for the template it is yielding.
20559      // This megahaxx allows us to override the controller, and most importantly,
20560      // prevents the downstream scope from attempting to bind the `controller` local.
20561      if (hash.controller) {
20562        scope = env.hooks.createChildScope(scope);
20563        scope.bindLocal('controller', new _emberMetalStreamsProxyStream.default(hash.controller, 'controller'));
20564        scope.overrideController = true;
20565      }
20566      block.invoke(env, [], params[0], morph, scope, visitor);
20567    } else {
20568      block.invoke(env, params, undefined, morph, scope, visitor);
20569    }
20570
20571    return true;
20572  }
20573});
20574enifed('ember-htmlbars/keywords/mut', ['exports', 'ember-metal/debug', 'ember-metal/symbol', 'ember-metal/streams/proxy-stream', 'ember-metal/streams/stream', 'ember-metal/streams/utils', 'ember-views/compat/attrs-proxy', 'ember-routing-htmlbars/keywords/closure-action'], function (exports, _emberMetalDebug, _emberMetalSymbol, _emberMetalStreamsProxyStream, _emberMetalStreamsStream, _emberMetalStreamsUtils, _emberViewsCompatAttrsProxy, _emberRoutingHtmlbarsKeywordsClosureAction) {
20575  /**
20576  @module ember
20577  @submodule ember-templates
20578  */
20579
20580  'use strict';
20581
20582  var _ProxyStream$extend;
20583
20584  exports.default = mut;
20585  exports.privateMut = privateMut;
20586  var MUTABLE_REFERENCE = _emberMetalSymbol.default('MUTABLE_REFERENCE');
20587
20588  exports.MUTABLE_REFERENCE = MUTABLE_REFERENCE;
20589  var MutStream = _emberMetalStreamsProxyStream.default.extend((_ProxyStream$extend = {
20590    init: function (stream) {
20591      this.label = '(mut ' + stream.label + ')';
20592      this.path = stream.path;
20593      this.sourceDep = this.addMutableDependency(stream);
20594      this[MUTABLE_REFERENCE] = true;
20595    },
20596
20597    cell: function () {
20598      var source = this;
20599      var value = source.value();
20600
20601      if (value && value[_emberRoutingHtmlbarsKeywordsClosureAction.ACTION]) {
20602        return value;
20603      }
20604
20605      var val = {
20606        value: value,
20607        update: function (val) {
20608          source.setValue(val);
20609        }
20610      };
20611
20612      val[_emberViewsCompatAttrsProxy.MUTABLE_CELL] = true;
20613      return val;
20614    }
20615  }, _ProxyStream$extend[_emberRoutingHtmlbarsKeywordsClosureAction.INVOKE] = function (val) {
20616    this.setValue(val);
20617  }, _ProxyStream$extend));
20618
20619  /**
20620    The `mut` helper lets you __clearly specify__ that a child `Component` can update the
20621    (mutable) value passed to it, which will __change the value of the parent component__.
20622  
20623    This is very helpful for passing mutable values to a `Component` of any size, but
20624    critical to understanding the logic of a large/complex `Component`.
20625  
20626    To specify that a parameter is mutable, when invoking the child `Component`:
20627  
20628    ```handlebars
20629    {{my-child childClickCount=(mut totalClicks)}}
20630    ```
20631  
20632    The child `Component` can then modify the parent's value as needed:
20633  
20634    ```javascript
20635    // my-child.js
20636    export default Component.extend({
20637      click() {
20638        this.get('childClickCount').update(this.get('childClickCount').value + 1);
20639      }
20640    });
20641    ```
20642  
20643    Additionally, the `mut` helper can be combined with the `action` helper to
20644    mutate a value. For example:
20645  
20646    ```handlebars
20647    {{my-child childClickCount=totalClicks click-count-change=(action (mut "totalClicks"))}}
20648    ```
20649  
20650    The child `Component` would invoke the action with the new click value:
20651  
20652    ```javascript
20653    // my-child.js
20654    export default Component.extend({
20655      click() {
20656        this.get('clickCountChange')(this.get('childClickCount') + 1);
20657      }
20658    });
20659    ```
20660  
20661    The `mut` helper changes the `totalClicks` value to what was provided as the action argument.
20662  
20663    See a [2.0 blog post](http://emberjs.com/blog/2015/05/10/run-up-to-two-oh.html#toc_the-code-mut-code-helper) for
20664    additional information on using `{{mut}}`.
20665  
20666    @public
20667    @method mut
20668    @param {Object} [attr] the "two-way" attribute that can be modified.
20669    @for Ember.Templates.helpers
20670    @public
20671  */
20672
20673  function mut(morph, env, scope, originalParams, hash, template, inverse) {
20674    // If `morph` is `null` the keyword is being invoked as a subexpression.
20675    if (morph === null) {
20676      var valueStream = originalParams[0];
20677      return mutParam(env.hooks.getValue, valueStream);
20678    }
20679
20680    return true;
20681  }
20682
20683  function privateMut(morph, env, scope, originalParams, hash, template, inverse) {
20684    // If `morph` is `null` the keyword is being invoked as a subexpression.
20685    if (morph === null) {
20686      var valueStream = originalParams[0];
20687      return mutParam(env.hooks.getValue, valueStream, true);
20688    }
20689
20690    return true;
20691  }
20692
20693  var LiteralStream = _emberMetalStreamsStream.default.extend({
20694    init: function (literal) {
20695      this.literal = literal;
20696      this.label = '(literal ' + literal + ')';
20697    },
20698
20699    compute: function () {
20700      return this.literal;
20701    },
20702
20703    setValue: function (val) {
20704      this.literal = val;
20705      this.notify();
20706    }
20707  });
20708
20709  function mutParam(read, stream, internal) {
20710    if (internal) {
20711      if (!_emberMetalStreamsUtils.isStream(stream)) {
20712        var literal = stream;
20713        stream = new LiteralStream(literal);
20714      }
20715    } else {
20716      _emberMetalDebug.assert('You can only pass a path to mut', _emberMetalStreamsUtils.isStream(stream));
20717    }
20718
20719    if (stream[MUTABLE_REFERENCE]) {
20720      return stream;
20721    }
20722
20723    return new MutStream(stream);
20724  }
20725});
20726enifed('ember-htmlbars/keywords/outlet', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-htmlbars/node-managers/view-node-manager', 'ember-htmlbars/templates/top-level-view', 'ember-metal/features'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberHtmlbarsNodeManagersViewNodeManager, _emberHtmlbarsTemplatesTopLevelView, _emberMetalFeatures) {
20727  /**
20728  @module ember
20729  @submodule ember-templates
20730  */
20731
20732  'use strict';
20733
20734  _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = '[email protected]';
20735
20736  /**
20737    The `{{outlet}}` helper lets you specify where a child route will render in
20738    your template. An important use of the `{{outlet}}` helper is in your
20739    application's `application.hbs` file:
20740  
20741    ```handlebars
20742    {{! app/templates/application.hbs }}
20743  
20744    <!-- header content goes here, and will always display -->
20745    {{my-header}}
20746  
20747    <div class="my-dynamic-content">
20748      <!-- this content will change based on the current route, which depen
20748ds on the current URL -->
20749      {{outlet}}
20750    </div>
20751  
20752    <!-- footer content goes here, and will always display -->
20753    {{my-footer}}
20754    ```
20755  
20756    See [templates guide](http://emberjs.com/guides/templates/the-application-template/) for
20757    additional information on using `{{outlet}}` in `application.hbs`.
20758  
20759    You may also specify a name for the `{{outlet}}`, which is useful when using more than one
20760    `{{outlet}}` in a template:
20761  
20762    ```handlebars
20763    {{outlet "menu"}}
20764    {{outlet "sidebar"}}
20765    {{outlet "main"}}
20766    ```
20767  
20768    Your routes can then render into a specific one of these `outlet`s by specifying the `outlet`
20769    attribute in your `renderTemplate` function:
20770  
20771    ```javascript
20772    
20772// app/routes/menu.js
20773  
20774    export default Ember.Route.extend({
20775      renderTemplate() {
20776        this.render({ outlet: 'menu' });
20777      }
20778    });
20779    ```
20780  
20781    See the [routing guide](http://emberjs.com/guides/routing/rendering-a-template/) for more
20782    information on how your `route` interacts with the `{{outlet}}` helper.
20783  
20784    Note: Your content __will not render__ if there isn't an `{{outlet}}` for it.
20785  
20786    @public
20787    @method outlet
20788    @param {String} [name]
20789    @for Ember.Templates.helpers
20790    @public
20791  */
20792  exports.default = {
20793    willRender: function (renderNode, env) {
20794      env.view.ownerView._outlets.push(renderNode);
20795    },
20796
20797    setupState: function (state, env, scope, params, hash) {
20798      var outletState = env.outletState;
20799      var read = env.hooks.getValue;
20800      var outletName = read(params[0]) || 'main';
20801      var selectedOutletState = outletState[outletName];
20802
20803      var toRender = selectedOutletState && selectedOutletState.render;
20804      if (toRender && !toRender.template && !toRender.ViewClass) {
20805        toRender.template = _emberHtmlbarsTemplatesTopLevelView.default;
20806      }
20807
20808      return {
20809        outletState: selectedOutletState,
20810        hasParentOutlet: env.hasParentOutlet,
20811        manager: state.manager
20812      };
20813    },
20814
20815    childEnv: function (state, env) {
20816      var outletState = state.outletState;
20817      var toRender = outletState && outletState.render;
20818      var meta = toRender && toRender.template && toRender.template.meta;
20819
20820      return env.childWithOutletState(outletState && outletState.outlets, true, meta);
20821    },
20822
20823    isStable: function (lastState, nextState) {
20824      return isStable(lastState.outletState, nextState.outletState);
20825    },
20826
20827    isEmpty: function (state) {
20828      return isEmpty(state.outletState);
20829    },
20830
20831    render: function (renderNode, env, scope, params, hash, template, inverse, visitor) {
20832      var state = renderNode.getState();
20833      var parentView = env.view;
20834      var outletState = state.outletState;
20835      var toRender = outletState.render;
20836      var namespace = env.owner.lookup('application:main');
20837      var LOG_VIEW_LOOKUPS = _emberMetalProperty_get.get(namespace, 'LOG_VIEW_LOOKUPS');
20838
20839      var ViewClass = outletState.render.ViewClass;
20840
20841      if (!state.hasParentOutlet && !ViewClass) {
20842        ViewClass = env.owner._lookupFactory('view:toplevel');
20843      }
20844
20845      var Component;
20846
20847      var options;
20848      var attrs = {};
20849      if (Component) {
20850        options = {
20851          component: Component
20852        };
20853        attrs = toRender.attrs;
20854      } else {
20855        options = {
20856          component: ViewClass,
20857          self: toRender.controller,
20858          createOptions: {
20859            controller: toRender.controller
20860          }
20861        };
20862
20863        template = template || toRender.template && toRender.template.raw;
20864
20865        if (LOG_VIEW_LOOKUPS && ViewClass) {
20866          _emberMetalDebug.info('Rendering ' + toRender.name + ' with ' + ViewClass, { fullName: 'view:' + toRender.name });
20867        }
20868      }
20869
20870      if (state.manager) {
20871        state.manager.destroy();
20872        state.manager = null;
20873      }
20874
20875      var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(renderNode, env, attrs, options, parentView, null, null, template);
20876      state.manager = nodeManager;
20877
20878      nodeManager.render(env, hash, visitor);
20879    }
20880  };
20881
20882  function isEmpty(outletState) {
20883    return !outletState || !outletState.render.ViewClass && !outletState.render.template;
20884  }
20885
20886  function isStable(a, b) {
20887    if (!a && !b) {
20888      return true;
20889    }
20890    if (!a || !b) {
20891      return false;
20892    }
20893    a = a.render;
20894    b = b.render;
20895    for (var key in a) {
20896      if (a.hasOwnProperty(key)) {
20897        // Name is only here for logging & debugging. If two different
20898        // names result in otherwise identical states, they're still
20899        // identical.
20900        if (a[key] !== b[key] && key !== 'name') {
20901          return false;
20902        }
20903      }
20904    }
20905    return true;
20906  }
20907});
20908enifed('ember-htmlbars/keywords/partial', ['exports', 'ember-views/system/lookup_partial', 'htmlbars-runtime'], function (exports, _emberViewsSystemLookup_partial, _htmlbarsRuntime) {
20909  /**
20910  @module ember
20911  @submodule ember-templates
20912  */
20913
20914  'use strict';
20915
20916  /**
20917    The `partial` helper renders another template without
20918    changing the template context:
20919  
20920    ```handlebars
20921    {{foo}}
20922    {{partial "nav"}}
20923    ```
20924  
20925    The above example template will render a template named
20926    "_nav", which has the same context as the parent template
20927    it's rendered into, so if the "_nav" template also referenced
20928    `{{foo}}`, it would print the same thing as the `{{foo}}`
20929    in the above example.
20930  
20931    If a "_nav" template isn't found, the `partial` helper will
20932    fall back to a template named "nav".
20933  
20934    ### Bound template names
20935  
20936    The parameter supplied to `partial` can also be a path
20937    to a property containing a template name, e.g.:
20938  
20939    ```handlebars
20940    {{partial someTemplateName}}
20941    ```
20942  
20943    The above example will look up the value of `someTemplateName`
20944    on the template context (e.g. a controller) and use that
20945    value as the name of the template to render. If the resolved
20946    value is falsy, nothing will be rendered. If `someTemplateName`
20947    changes, the partial will be re-rendered using the new template
20948    name.
20949  
20950  
20951    @method partial
20952    @for Ember.Templates.helpers
20953    @param {String} partialName The name of the template to render minus the leading underscore.
20954    @public
20955  */
20956
20957  exports.default = {
20958    setupState: function (state, env, scope, params, hash) {
20959      return { partialName: env.hooks.getValue(params[0]) };
20960    },
20961
20962    render: function (renderNode, env, scope, params, hash, template, inverse, visitor) {
20963      var state = renderNode.getState();
20964      if (!state.partialName) {
20965        return true;
20966      }
20967      var found = _emberViewsSystemLookup_partial.default(env, state.partialName);
20968      if (!found) {
20969        return true;
20970      }
20971
20972      _htmlbarsRuntime.internal.hostBlock(renderNode, env, scope, found.raw, null, null, visitor, function (options) {
20973        options.templates.template.yield();
20974      });
20975    }
20976  };
20977});
20978enifed('ember-htmlbars/keywords/readonly', ['exports', 'ember-htmlbars/keywords/mut'], function (exports, _emberHtmlbarsKeywordsMut) {
20979  /**
20980  @module ember
20981  @submodule ember-templates
20982  */
20983
20984  'use strict';
20985
20986  exports.default = readonly;
20987
20988  function readonly(morph, env, scope, originalParams, hash, template, inverse) {
20989    // If `morph` is `null` the keyword is being invoked as a subexpression.
20990    if (morph === null) {
20991      var stream = originalParams[0];
20992      if (stream && stream[_emberHtmlbarsKeywordsMut.MUTABLE_REFERENCE]) {
20993        return stream.sourceDep.dependee;
20994      }
20995      return stream;
20996    }
20997
20998    return true;
20999  }
21000});
21001enifed('ember-htmlbars/keywords/textarea', ['exports'], function (exports) {
21002  /**
21003  @module ember
21004  @submodule ember-templates
21005  */
21006
21007  /**
21008    `{{textarea}}` inserts a new instance of `<textarea>` tag into the template.
21009    The attributes of `{{textarea}}` match those of the native HTML tags as
21010    closely as possible.
21011  
21012    The following HTML attributes can be set:
21013  
21014      * `value`
21015      * `name`
21016      * `rows`
21017      * `cols`
21018      * `placeholder`
21019      * `disabled`
21020      * `maxlength`
21021      * `tabindex`
21022      * `selectionEnd`
21023      * `selectionStart`
21024      * `selectionDirection`
21025      * `wrap`
21026      * `readonly`
21027      * `autofocus`
21028      * `form`
21029      * `spellcheck`
21030      * `required`
21031  
21032    When set to a quoted string, these value will be directly applied to the HTML
21033    element. When left unquoted, these values will be bound to a property on the
21034    template's current rendering context (most typically a controller instance).
21035  
21036    Unbound:
21037  
21038    ```handlebars
21039    {{textarea value="Lots of static text that ISN'T bound"}}
21040    ```
21041  
21042    Would result in the following HTML:
21043  
21044    ```html
21045    <textarea class="ember-text-area">
21046      Lots of static text that ISN'T bound
21047    </textarea>
21048    ```
21049  
21050    Bound:
21051  
21052    In the following example, the `writtenWords` property on `App.ApplicationController`
21053    will be updated live as the user types 'Lots of text that IS bound' into
21054    the text area of their browser's window.
21055  
21056    ```javascript
21057    App.ApplicationController = Ember.Controller.extend({
21058      writtenWords: "Lots of text that IS bound"
21059    });
21060    ```
21061  
21062    ```handlebars
21063    {{textarea value=writtenWords}}
21064    ```
21065  
21066     Would result in the following HTML:
21067  
21068    ```html
21069    <textarea class="ember-text-area">
21070      Lots of text that IS bound
21071    </textarea>
21072    ```
21073  
21074    If you wanted a one way binding between the text area and a div tag
21075    somewhere else on your screen, you could use `Ember.computed.oneWay`:
21076  
21077    ```javascript
21078    App.ApplicationController = Ember.Controller.extend({
21079      writtenWords: "Lots of text that IS bound",
21080      outputWrittenWords: Ember.computed.oneWay("writtenWords")
21081    });
21082    ```
21083  
21084    ```handlebars
21085    {{textarea value=writtenWords}}
21086  
21087    <div>
21088      {{outputWrittenWords}}
21089    </div>
21090    ```
21091  
21092    Would result in the following HTML:
21093  
21094    ```html
21095    <textarea class="ember-text-area">
21096      Lots of text that IS bound
21097    </textarea>
21098  
21099    <-- the following div will be updated in real time as you type -->
21100  
21101    <div>
21102      Lots of text that IS bound
21103    </div>
21104    ```
21105  
21106    Finally, this example really shows the power and ease of Ember when two
21107    properties are bound to eachother via `Ember.computed.alias`. Type into
21108    either text area box and they'll both stay in sync. Note that
21109    `Ember.computed.alias` costs more in terms of performance, so only use it when
21110    your really binding in both directions:
21111  
21112    ```javascript
21113    App.ApplicationController = Ember.Controller.extend({
21114      writtenWords: "Lots of text that IS bound",
21115      twoWayWrittenWords: Ember.computed.alias("writtenWords")
21116    });
21117    ```
21118  
21119    ```handlebars
21120    {{textarea value=writtenWords}}
21121    {{textarea value=twoWayWrittenWords}}
21122    ```
21123  
21124    ```html
21125    <textarea id="ember1" class="ember-text-area">
21126      Lots of text that IS bound
21127    </textarea>
21128  
21129    <-- both updated in real time -->
21130  
21131    <textarea id="ember2" class="ember-text-area">
21132      Lots of text that IS bound
21133    </textarea>
21134    ```
21135  
21136    ### Actions
21137  
21138    The helper can send multiple actions based on user events.
21139  
21140    The action property defines the action which is send when
21141    the user presses the return key.
21142  
21143    ```handlebars
21144    {{input action="submit"}}
21145    ```
21146  
21147    The helper allows some user events to send actions.
21148  
21149  * `enter`
21150  * `insert-newline`
21151  * `escape-press`
21152  * `focus-in`
21153  * `focus-out`
21154  * `key-press`
21155  
21156    For example, if you desire an action to be sent when the input is blurred,
21157    you only need to setup the action name to the event name property.
21158  
21159    ```handlebars
21160    {{textarea focus-in="alertMessage"}}
21161    ```
21162  
21163    See more about [Text Support Actions](/api/classes/Ember.TextArea.html)
21164  
21165    ### Extension
21166  
21167    Internally, `{{textarea}}` creates an instance of `Ember.TextArea`, passing
21168    arguments from the helper to `Ember.TextArea`'s `create` method. You can
21169    extend the capabilities of text areas in your application by reopening this
21170    class. For example, if you are building a Bootstrap project where `data-*`
21171    attributes are used, you can globally add support for a `data-*` attribute
21172    on all `{{textarea}}`s' in your app by reopening `Ember.TextArea` or
21173    `Ember.TextSupport` and adding it to the `attributeBindings` concatenated
21174    property:
21175  
21176    ```javascript
21177    Ember.TextArea.reopen({
21178      attributeBindings: ['data-error']
21179    });
21180    ```
21181  
21182    Keep in mind when writing `Ember.TextArea` subclasses that `Ember.TextArea`
21183    itself extends `Ember.Component`. Expect isolated component semantics, not
21184    legacy 1.x view semantics (like `controller` being present).
21185  
21186    See more about [Ember components](/api/classes/Ember.Component.html)
21187  
21188    @method textarea
21189    @for Ember.Templates.helpers
21190    @param {Hash} options
21191    @public
21192  */
21193  'use strict';
21194
21195  exports.default = textarea;
21196
21197  function textarea(morph, env, scope, originalParams, hash, template, inverse, visitor) {
21198    env.hooks.component(morph, env, scope, '-text-area', originalParams, hash, { default: template, inverse: inverse }, visitor);
21199    return true;
21200  }
21201});
21202enifed('ember-htmlbars/keywords/unbound', ['exports', 'ember-metal/debug', 'ember-metal/stream
21202s/stream', 'ember-metal/streams/utils'], function (exports, _emberMetalDebug, _emberMetalStreamsStream, _emberMetalStreamsUtils) {
21203  /**
21204  @module ember
21205  @submodule ember-templates
21206  */
21207
21208  'use strict';
21209
21210  exports.default = unbound;
21211
21212  /**
21213    The `{{unbound}}` helper disconnects the one-way binding of a property,
21214    essentially freezing its value at the moment of rendering. For example,
21215    in this example the display of the variable `name` will not change even
21216    if it is set with a new value:
21217  
21218    ```handlebars
21219    {{unbound name}}
21220    ```
21221  
21222    Like any helper, the `unbound` helper can accept a nested helper expression.
21223    This allows for custom helpers to be rendered unbound:
21224  
21225    ```handlebars
21226    {{unbound (some-custom-helper)}}
21227    {{unbound (capitalize name)}}
21228    {{! You can use any helper, including unbound, in a nested expression }}
21229    {{capitalize (unbound name)}}
21230    ```
21231  
21232    The `unbound` helper only accepts a single argument, and it return an
21233    unbound value.
21234  
21235    @method unbound
21236    @for Ember.Templates.helpers
21237    @public
21238  */
21239
21240  var VolatileStream = _emberMetalStreamsStream.default.extend({
21241    init: function (source) {
21242      this.label = '(volatile ' + source.label + ')';
21243      this.source = source;
21244      this.addDependency(source);
21245    },
21246
21247    value: function () {
21248      return _emberMetalStreamsUtils.read(this.source);
21249    },
21250
21251    notify: function () {}
21252  });
21253
21254  function unbound(morph, env, scope, params, hash, template, inverse, visitor) {
21255    _emberMetalDebug.assert('unbound helper cannot be called with multiple params or hash params', params.length === 1 && Object.keys(hash).length === 0);
21256    _emberMetalDebug.assert('unbound helper cannot be called as a block', !template);
21257
21258    if (morph === null) {
21259      return new VolatileStream(params[0]);
21260    }
21261
21262    var stream = undefined;
21263    if (morph.linkedResult) {
21264      stream = morph.linkedResult;
21265    } else {
21266      stream = new VolatileStream(params[0]);
21267      morph.linkedResult = stream;
21268    }
21269    env.hooks.range(morph, env, scope, null, stream, visitor);
21270    return true;
21271  }
21272});
21273enifed('ember-htmlbars/keywords/view', ['exports', 'ember-views/streams/utils', 'ember-views/views/view', 'ember-htmlbars/node-managers/view-node-manager'], function (exports, _emberViewsStreamsUtils, _emberViewsViewsView, _emberHtmlbarsNodeManagersViewNodeManager) {
21274  /**
21275  @module ember
21276  @submodule ember-templates
21277  */
21278
21279  'use strict';
21280
21281  /**
21282    `{{view}}` inserts a new instance of an `Ember.View` into a template passing its
21283    options to the `Ember.View`'s `create` method and using the supplied block as
21284    the view's own template.
21285  
21286    An empty `<body>` and the following template:
21287  
21288    ```handlebars
21289    A span:
21290    {{#view tagName="span"}}
21291      hello.
21292    {{/view}}
21293    ```
21294  
21295    Will result in HTML structure:
21296  
21297    ```html
21298    <body>
21299      <!-- Note: the handlebars template script
21300           also results in a rendered Ember.View
21301           which is the outer <div> here -->
21302  
21303      <div class="ember-view">
21304        A span:
21305        <span id="ember1" class="ember-view">
21306          Hello.
21307        </span>
21308      </div>
21309    </body>
21310    ```
21311  
21312    ### `parentView` setting
21313  
21314    The `parentView` property of the new `Ember.View` instance created through
21315    `{{view}}` will be set to the `Ember.View` instance of the template where
21316    `{{view}}` was called.
21317  
21318    ```javascript
21319    aView = Ember.View.create({
21320      template: Ember.Handlebars.compile("{{#view}} my parent: {{parentView.elementId}} {{/view}}")
21321    });
21322  
21323    aView.appendTo('body');
21324    ```
21325  
21326    Will result in HTML structure:
21327  
21328    ```html
21329    <div id="ember1" class="ember-view">
21330      <div id="ember2" class="ember-view">
21331        my parent: ember1
21332      </div>
21333    </div>
21334    ```
21335  
21336    ### Setting CSS id and class attributes
21337  
21338    The HTML `id` attribute can be set on the `{{view}}`'s resulting element with
21339    the `id` option. This option will _not_ be passed to `Ember.View.create`.
21340  
21341    ```handlebars
21342    {{#view tagName="span" id="a-custom-id"}}
21343      hello.
21344    {{/view}}
21345    ```
21346  
21347    Results in the following HTML structure:
21348  
21349    ```html
21350    <div class="ember-view">
21351      <span id="a-custom-id" class="ember-view">
21352        hello.
21353      </span>
21354    </div>
21355    ```
21356  
21357    The HTML `class` attribute can be set on the `{{view}}`'s resulting element
21358    with the `class` or `classNameBindings` options. The `class` option will
21359    directly set the CSS `class` attribute and will not be passed to
21360    `Ember.View.create`. `classNameBindings` will be passed to `create` and use
21361    `Ember.View`'s class name binding functionality:
21362  
21363    ```handlebars
21364    {{#view tagName="span" class="a-custom-class"}}
21365      hello.
21366    {{/view}}
21367    ```
21368  
21369    Results in the following HTML structure:
21370  
21371    ```html
21372    <div class="ember-view">
21373      <span id="ember2" class="ember-view a-custom-class">
21374        hello.
21375      </span>
21376    </div>
21377    ```
21378  
21379    ### Supplying a different view class
21380  
21381    `{{view}}` can take an optional first argument before its supplied options to
21382    specify a path to a custom view class.
21383  
21384    ```handlebars
21385    {{#view "custom"}}{{! will look up App.CustomView }}
21386      hello.
21387    {{/view}}
21388    ```
21389  
21390    The first argument can also be a relative path accessible from the current
21391    context.
21392  
21393    ```javascript
21394    MyApp = Ember.Application.create({});
21395    MyApp.OuterView = Ember.View.extend({
21396      innerViewClass: Ember.View.extend({
21397        classNames: ['a-custom-view-class-as-property']
21398      }),
21399      template: Ember.Handlebars.compile('{{#view view.innerViewClass}} hi {{/view}}')
21400    });
21401  
21402    MyApp.OuterView.create().appendTo('body');
21403    ```
21404  
21405    Will result in the following HTML:
21406  
21407    ```html
21408    <div id="ember1" class="ember-view">
21409      <div id="ember2" class="ember-view a-custom-view-class-as-property">
21410        hi
21411      </div>
21412    </div>
21413    ```
21414  
21415    ### Blockless use
21416  
21417    If you supply a custom `Ember.View` subclass that specifies its own template
21418    or provide a `templateName` option to `{{view}}` it can be used without
21419    supplying a block. Attempts to use both a `templateName` option and supply a
21420    block will throw an error.
21421  
21422    ```javascript
21423    var App = Ember.Application.create();
21424    App.WithTemplateDefinedView = Ember.View.extend({
21425      templateName: 'defined-template'
21426    });
21427    ```
21428  
21429    ```handlebars
21430    {{! application.hbs }}
21431    {{view 'with-template-defined'}}
21432    ```
21433  
21434    ```handlebars
21435    {{! defined-template.hbs }}
21436    Some content for the defined template view.
21437    ```
21438  
21439    ### `viewName` property
21440  
21441    You can supply a `viewName` option to `{{view}}`. The `Ember.View` instance
21442    will be referenced as a property of its parent view by this name.
21443  
21444    ```javascript
21445    aView = Ember.View.create({
21446      template: Ember.Handlebars.compile('{{#view viewName="aChildByName"}} hi {{/view}}')
21447    });
21448  
21449    aView.appendTo('body');
21450    aView.get('aChildByName') // the instance of Ember.View created by {{view}} helper
21451    ```
21452  
21453    @method view
21454    @for Ember.Templates.helpers
21455    @public
21456    @deprecated
21457  */
21458
21459  exports.default = {
21460    setupState: function (state, env, scope, params, hash) {
21461      var read = env.hooks.getValue;
21462      var targetObject = read(scope.getSelf());
21463      var viewClassOrInstance = state.viewClassOrInstance;
21464      if (!viewClassOrInstance) {
21465        viewClassOrInstance = getView(read(params[0]), env.owner);
21466      }
21467
21468      // if parentView exists, use its controller (the default
21469      // behavior), otherwise use `scope.self` as the controller
21470      var controller = scope.hasLocal('view') ? null : read(scope.getSelf());
21471
21472      return {
21473        manager: state.manager,
21474        parentView: env.view,
21475        controller: controller,
21476        targetObject: targetObject,
21477        viewClassOrInstance: viewClassOrInstance
21478      };
21479    },
21480
21481    rerender: function (morph, env, scope, params, hash, template, inverse, visitor) {
21482      // If the hash is empty, the component cannot have extracted a part
21483      // of a mutable param and used it in its layout, because there are
21484      // no params at all.
21485      if (Object.keys(hash).length) {
21486        return morph.getState().manager.rerender(env, hash, visitor, true);
21487      }
21488    },
21489
21490    render: function (node, env, scope, params, hash, template, inverse, visitor) {
21491      if (hash.tag) {
21492        hash = swapKey(hash, 'tag', 'tagName');
21493      }
21494
21495      if (hash.classNameBindings) {
21496        hash.classNameBindings = hash.classNameBindings.split(' ');
21497      }
21498
21499      var state = node.getState();
21500      var parentView = state.parentView;
21501
21502      var options = {
21503        component: state.viewClassOrInstance,
21504        layout: null
21505      };
21506
21507      options.createOptions = {};
21508      if (state.controller) {
21509        // Use `_controller` to avoid stomping on a CP
21510        // that exists in the target view/component
21511        options.createOptions._controller = state.controller;
21512      }
21513
21514      if (state.targetObject) {
21515        // Use `_targetObject` to avoid stomping on a CP
21516        // that exists in the target view/component
21517        options.createOptions._targetObject = state.targetObject;
21518      }
21519
21520      if (state.manager) {
21521        state.manager.destroy();
21522        state.manager = null;
21523      }
21524
21525      var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(node, env, hash, options, parentView, null, scope, template);
21526      state.manager = nodeManager;
21527
21528      nodeManager.render(env, hash, visitor);
21529    }
21530  };
21531
21532  function getView(viewPath, owner) {
21533    var viewClassOrInstance;
21534
21535    if (!viewPath) {
21536      if (owner) {
21537        viewClassOrInstance = owner._lookupFactory('view:toplevel');
21538      } else {
21539        viewClassOrInstance = _emberViewsViewsView.default;
21540      }
21541    } else {
21542      viewClassOrInstance = _emberViewsStreamsUtils.readViewFactory(viewPath, owner);
21543    }
21544
21545    return viewClassOrInstance;
21546  }
21547
21548  function swapKey(hash, original, update) {
21549    var newHash = {};
21550
21551    for (var prop in hash) {
21552      if (prop === original) {
21553        newHash[update] = hash[prop];
21554      } else {
21555        newHash[prop] = hash[prop];
21556      }
21557    }
21558
21559    return newHash;
21560  }
21561});
21562enifed('ember-htmlbars/keywords/with', ['exports', 'ember-metal/debug', 'htmlbars-runtime'], function (exports, _emberMetalDebug, _htmlbarsRuntime) {
21563  /**
21564  @module ember
21565  @submodule ember-templates
21566  */
21567
21568  'use strict';
21569
21570  exports.default = {
21571    isStable: function () {
21572      return true;
21573    },
21574
21575    isEmpty: function (state) {
21576      return false;
21577    },
21578
21579    render: function (morph, env, scope, params, hash, template, inverse, visitor) {
21580      _emberMetalDebug.assert('{{#with foo}} must be called with a single argument or the use the ' + '{{#with foo as |bar|}} syntax', params.length === 1);
21581
21582      _emberMetalDebug.assert('The {{#with}} helper must be called with a block', !!template);
21583
21584      _htmlbarsRuntime.internal.continueBlock(morph, env, scope, 'with', params, hash, template, inverse, visitor);
21585    },
21586
21587    rerender: function (morph, env, scope, params, hash, template, inverse, visitor) {
21588      _htmlbarsRuntime.internal.continueBlock(morph, env, scope, 'with', params, hash, template, inverse, visitor);
21589    }
21590  };
21591});
21592enifed('ember-htmlbars/keywords/yield', ['exports'], function (exports) {
21593  'use strict';
21594
21595  exports.default = yieldKeyword;
21596
21597  function yieldKeyword(morph, env, scope, params, hash, template, inverse, visitor) {
21598    var to = env.hooks.getValue(hash.to) || 'default';
21599    var block = scope.getBlock(to);
21600
21601    if (block) {
21602      block.invoke(env, params, hash.self, morph, scope, visitor);
21603    }
21604
21605    return true;
21606  }
21607});
21608enifed('ember-htmlbars/keywords', ['exports', 'htmlbars-runtime'], function (exports, _htmlbarsRuntime) {
21609  /**
21610  @module ember
21611  @submodule ember-htmlbars
21612  */
21613
21614  'use strict';
21615
21616  exports.registerKeyword = registerKeyword;
21617
21618  /**
21619   @private
21620   @property helpers
21621  */
21622  var keywords = Object.create(_htmlbarsRuntime.hooks.keywords);
21623
21624  /**
21625  @module ember
21626  @submodule ember-htmlbars
21627  */
21628
21629  /**
21630    @private
21631    @method _registerHelper
21632    @for Ember.HTMLBars
21633    @param {String} name
21634    @param {Object|Function} keyword The keyword to add.
21635  */
21636
21637  function registerKeyword(name, keyword) {
21638    keywords[name] = keyword;
21639  }
21640
21641  exports.default = keywords;
21642});
21643enifed('ember-htmlbars/morphs/attr-morph', ['exports', 'ember-metal/debug', 'dom-helper', 'ember-metal/is_none'], function (exports, _emberMetalDebug, _domHelper, _emberMetalIs_none) {
21644  'use strict';
21645
21646  var HTMLBarsAttrMorph = _domHelper.default.prototype.AttrMorphClass;
21647
21648  var styleWarning = '' + 'Binding style attributes may introduce cross-site scripting vulnerabilities; ' + 'please ensure that values being bound are properly escaped. For more information, ' + 'including how to disable this warning, see ' + 'http://emberjs.com/deprecations/v1.x/#toc_binding-style-attributes.';
21649
21650  exports.styleWarning = styleWarning;
21651  var proto = HTMLBarsAttrMorph.prototype;
21652
21653  proto.didInit = function () {
21654    this.streamUnsubscribers = null;
21655
21656    _emberMetalDebug.debugSeal(this);
21657  };
21658
21659  function deprecateEscapedStyle(morph, value) {
21660    _emberMetalDebug.warn(styleWarning, (function (name, value, escaped) {
21661      // SafeString
21662      if (_emberMetalIs_none.default(value) || value && value.toHTML) {
21663        return true;
21664      }
21665
21666      if (name !== 'style') {
21667        return true;
21668      }
21669
21670      return !escaped;
21671    })(morph.attrName, value, morph.escaped), { id: 'ember-htmlbars.style-xss-warning' });
21672  }
21673
21674  proto.willSetContent = function (value) {
21675    deprecateEscapedStyle(this, value);
21676  };
21677
21678  exports.default = HTMLBarsAttrMorph;
21679});
21680enifed('ember-htmlbars/morphs/morph', ['exports', 'dom-helper', 'ember-metal/debug'], function (exports, _domHelper, _emberMetalDebug) {
21681  'use strict';
21682
21683  var HTMLBarsMorph = _domHelper.default.prototype.MorphClass;
21684  var guid = 1;
21685
21686  function EmberMorph(DOMHelper, contextualElement) {
21687    this.HTMLBarsMorph$constructor(DOMHelper, contextualElement);
21688
21689    this.emberView = null;
21690    this.emberToDestroy = null;
21691    this.streamUnsubscribers = null;
21692    this.guid = guid++;
21693
21694    // A component can become dirty either because one of its
21695    // attributes changed, or because it was re-rendered. If any part
21696    // of the component's template changes through observation, it has
21697    // re-rendered from the perpsective of the programming model. This
21698    // flag is set to true whenever a component becomes dirty because
21699    // one of its attributes changed, which also triggers the attribute
21700    // update flag (didUpdateAttrs).
21701    this.shouldReceiveAttrs = false;
21702
21703    _emberMetalDebug.debugSeal(this);
21704  }
21705
21706  var proto = EmberMorph.prototype = Object.create(HTMLBarsMorph.prototype);
21707  proto.HTMLBarsMorph$constructor = HTMLBarsMorph;
21708  proto.HTMLBarsMorph$clear = HTMLBarsMorph.prototype.clear;
21709
21710  proto.addDestruction = function (toDestroy) {
21711    this.emberToDestroy = this.emberToDestroy || [];
21712    this.emberToDestroy.push(toDestroy);
21713  };
21714
21715  proto.cleanup = function () {
21716    var view = this.emberView;
21717
21718    if (view) {
21719      var parentView = view.parentView;
21720
21721      if (parentView && view.ownerView._destroyingSubtreeForView === parentView) {
21722        parentView.removeChild(view);
21723      }
21724    }
21725
21726    var toDestroy = this.emberToDestroy;
21727
21728    if (toDestroy) {
21729      for (var i = 0, l = toDestroy.length; i < l; i++) {
21730        toDestroy[i].destroy();
21731      }
21732
21733      this.emberToDestroy = null;
21734    }
21735  };
21736
21737  proto.didRender = function (env, scope) {
21738    env.renderedNodes.add(this);
21739  };
21740
21741  exports.default = EmberMorph;
21742});
21743enifed('ember-htmlbars/node-managers/component-node-manager', ['exports', 'ember-metal/debug', 'ember-views/system/build-component-template', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/system/instrumentation-support', 'ember-views/components/component', 'ember-htmlbars/glimmer-component', 'ember-htmlbars/utils/extract-positional-params', 'ember-metal/symbol', 'container/owner', 'ember-htmlbars/hooks/get-value'], function (exports, _emberMetalDebug, _emberViewsSystemBuildComponentTemplate, _emberHtmlbarsHooksGetCellOrValue, _emberMetalProperty_get, _emberMetalProperty_set, _emberViewsCompatAttrsProxy, _emberHtmlbarsSystemInstrumentationSupport, _emberViewsComponentsComponent, _emberHtmlbarsGlimmerComponent, _emberHtmlbarsUtilsExtractPositionalParams, _emberMetalSymbol, _containerOwner, _emberHtmlbarsHooksGetValue) {
21744  'use strict';
21745
21746  exports.createComponent = createComponent;
21747  exports.takeLegacySnapshot = takeLegacySnapshot;
21748
21749  // These symbols will be used to limit link-to's public API surface area.
21750  var HAS_BLOCK = _emberMetalSymbol.default('HAS_BLOCK');
21751
21752  exports.HAS_BLOCK = HAS_BLOCK;
21753  // In theory this should come through the env, but it should
21754  // be safe to import this until we make the hook system public
21755  // and it gets actively used in addons or other downstream
21756  // libraries.
21757
21758  function ComponentNodeManager(component, isAngleBracket, scope, renderNode, attrs, block, expectElement) {
21759    this.component = component;
21760    this.isAngleBracket = isAngleBracket;
21761    this.scope = scope;
21762    this.renderNode = renderNode;
21763    this.attrs = attrs;
21764    this.block = block;
21765    this.expectElement = expectElement;
21766  }
21767
21768  exports.default = ComponentNodeManager;
21769
21770  ComponentNodeManager.create = function ComponentNodeManager_create(renderNode, env, options) {
21771    var _createOptions;
21772
21773    var tagName = options.tagName;
21774    var params = options.params;
21775    var _options$attrs = options.attrs;
21776    var attrs = _options$attrs === undefined ? {} : _options$attrs;
21777    var parentView = options.parentView;
21778    var parentScope = options.parentScope;
21779    var isAngleBracket = options.isAngleBracket;
21780    var component = options.component;
21781    var layout = options.layout;
21782    var templates = options.templates;
21783
21784    component = component || (isAngleBracket ? _emberHtmlbarsGlimmerComponent.default : _emberViewsComponentsComponent.default);
21785
21786    var createOptions = (_createOptions = {
21787      parentView: parentView
21788    }, _createOptions[HAS_BLOCK] = !!templates.default, _createOptions);
21789
21790    configureTagName(attrs, tagName, component, isAngleBracket, createOptions);
21791
21792    // Map passed attributes (e.g. <my-component id="foo">) to component
21793    // properties ({ id: "foo" }).
21794    configureCreateOptions(attrs, createOptions);
21795
21796    // If there is a controller on the scope, pluck it off and save it on the
21797    // component. This allows the component to target actions sent via
21798    // `sendAction` correctly.
21799    if (parentScope.hasLocal('controller')) {
21800      createOptions._controller = _emberHtmlbarsHooksGetValue.default(parentScope.getLocal('controller'));
21801    } else {
21802      createOptions._targetObject = _emberHtmlbarsHooksGetValue.default(parentScope.getSelf());
21803    }
21804
21805    _emberHtmlbarsUtilsExtractPositionalParams.default(renderNode, component, params, attrs);
21806
21807    // Instantiate the component
21808    component = createComponent(component, isAngleBracket, createOptions, renderNode, env, attrs);
21809
21810    // If the component specifies its layout via the `layout` property
21811    // instead of using the template looked up in the container, get it
21812    // now that we have the component instance.
21813    if (!layout) {
21814      layout = _emberMetalProperty_get.get(component, 'layout');
21815    }
21816
21817    _emberMetalDebug.runInDebug(function () {
21818      if (isAngleBracket) {
21819        _emberMetalDebug.assert('You cannot invoke the \'' + tagName + '\' component with angle brackets, because it\'s a subclass of Component. Please upgrade to GlimmerComponent. Alternatively, you can invoke as \'{{' + tagName + '}}\'.', component.isGlimmerComponent);
21820      } else {
21821        _emberMetalDebug.assert('You cannot invoke the \'' + tagName + '\' component with curly braces, because it\'s a subclass of GlimmerComponent. Please invoke it as \'<' + tagName + '>\' instead.', !component.isGlimmerComponent);
21822      }
21823
21824      if (!layout) {
21825        return;
21826      }
21827
21828      var fragmentReason = layout.meta.fragmentReason;
21829      if (isAngleBracket && fragmentReason) {
21830        switch (fragmentReason.name) {
21831          case 'missing-wrapper':
21832            _emberMetalDebug.assert('The <' + tagName + '> template must have a single top-level element because it is a GlimmerComponent.');
21833            break;
21834          case 'modifiers':
21835            var modifiers = fragmentReason.modifiers.map(function (m) {
21836              return '{{' + m + ' ...}}';
21837            });
21838            _emberMetalDebug.assert('You cannot use ' + modifiers.join(', ') + ' in the top-level element of the <' + tagName + '> template because it is a GlimmerComponent.');
21839            break;
21840          case 'triple-curlies':
21841            _emberMetalDebug.assert('You cannot use triple curlies (e.g. style={{{ ... }}}) in the top-level element of the <' + tagName + '> template because it is a GlimmerComponent.');
21842            break;
21843        }
21844      }
21845    });
21846
21847    var results = _emberViewsSystemBuildComponentTemplate.default({ layout: layout, component: component, isAngleBracket: isAngleBracket }, attrs, { templates: templates, scope: parentScope });
21848
21849    return new ComponentNodeManager(component, isAngleBracket, parentScope, renderNode, attrs, results.block, results.createdElement);
21850  };
21851
21852  function configureTagName(attrs, tagName, component, isAngleBracket, createOptions) {
21853    if (isAngleBracket) {
21854      createOptions.tagName = tagName;
21855    } else if (attrs.tagName) {
21856      createOptions.tagName = _emberHtmlbarsHooksGetValue.default(attrs.tagName);
21857    }
21858  }
21859
21860  function configureCreateOptions(attrs, createOptions) {
21861    // Some attrs are special and need to be set as properties on the component
21862    // instance. Make sure we use getValue() to get them from `attrs` since
21863    // they are still streams.
21864    if (attrs.id) {
21865      createOptions.elementId = _emberHtmlbarsHooksGetValue.default(attrs.id);
21866    }
21867    if (attrs._defaultTagName) {
21868      createOptions._defaultTagName = _emberHtmlbarsHooksGetValue.default(attrs._defaultTagName);
21869    }
21870    if (attrs.viewName) {
21871      createOptions.viewName = _emberHtmlbarsHooksGetValue.default(attrs.viewName);
21872    }
21873  }
21874
21875  ComponentNodeManager.prototype.render = function ComponentNodeManager_render(_env, visitor) {
21876    var component = this.component;
21877
21878    return _emberHtmlbarsSystemInstrumentationSupport.instrument(component, function ComponentNodeManager_render_instrument() {
21879      var meta = this.block && this.block.template.meta;
21880      var env = _env.childWithView(component, meta);
21881
21882      env.renderer.componentWillRender(component);
21883      env.renderedViews.push(component.elementId);
21884
21885      if (this.block) {
21886        this.block.invoke(env, [], undefined, this.renderNode, this.scope, visitor);
21887      }
21888
21889      var element = undefined;
21890      if (this.expectElement || component.isGlimmerComponent) {
21891        // This code assumes that Glimmer components are never fragments. When
21892        // Glimmer components gain fragment powers, we will need to communicate
21893        // whether the layout produced a single top-level node or fragment
21894        // somehow (either via static information on the template/component, or
21895        // dynamically as the layout is being rendered).
21896        element = this.renderNode.firstNode;
21897
21898        // Glimmer components may have whitespace or boundary nodes around the
21899        // top-level element.
21900        if (element && element.nodeType !== 1) {
21901          element = nextElementSibling(element);
21902        }
21903      }
21904
21905      // In environments like FastBoot, disable any hooks that would cause the component
21906      // to access the DOM directly.
21907      if (env.destinedForDOM) {
21908        env.renderer.didCreateElement(component, element);
21909        env.renderer.willInsertElement(component, element);
21910
21911        env.lifecycleHooks.push({ type: 'didInsertElement', view: component });
21912      }
21913    }, this);
21914  };
21915
21916  function nextElementSibling(node) {
21917    var current = node;
21918
21919    while (current) {
21920      if (current.nodeType === 1) {
21921        return current;
21922      }
21923      current = node.nextSibling;
21924    }
21925  }
21926
21927  ComponentNodeManager.prototype.rerender = function ComponentNodeManager_rerender(_env, attrs, visitor) {
21928    var component = this.component;
21929
21930    return _emberHtmlbarsSystemInstrumentationSupport.instrument(component, function ComponentNodeManager_rerender_instrument() {
21931      var env = _env.childWithView(component);
21932
21933      var snapshot = takeSnapshot(attrs);
21934
21935      if (component._renderNode.shouldReceiveAttrs) {
21936        if (component._propagateAttrsToThis) {
21937          component._propagateAttrsToThis(takeLegacySnapshot(attrs));
21938        }
21939
21940        env.renderer.componentUpdateAttrs(component, snapshot);
21941        component._renderNode.shouldReceiveAttrs = false;
21942      }
21943
21944      // Notify component that it has become dirty and is about to change.
21945      env.renderer.componentWillUpdate(component, snapshot);
21946      env.renderer.componentWillRender(component);
21947
21948      env.renderedViews.push(component.elementId);
21949
21950      if (this.block) {
21951        this.block.invoke(env, [], undefined, this.renderNode, this.scope, visitor);
21952      }
21953
21954      env.lifecycleHooks.push({ type: 'didUpdate', view: component });
21955
21956      return env;
21957    }, this);
21958  };
21959
21960  ComponentNodeManager.prototype.destroy = function ComponentNodeManager_destroy() {
21961    var component = this.component;
21962
21963    // Clear component's render node. Normally this gets cleared
21964    // during view destruction, but in this case we're re-assigning the
21965    // node to a different view and it will get cleaned up automatically.
21966    component._renderNode = null;
21967    component.destroy();
21968  };
21969
21970  function createComponent(_component, isAngleBracket, props, renderNode, env) {
21971    var attrs = arguments.length <= 5 || arguments[5] === undefined ? {} : arguments[5];
21972
21973    if (!isAngleBracket) {
21974      _emberMetalDebug.assert('controller= is no longer supported', !('controller' in attrs));
21975
21976      snapshotAndUpdateTarget(attrs, props);
21977    } else {
21978      props.attrs = takeSnapshot(attrs);
21979
21980      props._isAngleBracket = true;
21981    }
21982
21983    _containerOwner.setOwner(props, env.owner);
21984    props.renderer = props.parentView ? props.parentView.renderer : env.owner.lookup('renderer:-dom');
21985    props._viewRegistry = props.parentView ? props.parentView._viewRegistry : env.owner.lookup('-view-registry:main');
21986
21987    var component = _component.create(props);
21988
21989    if (props.parentView) {
21990      props.parentView.appendChild(component);
21991
21992      if (props.viewName) {
21993        _emberMetalProperty_set.set(props.parentView, props.viewName, component);
21994      }
21995    }
21996
21997    component._renderNode = renderNode;
21998    renderNode.emberView = component;
21999    renderNode.buildChildEnv = buildChildEnv;
22000    return component;
22001  }
22002
22003  function takeSnapshot(attrs) {
22004    var hash = {};
22005
22006    for (var prop in attrs) {
22007      hash[prop] = _emberHtmlbarsHooksGetCellOrValue.default(attrs[prop]);
22008    }
22009
22010    return hash;
22011  }
22012
22013  function takeLegacySnapshot(attrs) {
22014    var hash = {};
22015
22016    for (var prop in attrs) {
22017      hash[prop] = _emberHtmlbarsHooksGetValue.default(attrs[prop]);
22018    }
22019
22020    return hash;
22021  }
22022
22023  function snapshotAndUpdateTarget(rawAttrs, target) {
22024    var attrs = {};
22025
22026    for (var prop in rawAttrs) {
22027      var value = _emberHtmlbarsHooksGetCellOrValue.default(rawAttrs[prop]);
22028      attrs[prop] = value;
22029
22030      // when `attrs` is an actual value being set in the
22031      // attrs hash (`{{foo-bar attrs="blah"}}`) we cannot
22032      // set `"blah"` to the root of the target because
22033      // that would replace all attrs with `attrs.attrs`
22034      if (prop === 'attrs') {
22035        _emberMetalDebug.warn('Invoking a component with a hash attribute named `attrs` is not supported. Please refactor usage of ' + target + ' to avoid passing `attrs` as a hash parameter.', false, { id: 'ember-htmlbars.component-unsupported-attrs' });
22036        continue;
22037      }
22038
22039      if (value && value[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) {
22040        value = value.value;
22041      }
22042
22043      target[prop] = value;
22044    }
22045
22046    return target.attrs = attrs;
22047  }
22048
22049  function buildChildEnv(state, env) {
22050    return env.childWithView(this.emberView);
22051  }
22052});
22053enifed('ember-htmlbars/node-managers/view-node-manager', ['exports', 'ember-metal/assign', 'ember-metal/debug', 'ember-views/system/build-component-template', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/set_properties', 'ember-views/views/view', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-htmlbars/system/instrumentation-support', 'ember-htmlbars/node-managers/component-node-manager', 'container/owner', 'ember-htmlbars/hooks/get-value'], function (exports, _emberMetalAssign, _emberMetalDebug, _emberViewsSystemBuildComponentTemplate, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalSet_properties, _emberViewsViewsView, _emberViewsCompatAttrsProxy, _emberHtmlbarsHooksGetCellOrValue, _emberHtmlbarsSystemInstrumentationSupport, _emberHtmlbarsNodeManagersComponentNodeManager, _containerOwner, _emberHtmlbarsHooksGetValue) {
22054  'use strict';
22055
22056  exports.createOrUpdateComponent = createOrUpdateComponent;
22057
22058  function ViewNodeManager(component, scope, renderNode, block, expectElement) {
22059    this.component = component;
22060    this.scope = scope;
22061    this.renderNode = renderNode;
22062    this.block = block;
22063    this.expectElement = expectElement;
22064  }
22065
22066  exports.default = ViewNodeManager;
22067
22068  ViewNodeManager.create = function ViewNodeManager_create(renderNode, env, attrs, found, parentView, path, contentScope, contentTemplate) {
22069    _emberMetalDebug.assert('HTMLBars error: Could not find component named "' + path + '" (no component or template with that name was found)', !!(function () {
22070      if (path) {
22071        return found.component || found.layout;
22072      } else {
22073        return found.component || found.layout || contentTemplate;
22074      }
22075    })());
22076
22077    var component;
22078    var componentInfo = { layout: found.layout };
22079
22080    if (found.component) {
22081      var options = { parentView: parentView };
22082
22083      if (attrs && attrs.id) {
22084        options.elementId = _emberHtmlbarsHooksGetValue.default(attrs.id);
22085      }
22086      if (attrs && attrs.tagName) {
22087        options.tagName = _emberHtmlbarsHooksGetValue.default(attrs.tagName);
22088      }
22089      if (attrs && attrs._defaultTagName) {
22090        options._defaultTagName = _emberHtmlbarsHooksGetValue.default(attrs._defaultTagName);
22091      }
22092      if (attrs && attrs.viewName) {
22093        options.viewName = _emberHtmlbarsHooksGetValue.default(attrs.viewName);
22094      }
22095
22096      if (found.component.create && contentScope) {
22097        var _self = contentScope.getSelf();
22098        if (_self) {
22099          options._context = _emberHtmlbarsHooksGetValue.default(contentScope.getSelf());
22100        }
22101      }
22102
22103      if (found.self) {
22104        options._context = _emberHtmlbarsHooksGetValue.default(found.self);
22105      }
22106
22107      component = componentInfo.component = createOrUpdateComponent(found.component, options, found.createOptions, renderNode, env, attrs);
22108
22109      var layout = _emberMetalProperty_get.get(component, 'layout');
22110      if (layout) {
22111        componentInfo.layout = layout;
22112      } else {
22113        componentInfo.layout = getTemplate(component) || componentInfo.layout;
22114      }
22115
22116      renderNode.emberView = component;
22117    }
22118
22119    _emberMetalDebug.assert('BUG: ViewNodeManager.create can take a scope or a self, but not both', !(contentScope && found.self));
22120
22121    var results = _emberViewsSystemBuildComponentTemplate.default(componentInfo, attrs, {
22122      templates: { default: contentTemplate },
22123      scope: contentScope,
22124      self: found.self
22125    });
22126
22127    return new ViewNodeManager(component, contentScope, renderNode, results.block, results.createdElement);
22128  };
22129
22130  ViewNodeManager.prototype.render = function ViewNodeManager_render(env, attrs, visitor) {
22131    var component = this.component;
22132
22133    return _emberHtmlbarsSystemInstrumentationSupport.instrument(component, function ViewNodeManager_render_instrument() {
22134      var newEnv = env;
22135      if (component) {
22136        newEnv = env.childWithView(component);
22137      } else {
22138        var meta = this.block && this.block.template.meta;
22139
22140        newEnv = env.childWithMeta(meta);
22141      }
22142
22143      if (component) {
22144        env.renderer.willRender(component);
22145        env.renderedViews.push(component.elementId);
22146      }
22147
22148      if (this.block) {
22149        this.block.invoke(newEnv, [], undefined, this.renderNode, this.scope, visitor);
22150      }
22151
22152      if (component) {
22153        var element = this.expectElement && this.renderNode.firstNode;
22154
22155        // In environments like FastBoot, disable any hooks that would cause the component
22156        // to access the DOM directly.
22157        if (env.destinedForDOM) {
22158          env.renderer.didCreateElement(component, element);
22159          env.renderer.willInsertElement(component, element);
22160          env.lifecycleHooks.push({ type: 'didInsertElement', view: component });
22161        }
22162      }
22163    }, this);
22164  };
22165
22166  ViewNodeManager.prototype.rerender = function ViewNodeManager_rerender(env, attrs, visitor) {
22167    var component = this.component;
22168
22169    return _emberHtmlbarsSystemInstrumentationSupport.instrument(component, function ViewNodeManager_rerender_instrument() {
22170      var newEnv = env;
22171      if (component) {
22172        newEnv = env.childWithView(component);
22173
22174        var snapshot = takeSnapshot(attrs);
22175
22176        // Notify component that it has become dirty and is about to change.
22177        env.renderer.willUpdate(component, snapshot);
22178
22179        if (component._renderNode.shouldReceiveAttrs) {
22180          if (component._propagateAttrsToThis) {
22181            component._propagateAttrsToThis(_emberHtmlbarsNodeManagersComponentNodeManager.takeLegacySnapshot(attrs));
22182          }
22183
22184          env.renderer.componentUpdateAttrs(component, snapshot);
22185          component._renderNode.shouldReceiveAttrs = false;
22186        }
22187
22188        env.renderer.willRender(component);
22189
22190        env.renderedViews.push(component.elementId);
22191      } else {
22192        var meta = this.block && this.block.template.meta;
22193
22194        newEnv = env.childWithMeta(meta);
22195      }
22196
22197      if (this.block) {
22198        this.block.invoke(newEnv, [], undefined, this.renderNode, this.scope, visitor);
22199      }
22200
22201      return newEnv;
22202    }, this);
22203  };
22204
22205  ViewNodeManager.prototype.destroy = function ViewNodeManager_destroy() {
22206    if (this.component) {
22207      this.component.destroy();
22208      this.component = null;
22209    }
22210  };
22211
22212  function getTemplate(componentOrView) {
22213    if (!componentOrView.isComponent) {
22214      return _emberMetalProperty_get.get(componentOrView, 'template');
22215    }
22216
22217    return null;
22218  }
22219
22220  function createOrUpdateComponent(component, options, createOptions, renderNode, env) {
22221    var attrs = arguments.length <= 5 || arguments[5] === undefined ? {} : arguments[5];
22222
22223    var snapshot = takeSnapshot(attrs);
22224    var props = _emberMetalAssign.default({}, options);
22225    var defaultController = _emberViewsViewsView.default.proto().controller;
22226    var hasSuppliedController = 'controller' in attrs || 'controller' in props;
22227
22228    if (!props.ownerView && options.parentView) {
22229      props.ownerView = options.parentView.ownerView;
22230    }
22231
22232    props.attrs = snapshot;
22233    if (component.create) {
22234      var proto = component.proto();
22235
22236      if (createOptions) {
22237        _emberMetalAssign.default(props, createOptions);
22238      }
22239
22240      mergeBindings(props, snapshot);
22241
22242      var owner = env.owner;
22243
22244      _containerOwner.setOwner(props, owner);
22245      props.renderer = options.parentView ? options.parentView.renderer : owner && owner.lookup('renderer:-dom');
22246      props._viewRegistry = options.parentView ? options.parentView._viewRegistry : owner && owner.lookup('-view-registry:main');
22247
22248      if (proto.controller !== defaultController || hasSuppliedController) {
22249        delete props._context;
22250      }
22251
22252      component = component.create(props);
22253    } else {
22254      env.renderer.componentUpdateAttrs(component, snapshot);
22255      _emberMetalSet_properties.default(component, props);
22256
22257      if (component._propagateAttrsToThis) {
22258        component._propagateAttrsToThis(_emberHtmlbarsNodeManagersComponentNodeManager.takeLegacySnapshot(attrs));
22259      }
22260    }
22261
22262    if (options.parentView) {
22263      options.parentView.appendChild(component);
22264
22265      if (options.viewName) {
22266        _emberMetalProperty_set.set(options.parentView, options.viewName, component);
22267      }
22268    }
22269
22270    component._renderNode = renderNode;
22271
22272    renderNode.emberView = component;
22273    return component;
22274  }
22275
22276  function takeSnapshot(attrs) {
22277    var hash = {};
22278
22279    for (var prop in attrs) {
22280      hash[prop] = _emberHtmlbarsHooksGetCellOrValue.default(attrs[prop]);
22281    }
22282
22283    return hash;
22284  }
22285
22286  function mergeBindings(target, attrs) {
22287    for (var prop in attrs) {
22288      if (!attrs.hasOwnProperty(prop)) {
22289        continue;
22290      }
22291      // when `attrs` is an actual value being set in the
22292      // attrs hash (`{{foo-bar attrs="blah"}}`) we cannot
22293      // set `"blah"` to the root of the target because
22294      // that would replace all attrs with `attrs.attrs`
22295      if (prop === 'attrs') {
22296        _emberMetalDebug.warn('Invoking a component with a hash attribute named `attrs` is not supported. Please refactor usage of ' + target + ' to avoid passing `attrs` as a hash parameter.', false, { id: 'ember-htmlbars.view-unsupported-attrs' });
22297        continue;
22298      }
22299      var value = attrs[prop];
22300
22301      if (value && value[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) {
22302        target[prop] = value.value;
22303      } else {
22304        target[prop] = value;
22305      }
22306    }
22307
22308    return target;
22309  }
22310});
22311
22312// In theory this should come through the env, but it should
22313// be safe to import this until we make the hook system public
22314// and it gets actively used in addons or other downstream
22315// libraries.
22316enifed('ember-htmlbars/streams/built-in-helper', ['exports', 'ember-metal/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberMetalStreamsStream, _emberHtmlbarsStreamsUtils) {
22317  'use strict';
22318
22319  var BuiltInHelperStream = _emberMetalStreamsStream.default.extend({
22320    init: function (helper, params, hash, templates, env, scope, label) {
22321      this.helper = helper;
22322      this.params = params;
22323      this.templates = templates;
22324      this.env = env;
22325      this.scope = scope;
22326      this.hash = hash;
22327      this.label = label;
22328    },
22329
22330    compute: function () {
22331      return this.helper(_emberHtmlbarsStreamsUtils.getArrayValues(this.params), _emberHtmlbarsStreamsUtils.getHashValues(this.hash), this.templates, this.env, this.scope);
22332    }
22333  });
22334
22335  exports.default = BuiltInHelperStream;
22336});
22337enifed('ember-htmlbars/streams/helper-factory', ['exports', 'ember-metal/stream
22337s/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberMetalStreamsStream, _emberHtmlbarsStreamsUtils) {
22338  'use strict';
22339
22340  var HelperFactoryStream = _emberMetalStreamsStream.default.extend({
22341    init: function (helperFactory, params, hash, label) {
22342      this.helperFactory = helperFactory;
22343      this.params = params;
22344      this.hash = hash;
22345      this.linkable = true;
22346      this.helper = null;
22347      this.label = label;
22348    },
22349
22350    compute: function () {
22351      if (!this.helper) {
22352        this.helper = this.helperFactory.create({ _stream: this });
22353      }
22354      return this.helper.compute(_emberHtmlbarsStreamsUtils.getArrayValues(this.params), _emberHtmlbarsStreamsUtils.getHashValues(this.hash));
22355    },
22356
22357    deactivate: function () {
22358      this.super$deactivate();
22359      if (this.helper) {
22360        this.helper.destroy();
22361        this.helper = null;
22362      }
22363    },
22364    super$deactivate: _emberMetalStreamsStream.default.prototype.deactivate
22365  });
22366
22367  exports.default = HelperFactoryStream;
22368});
22369enifed('ember-htmlbars/streams/helper-instance', ['exports', 'ember-metal/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberMetalStreamsStream, _emberHtmlbarsStreamsUtils) {
22370  'use strict';
22371
22372  var HelperInstanceStream = _emberMetalStreamsStream.default.extend({
22373    init: function (helper, params, hash, label) {
22374      this.helper = helper;
22375      this.params = params;
22376      this.hash = hash;
22377      this.linkable = true;
22378      this.label = label;
22379    },
22380
22381    compute: function () {
22382      return this.helper.compute(_emberHtmlbarsStreamsUtils.getArrayValues(this.params), _emberHtmlbarsStreamsUtils.getHashValues(this.hash));
22383    }
22384  });
22385
22386  exports.default = HelperInstanceStream;
22387});
22388enifed('ember-htmlbars/streams/utils', ['exports', 'ember-htmlbars/hooks/get-value'], function (exports, _emberHtmlbarsHooksGetValue) {
22389  'use strict';
22390
22391  exports.getArrayValues = getArrayValues;
22392  exports.getHashValues = getHashValues;
22393
22394  // We don't want to leak mutable cells into helpers, which
22395  // are pure functions that can only work with values.
22396
22397  function getArrayValues(params) {
22398    var l = params.length;
22399    var out = new Array(l);
22400
22401    for (var i = 0; i < l; i++) {
22402      out[i] = _emberHtmlbarsHooksGetValue.default(params[i]);
22403    }
22404
22405    return out;
22406  }
22407
22408  function getHashValues(hash) {
22409    var out = {};
22410
22411    for (var prop in hash) {
22412      out[prop] = _emberHtmlbarsHooksGetValue.default(hash[prop]);
22413    }
22414
22415    return out;
22416  }
22417});
22418enifed('ember-htmlbars/system/append-templated-view', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-views/views/view'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberViewsViewsView) {
22419  /**
22420  @module ember
22421  @submodule ember-htmlbars
22422  */
22423
22424  'use strict';
22425
22426  exports.default = appendTemplatedView;
22427
22428  function appendTemplatedView(parentView, morph, viewClassOrInstance, props) {
22429    var viewProto;
22430    if (_emberViewsViewsView.default.detectInstance(viewClassOrInstance)) {
22431      viewProto = viewClassOrInstance;
22432    } else {
22433      viewProto = viewClassOrInstance.proto();
22434    }
22435
22436    _emberMetalDebug.assert('You cannot provide a template block if you also specified a templateName', !props.template || !_emberMetalProperty_get.get(props, 'templateName') && !_emberMetalProperty_get.get(viewProto, 'templateName'));
22437
22438    // We only want to override the `_context` computed property if there is
22439    // no specified controller. See View#_context for more information.
22440    var noControllerInProto = !viewProto.controller;
22441    if (viewProto.controller && viewProto.controller.isDescriptor) {
22442      noControllerInProto = true;
22443    }
22444    if (noControllerInProto && !viewProto.controllerBinding && !props.controller && !props.controllerBinding) {
22445      props._context = _emberMetalProperty_get.get(parentView, 'context'); // TODO: is this right?!
22446    }
22447
22448    props._morph = morph;
22449
22450    return parentView.appendChild(viewClassOrInstance, props);
22451  }
22452});
22453enifed('ember-htmlbars/system/bootstrap', ['exports', 'ember-views/component_lookup', 'ember-views/system/jquery', 'ember-metal/error', 'ember-runtime/system/lazy_load', 'ember-template-compiler/system/compile', 'ember-metal/environment', 'ember-htmlbars/template_registry'], function (exports, _emberViewsComponent_lookup, _emberViewsSystemJquery, _emberMetalError, _emberRuntimeSystemLazy_load, _emberTemplateCompilerSystemCompile, _emberMetalEnvironment, _emberHtmlbarsTemplate_registry) {
22454  /*globals Handlebars */
22455
22456  /**
22457  @module ember
22458  @submodule ember-htmlbars
22459  */
22460
22461  'use strict';
22462
22463  /**
22464  @module ember
22465  @submodule ember-htmlbars
22466  */
22467
22468  /**
22469    Find templates stored in the head tag as script tags and make them available
22470    to `Ember.CoreView` in the global `Ember.TEMPLATES` object. This will be run
22471    as a jQuery DOM-ready callback.
22472  
22473    Script tags with `text/x-handlebars` will be compiled
22474    with Ember's template compiler and are suitable for use as a view's template.
22475    Those with type `text/x-raw-handlebars` will be compiled with regular
22476    Handlebars and are suitable for use in views' computed properties.
22477  
22478    @private
22479    @method bootstrap
22480    @for Ember.HTMLBars
22481    @static
22482    @param ctx
22483  */
22484  function bootstrap(ctx) {
22485    var selectors = 'script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]';
22486
22487    _emberViewsSystemJquery.default(selectors, ctx).each(function () {
22488      // Get a reference to the script tag.
22489      var script = _emberViewsSystemJquery.default(this);
22490
22491      // Get the name of the script, used by Ember.View's templateName property.
22492      // First look for data-template-name attribute, then fall back to its
22493      // id if no name is found.
22494      var templateName = script.attr('data-template-name') || script.attr('id') || 'application';
22495      var template, compile;
22496
22497      if (script.attr('type') === 'text/x-raw-handlebars') {
22498        compile = _emberViewsSystemJquery.default.proxy(Handlebars.compile, Handlebars);
22499        template = compile(script.html());
22500      } else {
22501        template = _emberTemplateCompilerSystemCompile.default(script.html(), {
22502          moduleName: templateName
22503        });
22504      }
22505
22506      // Check if template of same name already exists.
22507      if (_emberHtmlbarsTemplate_registry.has(templateName)) {
22508        throw new _emberMetalError.default('Template named "' + templateName + '" already exists.');
22509      }
22510
22511      // For templates which have a name, we save them and then remove them from the DOM.
22512      _emberHtmlbarsTemplate_registry.set(templateName, template);
22513
22514      // Remove script tag from DOM.
22515      script.remove();
22516    });
22517  }
22518
22519  function _bootstrap() {
22520    bootstrap(_emberViewsSystemJquery.default(document));
22521  }
22522
22523  function registerComponentLookup(app) {
22524    app.register('component-lookup:main', _emberViewsComponent_lookup.default);
22525  }
22526
22527  /*
22528    We tie this to application.load to ensure that we've at least
22529    attempted to bootstrap at the point that the application is loaded.
22530  
22531    We also tie this to document ready since we're guaranteed that all
22532    the inline templates are present at this point.
22533  
22534    There's no harm to running this twice, since we remove the templates
22535    from the DOM after processing.
22536  */
22537
22538  _emberRuntimeSystemLazy_load.onLoad('Ember.Application', function (Application) {
22539    Application.initializer({
22540      name: 'domTemplates',
22541      initialize: _emberMetalEnvironment.default.hasDOM ? _bootstrap : function () {}
22542    });
22543
22544    Application.instanceInitializer({
22545      name: 'registerComponentLookup',
22546      initialize: registerComponentLookup
22547    });
22548  });
22549
22550  exports.default = bootstrap;
22551});
22552enifed('ember-htmlbars/system/dom-helper', ['exports', 'dom-helper', 'ember-htmlbars/morphs/morph', 'ember-htmlbars/morphs/attr-morph'], function (exports, _domHelper, _emberHtmlbarsMorphsMorph, _emberHtmlbarsMorphsAttrMorph) {
22553  'use strict';
22554
22555  function EmberDOMHelper(_document) {
22556    _domHelper.default.call(this, _document);
22557  }
22558
22559  var proto = EmberDOMHelper.prototype = Object.create(_domHelper.default.prototype);
22560  proto.MorphClass = _emberHtmlbarsMorphsMorph.default;
22561  proto.AttrMorphClass = _emberHtmlbarsMorphsAttrMorph.default;
22562
22563  exports.default = EmberDOMHelper;
22564});
22565enifed('ember-htmlbars/system/instrumentation-support', ['exports', 'ember-metal/instrumentation'], function (exports, _emberMetalInstrumentation) {
22566  'use strict';
22567
22568  exports.instrument = instrument;
22569
22570  /**
22571    Provides instrumentation for node managers.
22572  
22573    Wrap your node manager's render and re-render methods
22574    with this function.
22575  
22576    @param {Object} component Component or View instance (optional).
22577    @param {Function} callback The function to instrument.
22578    @param {Object} context The context to call the function with.
22579    @return {Object} Return value from the invoked callback.
22580    @private
22581  */
22582
22583  function instrument(component, callback, context) {
22584    var instrumentName, val, details, end;
22585    // Only instrument if there's at least one subscriber.
22586    if (_emberMetalInstrumentation.subscribers.length) {
22587      if (component) {
22588        instrumentName = component.instrumentName;
22589      } else {
22590        instrumentName = 'node';
22591      }
22592      details = {};
22593      if (component) {
22594        component.instrumentDetails(details);
22595      }
22596      end = _emberMetalInstrumentation._instrumentStart('render.' + instrumentName, function viewInstrumentDetails() {
22597        return details;
22598      });
22599      val = callback.call(context);
22600      if (end) {
22601        end();
22602      }
22603      return val;
22604    } else {
22605      return callback.call(context);
22606    }
22607  }
22608});
22609enifed('ember-htmlbars/system/invoke-helper', ['exports', 'ember-metal/debug', 'ember-htmlbars/streams/helper-instance', 'ember-htmlbars/streams/helper-factory', 'ember-htmlbars/streams/built-in-helper'], function (exports, _emberMetalDebug, _emberHtmlbarsStreamsHelperInstance, _emberHtmlbarsStreamsHelperFactory, _emberHtmlbarsStreamsBuiltInHelper) {
22610  'use strict';
22611
22612  exports.buildHelperStream = buildHelperStream;
22613
22614  function buildHelperStream(helper, params, hash, templates, env, scope, label) {
22615    var isAnyKindOfHelper = helper.isHelperInstance || helper.isHelperFactory;
22616    _emberMetalDebug.assert('Helpers may not be used in the block form, for example {{#my-helper}}{{/my-helper}}. Please use a component, or alternatively use the helper in combination with a built-in Ember helper, for example {{#if (my-helper)}}{{/if}}.', !(isAnyKindOfHelper && templates && templates.template && templates.template.meta));
22617    _emberMetalDebug.assert('Helpers may not be used in the element form, for example <div {{my-helper}}>.', !(isAnyKindOfHelper && templates && templates.element));
22618    if (helper.isHelperFactory) {
22619      return new _emberHtmlbarsStreamsHelperFactory.default(helper, params, hash, label);
22620    } else if (helper.isHelperInstance) {
22621      return new _emberHtmlbarsStreamsHelperInstance.default(helper, params, hash, label);
22622    } else {
22623      templates = templates || { template: {}, inverse: {} };
22624      return new _emberHtmlbarsStreamsBuiltInHelper.default(helper, params, hash, templates, env, scope, label);
22625    }
22626  }
22627});
22628enifed('ember-htmlbars/system/lookup-helper', ['exports', 'ember-metal/debug', 'ember-metal/cache'], function (exports, _emberMetalDebug, _emberMetalCache) {
22629  /**
22630  @module ember
22631  @submodule ember-htmlbars
22632  */
22633
22634  'use strict';
22635
22636  exports.validateLazyHelperName = validateLazyHelperName;
22637  exports.findHelper = findHelper;
22638  exports.default = lookupHelper;
22639  var CONTAINS_DASH_CACHE = new _emberMetalCache.default(1000, function (key) {
22640    return key.indexOf('-') !== -1;
22641  });
22642
22643  exports.CONTAINS_DASH_CACHE = CONTAINS_DASH_CACHE;
22644  var CONTAINS_DOT_CACHE = new _emberMetalCache.default(1000, function (key) {
22645    return key.indexOf('.') !== -1;
22646  });
22647
22648  exports.CONTAINS_DOT_CACHE = CONTAINS_DOT_CACHE;
22649
22650  function validateLazyHelperName(helperName, container, keywords) {
22651    return container && !(helperName in keywords);
22652  }
22653
22654  /**
22655    Used to lookup/resolve handlebars helpers. The lookup order is:
22656  
22657    * Look for a registered helper
22658    * If a dash exists in the name:
22659      * Look for a helper registed in the container.
22660      * Use Ember.ComponentLookup to find an Ember.Component that resolves
22661        to the given name.
22662  
22663    @private
22664    @method resolveHelper
22665    @param {String} name The name of the helper to lookup.
22666    @return {Helper}
22667  */
22668  function _findHelper(name, view, env, options) {
22669    var helper = env.helpers[name];
22670
22671    if (!helper) {
22672      var owner = env.owner;
22673      if (validateLazyHelperName(name, owner, env.hooks.keywords)) {
22674        var helperName = 'helper:' + name;
22675        // See https://github.com/emberjs/ember.js/issues/13071
22676        // See https://bugs.chromium.org/p/v8/issues/detail?id=4839
22677        var registered = owner.hasRegistration(helperName, options);
22678        if (registered) {
22679          helper = owner._lookupFactory(helperName, options);
22680          _emberMetalDebug.assert('Expected to find an Ember.Helper with the name ' + helperName + ', but found an object of type ' + typeof helper + ' instead.', helper.isHelperFactory || helper.isHelperInstance);
22681        }
22682      }
22683    }
22684
22685    return helper;
22686  }
22687
22688  function findHelper(name, view, env) {
22689    var options = {};
22690    var moduleName = env.meta && env.meta.moduleName;
22691    if (moduleName) {
22692      options.source = 'template:' + moduleName;
22693    }
22694
22695    var localHelper = _findHelper(name, view, env, options);
22696
22697    // Local match found, use it.
22698    if (localHelper) {
22699      return localHelper;
22700    }
22701
22702    // Fall back to global.
22703    return _findHelper(name, view, env);
22704  }
22705
22706  function lookupHelper(name, view, env) {
22707    var helper = findHelper(name, view, env);
22708
22709    _emberMetalDebug.assert('A helper named \'' + name + '\' could not be found', !!
22709helper);
22710
22711    return helper;
22712  }
22713});
22714enifed('ember-htmlbars/system/make_bound_helper', ['exports', 'ember-metal/debug', 'ember-htmlbars/helper'], function (exports, _emberMetalDebug, _emberHtmlbarsHelper) {
22715  /**
22716  @module ember
22717  @submodule ember-htmlbars
22718  */
22719  'use strict';
22720
22721  exports.default = makeBoundHelper;
22722
22723  /**
22724    Create a bound helper. Accepts a function that receives the ordered and hash parameters
22725    from the template. If a bound property was provided in the template, it will be resolved to its
22726    value and any changes to the bound property cause the helper function to be re-run with the updated
22727    values.
22728  
22729    * `params` - An array of resolved ordered parameters.
22730    * `hash` - An object containing the hash parameters.
22731  
22732    For example:
22733  
22734    * With an unquoted ordered parameter:
22735  
22736      ```javascript
22737      {{x-capitalize foo}}
22738      ```
22739  
22740      Assuming `foo` was set to `"bar"`, the bound helper would receive `["bar"]` as its first argument, and
22741      an empty hash as its second.
22742  
22743    * With a quoted ordered parameter:
22744  
22745      ```javascript
22746      {{x-capitalize "foo"}}
22747      ```
22748  
22749      The bound helper would receive `["foo"]` as its first argument, and an empty hash as its second.
22750  
22751    * With an unquoted hash parameter:
22752  
22753      ```javascript
22754      {{x-repeat "foo" count=repeatCount}}
22755      ```
22756  
22757      Assuming that `repeatCount` resolved to 2, the bound helper would receive `["foo"]` as its first argument,
22758      and { count: 2 } as its second.
22759  
22760    @private
22761    @method makeBoundHelper
22762    @for Ember.HTMLBars
22763    @param {Function} fn
22764    @since 1.10.0
22765  */
22766
22767  function makeBoundHelper(fn) {
22768    _emberMetalDebug.deprecate('Using `Ember.HTMLBars.makeBoundHelper` is deprecated. Please refactor to use `Ember.Helper` or `Ember.Helper.helper`.', false, { id: 'ember-htmlbars.make-bound-helper', until: '3.0.0' });
22769    return _emberHtmlbarsHelper.helper(fn);
22770  }
22771});
22772enifed('ember-htmlbars/system/render-env', ['exports', 'ember-htmlbars/env', 'ember-metal-views', 'container/owner'], function (exports, _emberHtmlbarsEnv, _emberMetalViews, _containerOwner) {
22773  'use strict';
22774
22775  exports.default = RenderEnv;
22776
22777  function RenderEnv(options) {
22778    this.lifecycleHooks = options.lifecycleHooks || [];
22779    this.renderedViews = options.renderedViews || [];
22780    this.renderedNodes = options.renderedNodes || new _emberMetalViews.MorphSet();
22781    this.hasParentOutlet = options.hasParentOutlet || false;
22782
22783    this.view = options.view;
22784    this.outletState = options.outletState;
22785    this.owner = options.owner;
22786    this.renderer = options.renderer;
22787    this.dom = options.dom;
22788    this.meta = options.meta;
22789
22790    this.hooks = _emberHtmlbarsEnv.default.hooks;
22791    this.helpers = _emberHtmlbarsEnv.default.helpers;
22792    this.useFragmentCache = _emberHtmlbarsEnv.default.useFragmentCache;
22793    this.destinedForDOM = this.renderer._destinedForDOM;
22794  }
22795
22796  RenderEnv.build = function (view, meta) {
22797    return new RenderEnv({
22798      view: view,
22799      outletState: view.outletState,
22800      owner: _containerOwner.getOwner(view),
22801      renderer: view.renderer,
22802      dom: view.renderer._dom,
22803      meta: meta
22804    });
22805  };
22806
22807  RenderEnv.prototype.childWithMeta = function (meta) {
22808    return new RenderEnv({
22809      view: this.view,
22810      outletState: this.outletState,
22811      owner: this.owner,
22812      renderer: this.renderer,
22813      dom: this.dom,
22814      lifecycleHooks: this.lifecycleHooks,
22815      renderedViews: this.renderedViews,
22816      renderedNodes: this.renderedNodes,
22817      hasParentOutlet: this.hasParentOutlet,
22818      meta: meta
22819    });
22820  };
22821
22822  RenderEnv.prototype.childWithView = function (view) {
22823    var meta = arguments.length <= 1 || arguments[1] === undefined ? this.meta : arguments[1];
22824
22825    return new RenderEnv({
22826      view: view,
22827      outletState: this.outletState,
22828      owner: this.owner,
22829      renderer: this.renderer,
22830      dom: this.dom,
22831      lifecycleHooks: this.lifecycleHooks,
22832      renderedViews: this.renderedViews,
22833      renderedNodes: this.renderedNodes,
22834      hasParentOutlet: this.hasParentOutlet,
22835      meta: meta
22836    });
22837  };
22838
22839  RenderEnv.prototype.childWithOutletState = function (outletState) {
22840    var hasParentOutlet = arguments.length <= 1 || arguments[1] === undefined ? this.hasParentOutlet : arguments[1];
22841    var meta = arguments.length <= 2 || arguments[2] === undefined ? this.meta : arguments[2];
22842
22843    return new RenderEnv({
22844      view: this.view,
22845      outletState: outletState,
22846      owner: this.owner,
22847      renderer: this.renderer,
22848      dom: this.dom,
22849      lifecycleHooks: this.lifecycleHooks,
22850      renderedViews: this.renderedViews,
22851      renderedNodes: this.renderedNodes,
22852      hasParentOutlet: hasParentOutlet,
22853      meta: meta
22854    });
22855  };
22856});
22857enifed('ember-htmlbars/system/render-view', ['exports', 'ember-htmlbars/node-managers/view-node-manager', 'ember-htmlbars/system/render-env'], function (exports, _emberHtmlbarsNodeManagersViewNodeManager, _emberHtmlbarsSystemRenderEnv) {
22858  'use strict';
22859
22860  exports.renderHTMLBarsBlock = renderHTMLBarsBlock;
22861
22862  // This function only gets called once per render of a "root view" (`appendTo`). Otherwise,
22863  // HTMLBars propagates the existing env and renders templates for a given render node.
22864
22865  function renderHTMLBarsBlock(view, block, renderNode) {
22866    var meta = block && block.template && block.template.meta;
22867    var env = _emberHtmlbarsSystemRenderEnv.default.build(view, meta);
22868
22869    view.env = env;
22870    _emberHtmlbarsNodeManagersViewNodeManager.createOrUpdateComponent(view, {}, null, renderNode, env);
22871    var nodeManager = new _emberHtmlbarsNodeManagersViewNodeManager.default(view, null, renderNode, block, view.tagName !== '');
22872
22873    nodeManager.render(env, {});
22874  }
22875});
22876enifed("ember-htmlbars/template_registry", ["exports"], function (exports) {
22877  // STATE within a module is frowned apon, this exists
22878  // to support Ember.TEMPLATES but shield ember internals from this legacy
22879  // global API.
22880  "use strict";
22881
22882  exports.setTemplates = setTemplates;
22883  exports.getTemplates = getTemplates;
22884  exports.get = get;
22885  exports.has = has;
22886  exports.set = set;
22887  var TEMPLATES = {};
22888
22889  function setTemplates(templates) {
22890    TEMPLATES = templates;
22891  }
22892
22893  function getTemplates() {
22894    return TEMPLATES;
22895  }
22896
22897  function get(name) {
22898    if (TEMPLATES.hasOwnProperty(name)) {
22899      return TEMPLATES[name];
22900    }
22901  }
22902
22903  function has(name) {
22904    return TEMPLATES.hasOwnProperty(name);
22905  }
22906
22907  function set(name, template) {
22908    return TEMPLATES[name] = template;
22909  }
22910});
22911enifed("ember-htmlbars/templates/component", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
22912  "use strict";
22913
22914  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
22915    return {
22916      meta: {},
22917      isEmpty: false,
22918      arity: 0,
22919      cachedFragment: null,
22920      hasRendered: false,
22921      buildFragment: function buildFragment(dom) {
22922        var el0 = dom.createDocumentFragment();
22923        var el1 = dom.createComment("");
22924        dom.appendChild(el0, el1);
22925        return el0;
22926      },
22927      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
22928        var morphs = new Array(1);
22929        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
22930        dom.insertBoundary(fragment, 0);
22931        dom.insertBoundary(fragment, null);
22932        return morphs;
22933      },
22934      statements: [["content", "yield", ["loc", [null, [1, 0], [1, 9]]]]],
22935      locals: [],
22936      templates: []
22937    };
22938  })());
22939});
22940enifed("ember-htmlbars/templates/container-view", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
22941  "use strict";
22942
22943  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
22944    var child0 = (function () {
22945      return {
22946        meta: {},
22947        isEmpty: false,
22948        arity: 1,
22949        cachedFragment: null,
22950        hasRendered: false,
22951        buildFragment: function buildFragment(dom) {
22952          var el0 = dom.createDocumentFragment();
22953          var el1 = dom.createComment("");
22954          dom.appendChild(el0, el1);
22955          return el0;
22956        },
22957        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
22958          var morphs = new Array(1);
22959          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
22960          dom.insertBoundary(fragment, 0);
22961          dom.insertBoundary(fragment, null);
22962          return morphs;
22963        },
22964        statements: [["inline", "view", [["get", "childView", ["loc", [null, [1, 63], [1, 72]]]]], [], ["loc", [null, [1, 56], [1, 74]]]]],
22965        locals: ["childView"],
22966        templates: []
22967      };
22968    })();
22969    var child1 = (function () {
22970      var child0 = (function () {
22971        return {
22972          meta: {},
22973          isEmpty: false,
22974          arity: 0,
22975          cachedFragment: null,
22976          hasRendered: false,
22977          buildFragment: function buildFragment(dom) {
22978            var el0 = dom.createDocumentFragment();
22979            var el1 = dom.createComment("");
22980            dom.appendChild(el0, el1);
22981            return el0;
22982          },
22983          buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
22984            var morphs = new Array(1);
22985            morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
22986            dom.insertBoundary(fragment, 0);
22987            dom.insertBoundary(fragment, null);
22988            return morphs;
22989          },
22990          statements: [["inline", "view", [["get", "view._emptyView", ["loc", [null, [1, 108], [1, 123]]]]], ["_defaultTagName", ["get", "view._emptyViewTagName", ["loc", [null, [1, 140], [1, 162]]]]], ["loc", [null, [1, 101], [1, 164]]]]],
22991          locals: [],
22992          templates: []
22993        };
22994      })();
22995      return {
22996        meta: {},
22997        isEmpty: false,
22998        arity: 0,
22999        cachedFragment: null,
23000        hasRendered: false,
23001        buildFragment: function buildFragment(dom) {
23002          var el0 = dom.createDocumentFragment();
23003          var el1 = dom.createComment("");
23004          dom.appendChild(el0, el1);
23005          return el0;
23006        },
23007        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23008          var morphs = new Array(1);
23009          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23010          dom.insertBoundary(fragment, 0);
23011          dom.insertBoundary(fragment, null);
23012          return morphs;
23013        },
23014        statements: [["block", "if", [["get", "view._emptyView", ["loc", [null, [1, 84], [1, 99]]]]], [], 0, null, ["loc", [null, [1, 74], [1, 164]]]]],
23015        locals: [],
23016        templates: [child0]
23017      };
23018    })();
23019    return {
23020      meta: {},
23021      isEmpty: false,
23022      arity: 0,
23023      cachedFragment: null,
23024      hasRendered: false,
23025      buildFragment: function buildFragment(dom) {
23026        var el0 = dom.createDocumentFragment();
23027        var el1 = dom.createComment("");
23028        dom.appendChild(el0, el1);
23029        return el0;
23030      },
23031      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23032        var morphs = new Array(1);
23033        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23034        dom.insertBoundary(fragment, 0);
23035        dom.insertBoundary(fragment, null);
23036        return morphs;
23037      },
23038      statements: [["block", "each", [["get", "view.childViews", ["loc", [null, [1, 8], [1, 23]]]]], ["key", "elementId"], 0, 1, ["loc", [null, [1, 0], [1, 173]]]]],
23039      locals: [],
23040      templates: [child0, child1]
23041    };
23042  })());
23043});
23044enifed("ember-htmlbars/templates/empty", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23045  "use strict";
23046
23047  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23048    return {
23049      meta: {},
23050      isEmpty: true,
23051      arity: 0,
23052      cachedFragment: null,
23053      hasRendered: false,
23054      buildFragment: function buildFragment(dom) {
23055        var el0 = dom.createDocumentFragment();
23056        return el0;
23057      },
23058      buildRenderNodes: function buildRenderNodes() {
23059        return [];
23060      },
23061      statements: [],
23062      locals: [],
23063      templates: []
23064    };
23065  })());
23066});
23067enifed("ember-htmlbars/templates/legacy-each", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23068  "use strict";
23069
23070  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23071    var child0 = (function () {
23072      var child0 = (function () {
23073        var child0 = (function () {
23074          var child0 = (function () {
23075            return {
23076              meta: {},
23077              isEmpty: false,
23078              arity: 0,
23079              cachedFragment: null,
23080              hasRendered: false,
23081              buildFragment: function buildFragment(dom) {
23082                var el0 = dom.createDocumentFragment();
23083                var el1 = dom.createComment("");
23084                dom.appendChild(el0, el1);
23085                return el0;
23086              },
23087              buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23088                var morphs = new Array(1);
23089                morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23090                dom.insertBoundary(fragment, 0);
23091                dom.insertBoundary(fragment, null);
23092                return morphs;
23093              },
23094              statements: [["inline", "legacy-yield", [["get", "item", ["loc", [null, [5, 24], [5, 28]]]]], [], ["loc", [null, [5, 8], [5, 31]]]]],
23095              locals: [],
23096              templates: []
23097            };
23098          })();
23099          return {
23100            meta: {},
23101            isEmpty: false,
23102            arity: 0,
23103            cachedFragment: null,
23104            hasRendered: false,
23105            buildFragment: function buildFragment(dom) {
23106              var el0 = dom.createDocumentFragment();
23107              var el1 = dom.createComment("");
23108              dom.appendChild(el0, el1);
23109              return el0;
23110            },
23111            buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23112              var morphs = new Array(1);
23113              morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23114              dom.insertBoundary(fragment, 0);
23115              dom.insertBoundary(fragment, null);
23116              return morphs;
23117            },
23118            statements: [["block", "view", [["get", "attrs.itemViewClass", ["loc", [null, [4, 15], [4, 34]]]]], ["_defaultTagName", ["get", "view._itemTagName", ["loc", [null, [4, 51], [4, 68]]]]], 0, null, ["loc", [null, [4, 6], [6, 17]]]]],
23119            locals: [],
23120            templates: [child0]
23121          };
23122        })();
23123        var child1 = (function () {
23124          return {
23125            meta: {},
23126            isEmpty: false,
23127            arity: 0,
23128            cachedFragment: null,
23129            hasRendered: false,
23130            buildFragment: function buildFragment(dom) {
23131              var el0 = dom.createDocumentFragment();
23132              var el1 = dom.createComment("");
23133              dom.appendChild(el0, el1);
23134              return el0;
23135            },
23136            buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23137              var morphs = new Array(1);
23138              morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23139              dom.insertBoundary(fragment, 0);
23140              dom.insertBoundary(fragment, null);
23141              return morphs;
23142            },
23143            statements: [["inline", "legacy-yield", [["get", "item", ["loc", [null, [8, 22], [8, 26]]]]], [], ["loc", [null, [8, 6], [8, 29]]]]],
23144            locals: [],
23145            templates: []
23146          };
23147        })();
23148        return {
23149          meta: {},
23150          isEmpty: false,
23151          arity: 0,
23152          cachedFragment: null,
23153          hasRendered: false,
23154          buildFragment: function buildFragment(dom) {
23155            var el0 = dom.createDocumentFragment();
23156            var el1 = dom.createComment("");
23157            dom.appendChild(el0, el1);
23158            return el0;
23159          },
23160          buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23161            var morphs = new Array(1);
23162            morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23163            dom.insertBoundary(fragment, 0);
23164            dom.insertBoundary(fragment, null);
23165            return morphs;
23166          },
23167          statements: [["block", "if", [["get", "attrs.itemViewClass", ["loc", [null, [3, 11], [3, 30]]]]], [], 0, 1, ["loc", [null, [3, 4], [9, 13]]]]],
23168          locals: [],
23169          templates: [child0, child1]
23170        };
23171      })();
23172      var child1 = (function () {
23173        var child0 = (function () {
23174          var child0 = (function () {
23175            return {
23176              meta: {},
23177              isEmpty: false,
23178              arity: 0,
23179              cachedFragment: null,
23180              hasRendered: false,
23181              buildFragment: function buildFragment(dom) {
23182                var el0 = dom.createDocumentFragment();
23183                var el1 = dom.createComment("");
23184                dom.appendChild(el0, el1);
23185                return el0;
23186              },
23187              buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23188                var morphs = new Array(1);
23189                morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23190                dom.insertBoundary(fragment, 0);
23191                dom.insertBoundary(fragment, null);
23192                return morphs;
23193              },
23194              statements: [["inline", "legacy-yield", [["get", "item", ["loc", [null, [13, 24], [13, 28]
23194]]]], [], ["loc", [null, [13, 8], [13, 31]]]]],
23195              locals: [],
23196              templates: []
23197            };
23198          })();
23199          return {
23200            meta: {},
23201            isEmpty: false,
23202            arity: 0,
23203            cachedFragment: null,
23204            hasRendered: false,
23205            buildFragment: function buildFragment(dom) {
23206              var el0 = dom.createDocumentFragment();
23207              var el1 = dom.createComment("");
23208              dom.appendChild(el0, el1);
23209              return el0;
23210            },
23211            buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23212              var morphs = new Array(1);
23213              morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23214              dom.insertBoundary(fragment, 0);
23215              dom.insertBoundary(fragment, null);
23216              return morphs;
23217            },
23218            statements: [["block", "view", [["get", "attrs.itemViewClass", ["loc", [null, [12, 15], [12, 34]]]]], ["controller", ["get", "item", ["loc", [null, [12, 46], [12, 50]]]], "_defaultTagName", ["get", "view._itemTagName", ["loc", [null, [12, 67], [12, 84]]]]], 0, null, ["loc", [null, [12, 6], [14, 17]]]]],
23219            locals: [],
23220            templates: [child0]
23221          };
23222        })();
23223        var child1 = (function () {
23224          return {
23225            meta: {},
23226            isEmpty: false,
23227            arity: 0,
23228            cachedFragment: null,
23229            hasRendered: false,
23230            buildFragment: function buildFragment(dom) {
23231              var el0 = dom.createDocumentFragment();
23232              var el1 = dom.createComment("");
23233              dom.appendChild(el0, el1);
23234              return el0;
23235            },
23236            buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23237              var morphs = new Array(1);
23238              morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23239              dom.insertBoundary(fragment, 0);
23240              dom.insertBoundary(fragment, null);
23241              return morphs;
23242            },
23243            statements: [["inline", "legacy-yield", [["get", "item", ["loc", [null, [16, 22], [16, 26]]]]], ["controller", ["get", "item", ["loc", [null, [16, 38], [16, 42]]]]], ["loc", [null, [16, 6], [16, 45]]]]],
23244            locals: [],
23245            templates: []
23246          };
23247        })();
23248        return {
23249          meta: {},
23250          isEmpty: false,
23251          arity: 0,
23252          cachedFragment: null,
23253          hasRendered: false,
23254          buildFragment: function buildFragment(dom) {
23255            var el0 = dom.createDocumentFragment();
23256            var el1 = dom.createComment("");
23257            dom.appendChild(el0, el1);
23258            return el0;
23259          },
23260          buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23261            var morphs = new Array(1);
23262            morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23263            dom.insertBoundary(fragment, 0);
23264            dom.insertBoundary(fragment, null);
23265            return morphs;
23266          },
23267          statements: [["block", "if", [["get", "attrs.itemViewClass", ["loc", [null, [11, 11], [11, 30]]]]], [], 0, 1, ["loc", [null, [11, 4], [17, 13]]]]],
23268          locals: [],
23269          templates: [child0, child1]
23270        };
23271      })();
23272      return {
23273        meta: {},
23274        isEmpty: false,
23275        arity: 1,
23276        cachedFragment: null,
23277        hasRendered: false,
23278        buildFragment: function buildFragment(dom) {
23279          var el0 = dom.createDocumentFragment();
23280          var el1 = dom.createComment("");
23281          dom.appendChild(el0, el1);
23282          return el0;
23283        },
23284        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23285          var morphs = new Array(1);
23286          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23287          dom.insertBoundary(fragment, 0);
23288          dom.insertBoundary(fragment, null);
23289          return morphs;
23290        },
23291        statements: [["block", "if", [["get", "view.keyword", ["loc", [null, [2, 9], [2, 21]]]]], [], 0, 1, ["loc", [null, [2, 2], [18, 11]]]]],
23292        locals: ["item"],
23293        templates: [child0, child1]
23294      };
23295    })();
23296    var child1 = (function () {
23297      var child0 = (function () {
23298        return {
23299          meta: {},
23300          isEmpty: false,
23301          arity: 0,
23302          cachedFragment: null,
23303          hasRendered: false,
23304          buildFragment: function buildFragment(dom) {
23305            var el0 = dom.createDocumentFragment();
23306            var el1 = dom.createComment("");
23307            dom.appendChild(el0, el1);
23308            return el0;
23309          },
23310          buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23311            var morphs = new Array(1);
23312            morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23313            dom.insertBoundary(fragment, 0);
23314            dom.insertBoundary(fragment, null);
23315            return morphs;
23316          },
23317          statements: [["inline", "view", [["get", "view._emptyView", ["loc", [null, [20, 10], [20, 25]]]]], ["_defaultTagName", ["get", "view._itemTagName", ["loc", [null, [20, 42], [20, 59]]]]], ["loc", [null, [20, 2], [20, 62]]]]],
23318          locals: [],
23319          templates: []
23320        };
23321      })();
23322      return {
23323        meta: {},
23324        isEmpty: false,
23325        arity: 0,
23326        cachedFragment: null,
23327        hasRendered: false,
23328        buildFragment: function buildFragment(dom) {
23329          var el0 = dom.createDocumentFragment();
23330          var el1 = dom.createComment("");
23331          dom.appendChild(el0, el1);
23332          return el0;
23333        },
23334        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23335          var morphs = new Array(1);
23336          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23337          dom.insertBoundary(fragment, 0);
23338          dom.insertBoundary(fragment, null);
23339          return morphs;
23340        },
23341        statements: [["block", "if", [["get", "view._emptyView", ["loc", [null, [19, 11], [19, 26]]]]], [], 0, null, ["loc", [null, [19, 0], [21, 0]]]]],
23342        locals: [],
23343        templates: [child0]
23344      };
23345    })();
23346    return {
23347      meta: {},
23348      isEmpty: false,
23349      arity: 0,
23350      cachedFragment: null,
23351      hasRendered: false,
23352      buildFragment: function buildFragment(dom) {
23353        var el0 = dom.createDocumentFragment();
23354        var el1 = dom.createComment("");
23355        dom.appendChild(el0, el1);
23356        return el0;
23357      },
23358      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23359        var morphs = new Array(1);
23360        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23361        dom.insertBoundary(fragment, 0);
23362        dom.insertBoundary(fragment, null);
23363        return morphs;
23364      },
23365      statements: [["block", "each", [["get", "view._arrangedContent", ["loc", [null, [1, 9], [1, 30]]]]], ["-legacy-keyword", ["get", "view.keyword", ["loc", [null, [1, 47], [1, 59]]]]], 0, 1, ["loc", [null, [1, 0], [21, 11]]]]],
23366      locals: [],
23367      templates: [child0, child1]
23368    };
23369  })());
23370});
23371enifed("ember-htmlbars/templates/link-to", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23372  "use strict";
23373
23374  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23375    var child0 = (function () {
23376      return {
23377        meta: {},
23378        isEmpty: false,
23379        arity: 0,
23380        cachedFragment: null,
23381        hasRendered: false,
23382        buildFragment: function buildFragment(dom) {
23383          var el0 = dom.createDocumentFragment();
23384          var el1 = dom.createComment("");
23385          dom.appendChild(el0, el1);
23386          return el0;
23387        },
23388        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23389          var morphs = new Array(1);
23390          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23391          dom.insertBoundary(fragment, 0);
23392          dom.insertBoundary(fragment, null);
23393          return morphs;
23394        },
23395        statements: [["content", "linkTitle", ["loc", [null, [1, 17], [1, 30]]]]],
23396        locals: [],
23397        templates: []
23398      };
23399    })();
23400    var child1 = (function () {
23401      return {
23402        meta: {},
23403        isEmpty: false,
23404        arity: 0,
23405        cachedFragment: null,
23406        hasRendered: false,
23407        buildFragment: function buildFragment(dom) {
23408          var el0 = dom.createDocumentFragment();
23409          var el1 = dom.createComment("");
23410          dom.appendChild(el0, el1);
23411          return el0;
23412        },
23413        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23414          var morphs = new Array(1);
23415          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23416          dom.insertBoundary(fragment, 0);
23417          dom.insertBoundary(fragment, null);
23418          return morphs;
23419        },
23420        statements: [["content", "yield", ["loc", [null, [1, 38], [1, 47]]]]],
23421        locals: [],
23422        templates: []
23423      };
23424    })();
23425    return {
23426      meta: {},
23427      isEmpty: false,
23428      arity: 0,
23429      cachedFragment: null,
23430      hasRendered: false,
23431      buildFragment: function buildFragment(dom) {
23432        var el0 = dom.createDocumentFragment();
23433        var el1 = dom.createComment("");
23434        dom.appendChild(el0, el1);
23435        return el0;
23436      },
23437      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23438        var morphs = new Array(1);
23439        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23440        dom.insertBoundary(fragment, 0);
23441        dom.insertBoundary(fragment, null);
23442        return morphs;
23443      },
23444      statements: [["block", "if", [["get", "linkTitle", ["loc", [null, [1, 6], [1, 15]]]]], [], 0, 1, ["loc", [null, [1, 0], [1, 54]]]]],
23445      locals: [],
23446      templates: [child0, child1]
23447    };
23448  })());
23449});
23450enifed("ember-htmlbars/templates/select-optgroup", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23451  "use strict";
23452
23453  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23454    var child0 = (function () {
23455      return {
23456        meta: {},
23457        isEmpty: false,
23458        arity: 1,
23459        cachedFragment: null,
23460        hasRendered: false,
23461        buildFragment: function buildFragment(dom) {
23462          var el0 = dom.createDocumentFragment();
23463          var el1 = dom.createComment("");
23464          dom.appendChild(el0, el1);
23465          return el0;
23466        },
23467        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23468          var morphs = new Array(1);
23469          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23470          dom.insertBoundary(fragment, 0);
23471          dom.insertBoundary(fragment, null);
23472          return morphs;
23473        },
23474        statements: [["inline", "view", [["get", "attrs.optionView", ["loc", [null, [1, 40], [1, 56]]]]], ["content", ["get", "item", ["loc", [null, [1, 65], [1, 69]]]], "selection", ["get", "attrs.selection", ["loc", [null, [1, 80], [1, 95]]]], "parentValue", ["get", "attrs.value", ["loc", [null, [1, 108], [1, 119]]]], "multiple", ["get", "attrs.multiple", ["loc", [null, [1, 129], [1, 143]]]], "optionLabelPath", ["get", "attrs.optionLabelPath", ["loc", [null, [1, 160], [1, 181]]]], "optionValuePath", ["get", "attrs.optionValuePath", ["loc", [null, [1, 198], [1, 219]]]]], ["loc", [null, [1, 33], [1, 221]]]]],
23475        locals: ["item"],
23476        templates: []
23477      };
23478    })();
23479    return {
23480      meta: {},
23481      isEmpty: false,
23482      arity: 0,
23483      cachedFragment: null,
23484      hasRendered: false,
23485      buildFragment: function buildFragment(dom) {
23486        var el0 = dom.createDocumentFragment();
23487        var el1 = dom.createComment("");
23488        dom.appendChild(el0, el1);
23489        return el0;
23490      },
23491      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23492        var morphs = new Array(1);
23493        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23494        dom.insertBoundary(fragment, 0);
23495        dom.insertBoundary(fragment, null);
23496        return morphs;
23497      },
23498      statements: [["block", "each", [["get", "attrs.content", ["loc", [null, [1, 8], [1, 21]]]]], [], 0, null, ["loc", [null, [1, 0], [1, 230]]]]],
23499      locals: [],
23500      templates: [child0]
23501    };
23502  })());
23503});
23504enifed("ember-htmlbars/templates/select-option", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23505  "use strict";
23506
23507  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23508    return {
23509      meta: {},
23510      isEmpty: false,
23511      arity: 0,
23512      cachedFragment: null,
23513      hasRendered: false,
23514      buildFragment: function buildFragment(dom) {
23515        var el0 = dom.createDocumentFragment();
23516        var el1 = dom.createComment("");
23517        dom.appendChild(el0, el1);
23518        return el0;
23519      },
23520      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23521        var morphs = new Array(1);
23522        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23523        dom.insertBoundary(fragment, 0);
23524        dom.insertBoundary(fragment, null);
23525        return morphs;
23526      },
23527      statements: [["content", "view.label", ["loc", [null, [1, 0], [1, 16]]]]],
23528      locals: [],
23529      templates: []
23530    };
23531  })());
23532});
23533enifed("ember-htmlbars/templates/select", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23534  "use strict";
23535
23536  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23537    var child0 = (function () {
23538      return {
23539        meta: {},
23540        isEmpty: false,
23541        arity: 0,
23542        cachedFragment: null,
23543        hasRendered: false,
23544        buildFragment: function buildFragment(dom) {
23545          var el0 = dom.createDocumentFragment();
23546          var el1 = dom.createElement("option");
23547          dom.setAttribute(el1, "value", "");
23548          var el2 = dom.createComment("");
23549          dom.appendChild(el1, el2);
23550          dom.appendChild(el0, el1);
23551          return el0;
23552        },
23553        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23554          var morphs = new Array(1);
23555          morphs[0] = dom.createMorphAt(dom.childAt(fragment, [0]), 0, 0);
23556          return morphs;
23557        },
23558        statements: [["content", "view.prompt", ["loc", [null, [1, 36], [1, 51]]]]],
23559        locals: [],
23560        templates: []
23561      };
23562    })();
23563    var child1 = (function () {
23564      var child0 = (function () {
23565        return {
23566          meta: {},
23567          isEmpty: false,
23568          arity: 1,
23569          cachedFragment: null,
23570          hasRendered: false,
23571          buildFragment: function buildFragment(dom) {
23572            var el0 = dom.createDocumentFragment();
23573            var el1 = dom.createComment("");
23574            dom.appendChild(el0, el1);
23575            return el0;
23576          },
23577          buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23578            var morphs = new Array(1);
23579            morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23580            dom.insertBoundary(fragment, 0);
23581            dom.insertBoundary(fragment, null);
23582            return morphs;
23583          },
23584          statements: [["inline", "view", [["get", "view.groupView", ["loc", [null, [1, 142], [1, 156]]]]], ["content", ["get", "group.content", ["loc", [null, [1, 165], [1, 178]]]], "label", ["get", "group.label", ["loc", [null, [1, 185], [1, 196]]]], "selection", ["get", "view.selection", ["loc", [null, [1, 207], [1, 221]]]], "value", ["get", "view.value", ["loc", [null, [1, 228], [1, 238]]]], "multiple", ["get", "view.multiple", ["loc", [null, [1, 248], [1, 261]]]], "optionLabelPath", ["get", "view.optionLabelPath", ["loc", [null, [1, 278], [1, 298]]]], "optionValuePath", ["get", "view.optionValuePath", ["loc", [null, [1, 315], [1, 335]]]], "optionView", ["get", "view.optionView", ["loc", [null, [1, 347], [1, 362]]]]], ["loc", [null, [1, 135], [1, 364]]]]],
23585          locals: ["group"],
23586          templates: []
23587        };
23588      })();
23589      return {
23590        meta: {},
23591        isEmpty: false,
23592        arity: 0,
23593        cachedFragment: null,
23594        hasRendered: fal
23594se,
23595        buildFragment: function buildFragment(dom) {
23596          var el0 = dom.createDocumentFragment();
23597          var el1 = dom.createComment("");
23598          dom.appendChild(el0, el1);
23599          return el0;
23600        },
23601        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23602          var morphs = new Array(1);
23603          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23604          dom.insertBoundary(fragment, 0);
23605          dom.insertBoundary(fragment, null);
23606          return morphs;
23607        },
23608        statements: [["block", "each", [["get", "view.groupedContent", ["loc", [null, [1, 103], [1, 122]]]]], [], 0, null, ["loc", [null, [1, 95], [1, 373]]]]],
23609        locals: [],
23610        templates: [child0]
23611      };
23612    })();
23613    var child2 = (function () {
23614      var child0 = (function () {
23615        return {
23616          meta: {},
23617          isEmpty: false,
23618          arity: 1,
23619          cachedFragment: null,
23620          hasRendered: false,
23621          buildFragment: function buildFragment(dom) {
23622            var el0 = dom.createDocumentFragment();
23623            var el1 = dom.createComment("");
23624            dom.appendChild(el0, el1);
23625            return el0;
23626          },
23627          buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23628            var morphs = new Array(1);
23629            morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23630            dom.insertBoundary(fragment, 0);
23631            dom.insertBoundary(fragment, null);
23632            return morphs;
23633          },
23634          statements: [["inline", "view", [["get", "view.optionView", ["loc", [null, [1, 420], [1, 435]]]]], ["content", ["get", "item", ["loc", [null, [1, 444], [1, 448]]]], "selection", ["get", "view.selection", ["loc", [null, [1, 459], [1, 473]]]], "parentValue", ["get", "view.value", ["loc", [null, [1, 486], [1, 496]]]], "multiple", ["get", "view.multiple", ["loc", [null, [1, 506], [1, 519]]]], "optionLabelPath", ["get", "view.optionLabelPath", ["loc", [null, [1, 536], [1, 556]]]], "optionValuePath", ["get", "view.optionValuePath", ["loc", [null, [1, 573], [1, 593]]]]], ["loc", [null, [1, 413], [1, 595]]]]],
23635          locals: ["item"],
23636          templates: []
23637        };
23638      })();
23639      return {
23640        meta: {},
23641        isEmpty: false,
23642        arity: 0,
23643        cachedFragment: null,
23644        hasRendered: false,
23645        buildFragment: function buildFragment(dom) {
23646          var el0 = dom.createDocumentFragment();
23647          var el1 = dom.createComment("");
23648          dom.appendChild(el0, el1);
23649          return el0;
23650        },
23651        buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23652          var morphs = new Array(1);
23653          morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23654          dom.insertBoundary(fragment, 0);
23655          dom.insertBoundary(fragment, null);
23656          return morphs;
23657        },
23658        statements: [["block", "each", [["get", "view.content", ["loc", [null, [1, 389], [1, 401]]]]], [], 0, null, ["loc", [null, [1, 381], [1, 604]]]]],
23659        locals: [],
23660        templates: [child0]
23661      };
23662    })();
23663    return {
23664      meta: {},
23665      isEmpty: false,
23666      arity: 0,
23667      cachedFragment: null,
23668      hasRendered: false,
23669      buildFragment: function buildFragment(dom) {
23670        var el0 = dom.createDocumentFragment();
23671        var el1 = dom.createComment("");
23672        dom.appendChild(el0, el1);
23673        var el1 = dom.createComment("");
23674        dom.appendChild(el0, el1);
23675        var el1 = dom.createTextNode("\n");
23676        dom.appendChild(el0, el1);
23677        return el0;
23678      },
23679      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23680        var morphs = new Array(2);
23681        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23682        morphs[1] = dom.createMorphAt(fragment, 1, 1, contextualElement);
23683        dom.insertBoundary(fragment, 0);
23684        return morphs;
23685      },
23686      statements: [["block", "if", [["get", "view.prompt", ["loc", [null, [1, 6], [1, 17]]]]], [], 0, null, ["loc", [null, [1, 0], [1, 67]]]], ["block", "if", [["get", "view.optionGroupPath", ["loc", [null, [1, 73], [1, 93]]]]], [], 1, 2, ["loc", [null, [1, 67], [1, 611]]]]],
23687      locals: [],
23688      templates: [child0, child1, child2]
23689    };
23690  })());
23691});
23692enifed("ember-htmlbars/templates/top-level-view", ["exports", "ember-template-compiler/system/template"], function (exports, _emberTemplateCompilerSystemTemplate) {
23693  "use strict";
23694
23695  exports.default = _emberTemplateCompilerSystemTemplate.default((function () {
23696    return {
23697      meta: {},
23698      isEmpty: false,
23699      arity: 0,
23700      cachedFragment: null,
23701      hasRendered: false,
23702      buildFragment: function buildFragment(dom) {
23703        var el0 = dom.createDocumentFragment();
23704        var el1 = dom.createComment("");
23705        dom.appendChild(el0, el1);
23706        return el0;
23707      },
23708      buildRenderNodes: function buildRenderNodes(dom, fragment, contextualElement) {
23709        var morphs = new Array(1);
23710        morphs[0] = dom.createMorphAt(fragment, 0, 0, contextualElement);
23711        dom.insertBoundary(fragment, 0);
23712        dom.insertBoundary(fragment, null);
23713        return morphs;
23714      },
23715      statements: [["content", "outlet", ["loc", [null, [1, 0], [1, 10]]]]],
23716      locals: [],
23717      templates: []
23718    };
23719  })());
23720});
23721enifed('ember-htmlbars/utils/decode-each-key', ['exports', 'ember-metal/property_get', 'ember-metal/utils'], function (exports, _emberMetalProperty_get, _emberMetalUtils) {
23722  'use strict';
23723
23724  exports.default = decodeEachKey;
23725
23726  function identity(item) {
23727    var key = undefined;
23728    var type = typeof item;
23729
23730    if (type === 'string' || type === 'number') {
23731      key = item;
23732    } else {
23733      key = _emberMetalUtils.guidFor(item);
23734    }
23735
23736    return key;
23737  }
23738
23739  function decodeEachKey(item, keyPath, index) {
23740    var key;
23741
23742    switch (keyPath) {
23743      case '@index':
23744        key = index;
23745        break;
23746      case '@identity':
23747        key = identity(item);
23748        break;
23749      default:
23750        if (keyPath) {
23751          key = _emberMetalProperty_get.get(item, keyPath);
23752        } else {
23753          key = identity(item);
23754        }
23755    }
23756
23757    if (typeof key === 'number') {
23758      key = String(key);
23759    }
23760
23761    return key;
23762  }
23763});
23764enifed('ember-htmlbars/utils/extract-positional-params', ['exports', 'ember-metal/debug', 'ember-metal/stream
23764s/stream', 'ember-metal/streams/utils'], function (exports, _emberMetalDebug, _emberMetalStreamsStream, _emberMetalStreamsUtils) {
23765  'use strict';
23766
23767  exports.default = extractPositionalParams;
23768  exports.processPositionalParams = processPositionalParams;
23769
23770  function extractPositionalParams(renderNode, component, params, attrs) {
23771    var positionalParams = component.positionalParams;
23772
23773    if (positionalParams) {
23774      processPositionalParams(renderNode, positionalParams, params, attrs);
23775    }
23776  }
23777
23778  function processPositionalParams(renderNode, positionalParams, params, attrs) {
23779    var isRest = typeof positionalParams === 'string';
23780
23781    if (isRest) {
23782      processRestPositionalParameters(renderNode, positionalParams, params, attrs);
23783    } else {
23784      processNamedPositionalParameters(renderNode, positionalParams, params, attrs);
23785    }
23786  }
23787
23788  function processNamedPositionalParameters(renderNode, positionalParams, params, attrs) {
23789    var limit = Math.min(params.length, positionalParams.length);
23790
23791    for (var i = 0; i < limit; i++) {
23792      var param = params[i];
23793
23794      _emberMetalDebug.assert('You cannot specify both a positional param (at position ' + i + ') and the hash argument `' + positionalParams[i] + '`.', !(positionalParams[i] in attrs));
23795
23796      attrs[positionalParams[i]] = param;
23797    }
23798  }
23799
23800  function processRestPositionalParameters(renderNode, positionalParamsName, params, attrs) {
23801    var nameInAttrs = (positionalParamsName in attrs);
23802
23803    // when no params are used, do not override the specified `attrs.stringParamName` value
23804    if (params.length === 0 && nameInAttrs) {
23805      return;
23806    }
23807
23808    // If there is already an attribute for that variable, do nothing
23809    _emberMetalDebug.assert('You cannot specify positional parameters and the hash argument `' + positionalParamsName + '`.', !nameInAttrs);
23810
23811    var paramsStream = new _emberMetalStreamsStream.Stream(function () {
23812      return _emberMetalStreamsUtils.readArray(params.slice(0));
23813    }, 'params');
23814
23815    attrs[positionalParamsName] = paramsStream;
23816
23817    for (var i = 0; i < params.length; i++) {
23818      var param = params[i];
23819      paramsStream.addDependency(param);
23820    }
23821  }
23822});
23823enifed('ember-htmlbars/utils/is-component', ['exports', 'ember-metal/features', 'ember-htmlbars/system/lookup-helper', 'ember-htmlbars/keywords/closure-component', 'ember-metal/streams/utils'], function (exports, _emberMetalFeatures, _emberHtmlbarsSystemLookupHelper, _emberHtmlbarsKeywordsClosureComponent, _emberMetalStreamsUtils) {
23824  /**
23825  @module ember
23826  @submodule ember-htmlbars
23827  */
23828
23829  'use strict';
23830
23831  exports.default = isComponent;
23832
23833  function hasComponentOrTemplate(owner, path, options) {
23834    return owner.hasRegistration('component:' + path, options) || owner.hasRegistration('template:components/' + path, options);
23835  }
23836
23837  /*
23838   Given a path name, returns whether or not a component with that
23839   name was found in the container.
23840  */
23841
23842  function isComponent(env, scope, path) {
23843    var owner = env.owner;
23844    if (!owner) {
23845      return false;
23846    }
23847    if (typeof path === 'string') {
23848      if (_emberHtmlbarsSystemLookupHelper.CONTAINS_DOT_CACHE.get(path)) {
23849        var stream = env.hooks.get(env, scope, path);
23850        if (_emberMetalStreamsUtils.isStream(stream)) {
23851          var cell = stream.value();
23852          if (_emberHtmlbarsKeywordsClosureComponent.isComponentCell(cell)) {
23853            return true;
23854          }
23855        }
23856      }
23857      if (!_emberHtmlbarsSystemLookupHelper.CONTAINS_DASH_CACHE.get(path)) {
23858        return false;
23859      }
23860
23861      if (hasComponentOrTemplate(owner, path)) {
23862        return true; // global component found
23863      } else {
23864          var moduleName = env.meta && env.meta.moduleName;
23865
23866          if (!moduleName) {
23867            // Without a source moduleName, we can not perform local lookups.
23868            return false;
23869          }
23870
23871          var options = { source: 'template:' + moduleName };
23872
23873          return hasComponentOrTemplate(owner, path, options);
23874        }
23875    }
23876  }
23877});
23878enifed('ember-htmlbars/utils/lookup-component', ['exports', 'ember-metal/features'], function (exports, _emberMetalFeatures) {
23879  'use strict';
23880
23881  exports.default = lookupComponent;
23882
23883  function lookupComponentPair(componentLookup, owner, name, options) {
23884    return {
23885      component: componentLookup.componentFor(name, owner, options),
23886      layout: componentLookup.layoutFor(name, owner, options)
23887    };
23888  }
23889
23890  function lookupComponent(owner, name, options) {
23891    var componentLookup = owner.lookup('component-lookup:main');
23892
23893    var source = options && options.source;
23894
23895    if (source) {
23896      var localResult = lookupComponentPair(componentLookup, owner, name, options);
23897
23898      if (localResult.component || localResult.layout) {
23899        return localResult;
23900      }
23901    }
23902
23903    return lookupComponentPair(componentLookup, owner, name);
23904  }
23905});
23906enifed('ember-htmlbars/utils/new-stream', ['exports', 'ember-metal/streams/proxy-stream', 'ember-htmlbars/utils/subscribe'], function (exports, _emberMetalStreamsProxyStream, _emberHtmlbarsUtilsSubscribe) {
23907  'use strict';
23908
23909  exports.default = newStream;
23910
23911  function newStream(scope, key, newValue, renderNode, isSelf) {
23912    var stream = new _emberMetalStreamsProxyStream.default(newValue, isSelf ? '' : key);
23913    if (renderNode) {
23914      _emberHtmlbarsUtilsSubscribe.default(renderNode, scope, stream);
23915    }
23916    scope[key] = stream;
23917  }
23918});
23919enifed("ember-htmlbars/utils/normalize-self", ["exports"], function (exports) {
23920  "use strict";
23921
23922  exports.default = normalizeSelf;
23923
23924  function normalizeSelf(self) {
23925    if (self === undefined) {
23926      return null;
23927    } else {
23928      return self;
23929    }
23930  }
23931});
23932enifed('ember-htmlbars/utils/string', ['exports', 'ember-metal/core', 'ember-runtime/system/string', 'htmlbars-util'], function (exports, _emberMetalCore, _emberRuntimeSystemString, _htmlbarsUtil) {
23933  /**
23934  @module ember
23935  @submodule ember-htmlbars
23936  */
23937
23938  'use strict';
23939
23940  /**
23941    Mark a string as safe for unescaped output with Ember templates. If you
23942    return HTML from a helper, use this function to
23943    ensure Ember's rendering layer does not escape the HTML.
23944  
23945    ```javascript
23946    Ember.String.htmlSafe('<div>someString</div>')
23947    ```
23948  
23949    @method htmlSafe
23950    @for Ember.String
23951    @static
23952    @return {Handlebars.SafeString} A string that will not be HTML escaped by Handlebars.
23953    @public
23954  */
23955  function htmlSafe(str) {
23956    if (str === null || str === undefined) {
23957      str = '';
23958    } else if (typeof str !== 'string') {
23959      str = '' + str;
23960    }
23961    return new _htmlbarsUtil.SafeString(str);
23962  }
23963
23964  _emberRuntimeSystemString.default.htmlSafe = htmlSafe;
23965  if (_emberMetalCore.default.EXTEND_PROTOTYPES === true || _emberMetalCore.default.EXTEND_PROTOTYPES.String) {
23966    String.prototype.htmlSafe = function () {
23967      return htmlSafe(this);
23968    };
23969  }
23970
23971  exports.SafeString = _htmlbarsUtil.SafeString;
23972  exports.htmlSafe = htmlSafe;
23973  exports.escapeExpression = _htmlbarsUtil.escapeExpression;
23974});
23975enifed('ember-htmlbars/utils/subscribe', ['exports', 'ember-metal/streams/utils'], function (exports, _emberMetalStreamsUtils) {
23976  'use strict';
23977
23978  exports.default = subscribe;
23979
23980  function subscribe(node, env, scope, stream) {
23981    if (!_emberMetalStreamsUtils.isStream(stream)) {
23982      return;
23983    }
23984    var component = scope.getComponent();
23985    var unsubscribers = node.streamUnsubscribers = node.streamUnsubscribers || [];
23986
23987    unsubscribers.push(stream.subscribe(function () {
23988      node.isDirty = true;
23989
23990      // Whenever a render node directly inside a component becomes
23991      // dirty, we want to invoke the willRenderElement and
23992      // didRenderElement lifecycle hooks. From the perspective of the
23993      // programming model, whenever anything in the DOM changes, a
23994      // "re-render" has occured.
23995      if (component && component._renderNode) {
23996        component._renderNode.isDirty = true;
23997      }
23998
23999      if (node.getState().manager) {
24000        node.shouldReceiveAttrs = true;
24001      }
24002
24003      node.ownerNode.emberView.scheduleRevalidate(node, _emberMetalStreamsUtils.labelFor(stream));
24004    }));
24005  }
24006});
24007enifed('ember-htmlbars/utils/update-scope', ['exports', 'ember-metal/stream
24007s/proxy-stream', 'ember-htmlbars/utils/subscribe'], function (exports, _emberMetalStreamsProxyStream, _emberHtmlbarsUtilsSubscribe) {
24008  'use strict';
24009
24010  exports.default = updateScope;
24011
24012  function updateScope(scope, key, newValue, renderNode, isSelf) {
24013    var existing = scope[key];
24014
24015    if (existing) {
24016      existing.setSource(newValue);
24017    } else {
24018      var stream = new _emberMetalStreamsProxyStream.default(newValue, isSelf ? null : key);
24019      if (renderNode) {
24020        _emberHtmlbarsUtilsSubscribe.default(renderNode, scope, stream);
24021      }
24022      scope[key] = stream;
24023    }
24024  }
24025});
24026enifed('ember-metal/alias', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/error', 'ember-metal/properties', 'ember-metal/computed', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/dependent_keys'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalError, _emberMetalProperties, _emberMetalComputed, _emberMetalUtils, _emberMetalMeta, _emberMetalDependent_keys) {
24027  'use strict';
24028
24029  exports.default = alias;
24030  exports.AliasedProperty = AliasedProperty;
24031
24032  function alias(altKey) {
24033    return new AliasedProperty(altKey);
24034  }
24035
24036  function AliasedProperty(altKey) {
24037    this.isDescriptor = true;
24038    this.altKey = altKey;
24039    this._dependentKeys = [altKey];
24040  }
24041
24042  AliasedProperty.prototype = Object.create(_emberMetalProperties.Descriptor.prototype);
24043
24044  AliasedProperty.prototype.get = function AliasedProperty_get(obj, keyName) {
24045    return _emberMetalProperty_get.get(obj, this.altKey);
24046  };
24047
24048  AliasedProperty.prototype.set = function AliasedProperty_set(obj, keyName, value) {
24049    return _emberMetalProperty_set.set(obj, this.altKey, value);
24050  };
24051
24052  AliasedProperty.prototype.willWatch = function (obj, keyName) {
24053    _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, _emberMetalMeta.meta(obj));
24054  };
24055
24056  AliasedProperty.prototype.didUnwatch = function (obj, keyName) {
24057    _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, _emberMetalMeta.meta(obj));
24058  };
24059
24060  AliasedProperty.prototype.setup = function (obj, keyName) {
24061    _emberMetalDebug.assert('Setting alias \'' + keyName + '\' on self', this.altKey !== keyName);
24062    var m = _emberMetalMeta.meta(obj);
24063    if (m.peekWatching(keyName)) {
24064      _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, m);
24065    }
24066  };
24067
24068  AliasedProperty.prototype.teardown = function (obj, keyName) {
24069    var m = _emberMetalMeta.meta(obj);
24070    if (m.peekWatching(keyName)) {
24071      _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, m);
24072    }
24073  };
24074
24075  AliasedProperty.prototype.readOnly = function () {
24076    this.set = AliasedProperty_readOnlySet;
24077    return this;
24078  };
24079
24080  function AliasedProperty_readOnlySet(obj, keyName, value) {
24081    throw new _emberMetalError.default('Cannot set read-only property \'' + keyName + '\' on object: ' + _emberMetalUtils.inspect(obj));
24082  }
24083
24084  AliasedProperty.prototype.oneWay = function () {
24085    this.set = AliasedProperty_oneWaySet;
24086    return this;
24087  };
24088
24089  function AliasedProperty_oneWaySet(obj, keyName, value) {
24090    _emberMetalProperties.defineProperty(obj, keyName, null);
24091    return _emberMetalProperty_set.set(obj, keyName, value);
24092  }
24093
24094  // Backwards compatibility with Ember Data.
24095  AliasedProperty.prototype._meta = undefined;
24096  AliasedProperty.prototype.meta = _emberMetalComputed.ComputedProperty.prototype.meta;
24097});
24098enifed("ember-metal/assign", ["exports"], function (exports) {
24099  /**
24100    Copy properties from a source object to a target object.
24101  
24102    ```javascript
24103    var a = {first: 'Yehuda'};
24104    var b = {last: 'Katz'};
24105    var c = {company: 'Tilde Inc.'};
24106    Ember.assign(a, b, c); // a === {first: 'Yehuda', last: 'Katz', company: 'Tilde Inc.'}, b === {last: 'Katz'}, c === {company: 'Tilde Inc.'}
24107    ```
24108  
24109    @method assign
24110    @for Ember
24111    @param {Object} original The object to assign into
24112    @param {Object} ...args The objects to copy properties from
24113    @return {Object}
24114    @public
24115  */
24116  "use strict";
24117
24118  exports.default = assign;
24119
24120  function assign(original) {
24121    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
24122      args[_key - 1] = arguments[_key];
24123    }
24124
24125    for (var i = 0, l = args.length; i < l; i++) {
24126      var arg = args[i];
24127      if (!arg) {
24128        continue;
24129      }
24130
24131      var updates = Object.keys(arg);
24132
24133      for (var _i = 0, _l = updates.length; _i < _l; _i++) {
24134        var prop = updates[_i];
24135        original[prop] = arg[prop];
24136      }
24137    }
24138
24139    return original;
24140  }
24141});
24142enifed('ember-metal/binding', ['exports', 'ember-metal/core', 'ember-metal/logger', 'ember-metal/run_loop', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/events', 'ember-metal/observer', 'ember-metal/path_cache'], function (exports, _emberMetalCore, _emberMetalLogger, _emberMetalRun_loop, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalUtils, _emberMetalEvents, _emberMetalObserver, _emberMetalPath_cache) {
24143  'use strict';
24144
24145  exports.bind = bind;
24146
24147  // ES6TODO: where is Ember.lookup defined?
24148  /**
24149  @module ember
24150  @submodule ember-metal
24151  */
24152
24153  // ..........................................................
24154  // CONSTANTS
24155  //
24156
24157  /**
24158    Debug parameter you can turn on. This will log all bindings that fire to
24159    the console. This should be disabled in production code. Note that you
24160    can also enable this from the console or temporarily.
24161  
24162    @property LOG_BINDINGS
24163    @for Ember
24164    @type Boolean
24165    @default false
24166    @public
24167  */
24168  _emberMetalCore.default.LOG_BINDINGS = false || !!_emberMetalCore.default.ENV.LOG_BINDINGS;
24169
24170  // ..........................................................
24171  // BINDING
24172  //
24173
24174  function Binding(toPath, fromPath) {
24175    // Configuration
24176    this._from = fromPath;
24177    this._to = toPath;
24178    this._oneWay = undefined;
24179
24180    // State
24181    this._direction = undefined;
24182    this._readyToSync = undefined;
24183    this._fromObj = undefined;
24184    this._fromPath = undefined;
24185    this._toObj = undefined;
24186  }
24187
24188  /**
24189    @class Binding
24190    @namespace Ember
24191    @public
24192  */
24193
24194  Binding.prototype = {
24195    /**
24196      This copies the Binding so it can be connected to another object.
24197       @method copy
24198      @return {Ember.Binding} `this`
24199      @public
24200    */
24201    copy: function () {
24202      var copy = new Binding(this._to, this._from);
24203      if (this._oneWay) {
24204        copy._oneWay = true;
24205      }
24206      return copy;
24207    },
24208
24209    // ..........................................................
24210    // CONFIG
24211    //
24212
24213    /**
24214      This will set `from` property path to the specified value. It will not
24215      attempt to resolve this property path to an actual object until you
24216      connect the binding.
24217       The binding will search for the property path starting at the root object
24218      you pass when you `connect()` the binding. It follows the same rules as
24219      `get()` - see that method for more information.
24220       @method from
24221      @param {String} path The property path to connect to.
24222      @return {Ember.Binding} `this`
24223      @public
24224    */
24225    from: function (path) {
24226      this._from = path;
24227      return this;
24228    },
24229
24230    /**
24231      This will set the `to` property path to the specified value. It will not
24232      attempt to resolve this property path to an actual object until you
24233      connect the binding.
24234       The binding will search for the property path starting at the root object
24235      you pass when you `connect()` the binding. It follows the same rules as
24236      `get()` - see that method for more information.
24237       @method to
24238      @param {String|Tuple} path A property path or tuple.
24239      @return {Ember.Binding} `this`
24240      @public
24241    */
24242    to: function (path) {
24243      this._to = path;
24244      return this;
24245    },
24246
24247    /**
24248      Configures the binding as one way. A one-way binding will relay changes
24249      on the `from` side to the `to` side, but not the other way around. This
24250      means that if you change the `to` side directly, the `from` side may have
24251      a different value.
24252       @method oneWay
24253      @return {Ember.Binding} `this`
24254      @public
24255    */
24256    oneWay: function () {
24257      this._oneWay = true;
24258      return this;
24259    },
24260
24261    /**
24262      @method toString
24263      @return {String} string representation of binding
24264      @public
24265    */
24266    toString: function () {
24267      var oneWay = this._oneWay ? '[oneWay]' : '';
24268      return 'Ember.Binding<' + _emberMetalUtils.guidFor(this) + '>(' + this._from + ' -> ' + this._to + ')' + oneWay;
24269    },
24270
24271    // ..........................................................
24272    // CONNECT AND SYNC
24273    //
24274
24275    /**
24276      Attempts to connect this binding instance so that it can receive and relay
24277      changes. This method will raise an exception if you have not set the
24278      from/to properties yet.
24279       @method connect
24280      @param {Object} obj The root object for this binding.
24281      @return {Ember.Binding} `this`
24282      @public
24283    */
24284    connect: function (obj) {
24285      _emberMetalDebug.assert('Must pass a valid object to Ember.Binding.connect()', !!obj);
24286
24287      var fromObj = undefined,
24288          fromPath = undefined;
24289
24290      // If the binding's "from" path could be interpreted as a global, verify
24291      // whether the path refers to a global or not by consulting `Ember.lookup`.
24292      if (_emberMetalPath_cache.isGlobalPath(this._from)) {
24293        var _name = _emberMetalPath_cache.getFirstKey(this._from);
24294        var possibleGlobal = _emberMetalCore.default.lookup[_name];
24295
24296        if (possibleGlobal) {
24297          fromObj = possibleGlobal;
24298          fromPath = _emberMetalPath_cache.getTailPath(this._from);
24299        }
24300      }
24301
24302      if (fromObj === undefined) {
24303        fromObj = obj;
24304        fromPath = this._from;
24305      }
24306
24307      _emberMetalProperty_set.trySet(obj, this._to, _emberMetalProperty_get.get(fromObj, fromPath));
24308
24309      // Add an observer on the object to be notified when the binding should be updated.
24310      _emberMetalObserver.addObserver(fromObj, fromPath, this, 'fromDidChange');
24311
24312      // If the binding is a two-way binding, also set up an observer on the target.
24313      if (!this._oneWay) {
24314        _emberMetalObserver.addObserver(obj, this._to, this, 'toDidChange');
24315      }
24316
24317      _emberMetalEvents.addListener(obj, 'willDestroy', this, 'disconnect');
24318
24319      this._readyToSync = true;
24320      this._fromObj = fromObj;
24321      this._fromPath = fromPath;
24322      this._toObj = obj;
24323
24324      return this;
24325    },
24326
24327    /**
24328      Disconnects the binding instance. Changes will no longer be relayed. You
24329      will not usually need to call this method.
24330       @method disconnect
24331      @return {Ember.Binding} `this`
24332      @public
24333    */
24334    disconnect: function () {
24335      _emberMetalDebug.assert('Must pass a valid object to Ember.Binding.disconnect()', !!this._toObj);
24336
24337      // Remove an observer on the object so we're no longer notified of
24338      // changes that should update bindings.
24339      _emberMetalObserver.removeObserver(this._fromObj, this._fromPath, this, 'fromDidChange');
24340
24341      // If the binding is two-way, remove the observer from the target as well.
24342      if (!this._oneWay) {
24343        _emberMetalObserver.removeObserver(this._toObj, this._to, this, 'toDidChange');
24344      }
24345
24346      this._readyToSync = false; // Disable scheduled syncs...
24347      return this;
24348    },
24349
24350    // ..........................................................
24351    // PRIVATE
24352    //
24353
24354    /* Called when the from side changes. */
24355    fromDidChange: function (target) {
24356      this._scheduleSync('fwd');
24357    },
24358
24359    /* Called when the to side changes. */
24360    toDidChange: function (target) {
24361      this._scheduleSync('back');
24362    },
24363
24364    _scheduleSync: function (dir) {
24365      var existingDir = this._direction;
24366
24367      // If we haven't scheduled the binding yet, schedule it.
24368      if (existingDir === undefined) {
24369        _emberMetalRun_loop.default.schedule('sync', this, '_sync');
24370        this._direction = dir;
24371      }
24372
24373      // If both a 'back' and 'fwd' sync have been scheduled on the same object,
24374      // default to a 'fwd' sync so that it remains deterministic.
24375      if (existingDir === 'back' && dir === 'fwd') {
24376        this._direction = 'fwd';
24377      }
24378    },
24379
24380    _sync: function () {
24381      var log = _emberMetalCore.default.LOG_BINDINGS;
24382
24383      var toObj = this._toObj;
24384
24385      // Don't synchronize destroyed objects or disconnected bindings.
24386      if (toObj.isDestroyed || !this._readyToSync) {
24387        return;
24388      }
24389
24390      // Get the direction of the binding for the object we are
24391      // synchronizing from.
24392      var direction = this._direction;
24393
24394      var fromObj = this._fromObj;
24395      var fromPath = this._fromPath;
24396
24397      this._direction = undefined;
24398
24399      // If we're synchronizing from the remote object...
24400      if (direction === 'fwd') {
24401        var fromValue = _emberMetalProperty_get.get(fromObj, fromPath);
24402        if (log) {
24403          _emberMetalLogger.default.log(' ', this.toString(), '->', fromValue, fromObj);
24404        }
24405        if (this._oneWay) {
24406          _emberMetalProperty_set.trySet(toObj, this._to, fromValue);
24407        } else {
24408          _emberMetalObserver._suspendObserver(toObj, this._to, this, 'toDidChange', function () {
24409            _emberMetalProperty_set.trySet(toObj, this._to, fromValue);
24410          });
24411        }
24412        // If we're synchronizing *to* the remote object.
24413      } else if (direction === 'back') {
24414          var toValue = _emberMetalProperty_get.get(toObj, this._to);
24415          if (log) {
24416            _emberMetalLogger.default.log(' ', this.toString(), '<-', toValue, toObj);
24417          }
24418          _emberMetalObserver._suspendObserver(fromObj, fromPath, this, 'fromDidChange', function () {
24419            _emberMetalProperty_set.trySet(fromObj, fromPath, toValue);
24420          });
24421        }
24422    }
24423
24424  };
24425
24426  function mixinProperties(to, from) {
24427    for (var key in from) {
24428      if (from.hasOwnProperty(key)) {
24429        to[key] = from[key];
24430      }
24431    }
24432  }
24433
24434  mixinProperties(Binding, {
24435
24436    /*
24437      See `Ember.Binding.from`.
24438       @method from
24439      @static
24440    */
24441    from: function (from) {
24442      var C = this;
24443      return new C(undefined, from);
24444    },
24445
24446    /*
24447      See `Ember.Binding.to`.
24448       @method to
24449      @static
24450    */
24451    to: function (to) {
24452      var C = this;
24453      return new C(to, undefined);
24454    }
24455  });
24456  /**
24457    An `Ember.Binding` connects the properties of two objects so that whenever
24458    the value of one property changes, the other property will be changed also.
24459  
24460    ## Automatic Creation of Bindings with `/^*Binding/`-named Properties.
24461  
24462    You do not usually create Binding objects directly but instead describe
24463    bindings in your class or object definition using automatic binding
24464    detection.
24465  
24466    Properties ending in a `Binding` suffix will be converted to `Ember.Binding`
24467    instances. The value of this property should be a string representing a path
24468    to another object or a custom binding instance created using Binding helpers
24469    (see "One Way Bindings"):
24470  
24471    ```
24472    valueBinding: "MyApp.someController.title"
24473    ```
24474  
24475    This will create a binding from `MyApp.someController.title` to the `value`
24476    property of your object instance automatically. Now the two values will be
24477    kept in sync.
24478  
24479    ## One Way Bindings
24480  
24481    One especially useful binding customization you can use is the `oneWay()`
24482    helper. This helper tells Ember that you are only interested in
24483    receiving changes on the object you are binding from. For example, if you
24484    are binding to a preference and you want to be notified if the preference
24485    has changed, but your object will not be changing the preference itself, you
24486    could do:
24487  
24488    ```
24489    bigTitlesBinding: Ember.Binding.oneWay("MyApp.preferencesController.bigTitles")
24490    ```
24491  
24492    This way if the value of `MyApp.preferencesController.bigTitles` changes the
24493    `bigTitles` property of your object will change also. However, if you
24494    change the value of your `bigTitles` property, it will not update the
24495    `preferencesController`.
24496  
24497    One way bindings are almost twice as fast to setup and twice as fast to
24498    execute because the binding only has to worry about changes to one side.
24499  
24500    You should consider using one way bindings anytime you have an object that
24501    may be created frequently and you do not intend to change a property; only
24502    to monitor it for changes (such as in the example above).
24503  
24504    ## Adding Bindings Manually
24505  
24506    All of the examples above show you how to configure a custom binding, but the
24507    result of these customizations will be a binding template, not a fully active
24508    Binding instance. The binding will actually become active only when you
24509    instantiate the object the binding belongs to. It is useful, however, to
24510    understand what actually happens when the binding is activated.
24511  
24512    For a binding to function it must have at least a `from` property and a `to`
24513    property. The `from` property path points to the object/key that you want to
24514    bind from while the `to` path points to the object/key you want to bind to.
24515  
24516    When you define a custom binding, you are usually describing the property
24517    you want to bind from (such as `MyApp.someController.value` in the examples
24518    above). When your object is created, it will automatically assign the value
24519    you want to bind `to` based on the name of your binding key. In the
24520    examples above, during init, Ember objects will effectively call
24521    something like this on your binding:
24522  
24523    ```javascript
24524    binding = Ember.Binding.from("valueBinding").to("value");
24525    ```
24526  
24527    This creates a new binding instance based on the template you provide, and
24528    sets the to path to the `value` property of the new object. Now that the
24529    binding is fully configured with a `from` and a `to`, it simply needs to be
24530    connected to become active. This is done through the `connect()` method:
24531  
24532    ```javascript
24533    binding.connect(this);
24534    ```
24535  
24536    Note that when you connect a binding you pass the object you want it to be
24537    connected to. This object will be used as the root for both the from and
24538    to side of the binding when inspecting relative paths. This allows the
24539    binding to be automatically inherited by subclassed objects as well.
24540  
24541    This also allows you to bind between objects using the paths you declare in
24542    `from` and `to`:
24543  
24544    ```javascript
24545    // Example 1
24546    binding = Ember.Binding.from("App.someObject.value").to("value");
24547    binding.connect(this);
24548  
24549    // Example 2
24550    binding = Ember.Binding.from("parentView.value").to("App.someObject.value");
24551    binding.connect(this);
24552    ```
24553  
24554    Now that the binding is connected, it will observe both the from and to side
24555    and relay changes.
24556  
24557    If you ever needed to do so (you almost never will, but it is useful to
24558    understand this anyway), you could manually create an active binding by
24559    using the `Ember.bind()` helper method. (This is the same method used by
24560    to setup your bindings on objects):
24561  
24562    ```javascript
24563    Ember.bind(MyApp.anotherObject, "value", "MyApp.someController.value");
24564    ```
24565  
24566    Both of these code fragments have the same effect as doing the most friendly
24567    form of binding creation like so:
24568  
24569    ```javascript
24570    MyApp.anotherObject = Ember.Object.create({
24571      valueBinding: "MyApp.someController.value",
24572  
24573      // OTHER CODE FOR THIS OBJECT...
24574    });
24575    ```
24576  
24577    Ember's built in binding creation method makes it easy to automatically
24578    create bindings for you. You should always use the highest-level APIs
24579    available, even if you understand how it works underneath.
24580  
24581    @class Binding
24582    @namespace Ember
24583    @since Ember 0.9
24584    @public
24585  */
24586  // Ember.Binding = Binding; ES6TODO: where to put this?
24587
24588  /**
24589    Global helper method to create a new binding. Just pass the root object
24590    along with a `to` and `from` path to create and connect the binding.
24591  
24592    @method bind
24593    @for Ember
24594    @param {Object} obj The root object of the transform.
24595    @param {String} to The path to the 'to' side of the binding.
24596      Must be relative to obj.
24597    @param {String} from The path to the 'from' side of the binding.
24598      Must be relative to obj or a global path.
24599    @return {Ember.Binding} binding instance
24600    @public
24601  */
24602
24603  function bind(obj, to, from) {
24604    return new Binding(to, from).connect(obj);
24605  }
24606
24607  exports.Binding = Binding;
24608});
24609// Ember.LOG_BINDINGS
24610enifed('ember-metal/cache', ['exports', 'ember-metal/empty_object'], function (exports, _emberMetalEmpty_object) {
24611  'use strict';
24612
24613  exports.default = Cache;
24614
24615  function Cache(limit, func) {
24616    this.store = new _emberMetalEmpty_object.default();
24617    this.size = 0;
24618    this.misses = 0;
24619    this.hits = 0;
24620    this.limit = limit;
24621    this.func = func;
24622  }
24623
24624  var UNDEFINED = function () {};
24625
24626  Cache.prototype = {
24627    set: function (key, value) {
24628      if (this.limit > this.size) {
24629        this.size++;
24630        if (value === undefined) {
24631          this.store[key] = UNDEFINED;
24632        } else {
24633          this.store[key] = value;
24634        }
24635      }
24636
24637      return value;
24638    },
24639
24640    get: function (key) {
24641      var value = this.store[key];
24642
24643      if (value === undefined) {
24644        this.misses++;
24645        value = this.set(key, this.func(key));
24646      } else if (value === UNDEFINED) {
24647        this.hits++;
24648        value = undefined;
24649      } else {
24650        this.hits++;
24651        // nothing to translate
24652      }
24653
24654      return value;
24655    },
24656
24657    purge: function () {
24658      this.store = new _emberMetalEmpty_object.default();
24659      this.size = 0;
24660      this.hits = 0;
24661      this.misses = 0;
24662    }
24663  };
24664});
24665enifed('ember-metal/chains', ['exports', 'ember-metal/property_get', 'ember-metal/meta', 'ember-metal/watch_key', 'ember-metal/empty_object'], function (exports, _emberMetalProperty_get, _emberMetalMeta, _emberMetalWatch_key, _emberMetalEmpty_object) {
24666  'use strict';
24667
24668  exports.finishChains = finishChains;
24669
24670  var FIRST_KEY = /^([^\.]+)/;
24671
24672  function firstKey(path) {
24673    return path.match(FIRST_KEY)[0];
24674  }
24675
24676  function isObject(obj) {
24677    return obj && typeof obj === 'object';
24678  }
24679
24680  function isVolatile(obj) {
24681    return !(isObject(obj) && obj.isDescriptor && obj._volatile === false);
24682  }
24683
24684  function ChainWatchers() {
24685    // chain nodes that reference a key in this obj by key
24686    // we only create ChainWatchers when we are going to add them
24687    // so create this upfront
24688    this.chains = new _emberMetalEmpty_object.default();
24689  }
24690
24691  ChainWatchers.prototype = {
24692    add: function (key, node) {
24693      var nodes = this.chains[key];
24694      if (nodes === undefined) {
24695        this.chains[key] = [node];
24696      } else {
24697        nodes.push(node);
24698      }
24699    },
24700
24701    remove: function (key, node) {
24702      var nodes = this.chains[key];
24703      if (nodes) {
24704        for (var i = 0, l = nodes.length; i < l; i++) {
24705          if (nodes[i] === node) {
24706            nodes.splice(i, 1);
24707            break;
24708          }
24709        }
24710      }
24711    },
24712
24713    has: function (key, node) {
24714      var nodes = this.chains[key];
24715      if (nodes) {
24716        for (var i = 0, l = nodes.length; i < l; i++) {
24717          if (nodes[i] === node) {
24718            return true;
24719          }
24720        }
24721      }
24722      return false;
24723    },
24724
24725    revalidateAll: function () {
24726      for (var key in this.chains) {
24727        this.notify(key, true, undefined);
24728      }
24729    },
24730
24731    revalidate: function (key) {
24732      this.notify(key, true, undefined);
24733    },
24734
24735    // key: the string key that is part of a path changed
24736    // revalidate: boolean; the chains that are watching this value should revalidate
24737    // callback: function that will be called with the object and path that
24738    //           will be/are invalidated by this key change, depending on
24739    //           whether the revalidate flag is passed
24740    notify: function (key, revalidate, callback) {
24741      var nodes = this.chains[key];
24742      if (nodes === undefined || nodes.length === 0) {
24743        return;
24744      }
24745
24746      var affected = undefined;
24747
24748      if (callback) {
24749        affected = [];
24750      }
24751
24752      for (var i = 0, l = nodes.length; i < l; i++) {
24753        nodes[i].notify(revalidate, affected);
24754      }
24755
24756      if (callback === undefined) {
24757        return;
24758      }
24759
24760      // we gather callbacks so we don't notify them during revalidation
24761      for (var i = 0, l = affected.length; i < l; i += 2) {
24762        var obj = affected[i];
24763        var path = affected[i + 1];
24764        callback(obj, path);
24765      }
24766    }
24767  };
24768
24769  function makeChainWatcher() {
24770    return new ChainWatchers();
24771  }
24772
24773  function addChainWatcher(obj, keyName, node) {
24774    if (!isObject(obj)) {
24775      return;
24776    }
24777
24778    var m = _emberMetalMeta.meta(obj);
24779    m.writableChainWatchers(makeChainWatcher).add(keyName, node);
24780    _emberMetalWatch_key.watchKey(obj, keyName, m);
24781  }
24782
24783  function removeChainWatcher(obj, keyName, node) {
24784    if (!isObject(obj)) {
24785      return;
24786    }
24787
24788    var m = _emberMetalMeta.peekMeta(obj);
24789
24790    if (!m || !m.readableChainWatchers()) {
24791      return;
24792    }
24793
24794    // make meta writable
24795    m = _emberMetalMeta.meta(obj);
24796
24797    m.readableChainWatchers().remove(keyName, node);
24798
24799    _emberMetalWatch_key.unwatchKey(obj, keyName, m);
24800  }
24801
24802  // A ChainNode watches a single key on an object. If you provide a starting
24803  // value for the key then the node won't actually watch it. For a root node
24804  // pass null for parent and key and object for value.
24805  function ChainNode(parent, key, value) {
24806    this._parent = parent;
24807    this._key = key;
24808
24809    // _watching is true when calling get(this._parent, this._key) will
24810    // return the value of this node.
24811    //
24812    // It is false for the root of a chain (because we have no parent)
24813    // and for global paths (because the parent node is the object with
24814    // the observer on it)
24815    this._watching = value === undefined;
24816
24817    this._chains = undefined;
24818    this._object = undefined;
24819    this.count = 0;
24820
24821    this._value = value;
24822    this._paths = {};
24823    if (this._watching) {
24824      this._object = parent.value();
24825      if (this._object) {
24826        addChainWatcher(this._object, this._key, this);
24827      }
24828    }
24829  }
24830
24831  function lazyGet(obj, key) {
24832    if (!obj) {
24833      return;
24834    }
24835
24836    var meta = _emberMetalMeta.peekMeta(obj);
24837
24838    // check if object meant only to be a prototype
24839    if (meta && meta.proto === obj) {
24840      return;
24841    }
24842
24843    // Use `get` if the return value is an EachProxy or an uncacheable value.
24844    if (isVolatile(obj[key])) {
24845      return _emberMetalProperty_get.get(obj, key);
24846      // Otherwise attempt to get the cached value of the computed property
24847    } else {
24848        var cache = meta.readableCache();
24849        if (cache && key in cache) {
24850          return cache[key];
24851        }
24852      }
24853  }
24854
24855  ChainNode.prototype = {
24856    value: function () {
24857      if (this._value === undefined && this._watching) {
24858        var obj = this._parent.value();
24859        this._value = lazyGet(obj, this._key);
24860      }
24861      return this._value;
24862    },
24863
24864    destroy: function () {
24865      if (this._watching) {
24866        var obj = this._object;
24867        if (obj) {
24868          removeChainWatcher(obj, this._key, this);
24869        }
24870        this._watching = false; // so future calls do nothing
24871      }
24872    },
24873
24874    // copies a top level object only
24875    copy: function (obj) {
24876      var ret = new ChainNode(null, null, obj);
24877      var paths = this._paths;
24878      var path;
24879
24880      for (path in paths) {
24881        // this check will also catch non-number vals.
24882        if (paths[path] <= 0) {
24883          continue;
24884        }
24885        ret.add(path);
24886      }
24887      return ret;
24888    },
24889
24890    // called on the root node of a chain to setup watchers on the specified
24891    // path.
24892    add: function (path) {
24893      var paths = this._paths;
24894      paths[path] = (paths[path] || 0) + 1;
24895
24896      var key = firstKey(path);
24897      var tail = path.slice(key.length + 1);
24898
24899      this.chain(key, tail);
24900    },
24901
24902    // called on the root node of a chain to teardown watcher on the specified
24903    // path
24904    remove: function (path) {
24905      var paths = this._paths;
24906      if (paths[path] > 0) {
24907        paths[path]--;
24908      }
24909
24910      var key = firstKey(path);
24911      var tail = path.slice(key.length + 1);
24912
24913      this.unchain(key, tail);
24914    },
24915
24916    chain: function (key, path) {
24917      var chains = this._chains;
24918      var node;
24919      if (chains === undefined) {
24920        chains = this._chains = new _emberMetalEmpty_object.default();
24921      } else {
24922        node = chains[key];
24923      }
24924
24925      if (node === undefined) {
24926        node = chains[key] = new ChainNode(this, key, undefined);
24927      }
24928
24929      node.count++; // count chains...
24930
24931      // chain rest of path if there is one
24932      if (path) {
24933        key = firstKey(path);
24934        path = path.slice(key.length + 1);
24935        node.chain(key, path);
24936      }
24937    },
24938
24939    unchain: function (key, path) {
24940      var chains = this._chains;
24941      var node = chains[key];
24942
24943      // unchain rest of path first...
24944      if (path && path.length > 1) {
24945        var nextKey = firstKey(path);
24946        var nextPath = path.slice(nextKey.length + 1);
24947        node.unchain(nextKey, nextPath);
24948      }
24949
24950      // delete node if needed.
24951      node.count--;
24952      if (node.count <= 0) {
24953        chains[node._key] = undefined;
24954        node.destroy();
24955      }
24956    },
24957
24958    notify: function (revalidate, affected) {
24959      if (revalidate && this._watching) {
24960        var obj = this._parent.value();
24961        if (obj !== this._object) {
24962          removeChainWatcher(this._object, this._key, this);
24963          this._object = obj;
24964          addChainWatcher(obj, this._key, this);
24965        }
24966        this._value = undefined;
24967      }
24968
24969      // then notify chains...
24970      var chains = this._chains;
24971      var node;
24972      if (chains) {
24973        for (var key in chains) {
24974          node = chains[key];
24975          if (node !== undefined) {
24976            node.notify(revalidate, affected);
24977          }
24978        }
24979      }
24980
24981      if (affected && this._parent) {
24982        this._parent.populateAffected(this._key, 1, affected);
24983      }
24984    },
24985
24986    populateAffected: function (path, depth, affected) {
24987      if (this._key) {
24988        path = this._key + '.' + path;
24989      }
24990
24991      if (this._parent) {
24992        this._parent.populateAffected(path, depth + 1, affected);
24993      } else {
24994        if (depth > 1) {
24995          affected.push(this.value(), path);
24996        }
24997      }
24998    }
24999  };
25000
25001  function finishChains(obj) {
25002    // We only create meta if we really have to
25003    var m = _emberMetalMeta.peekMeta(obj);
25004    if (m) {
25005      m = _emberMetalMeta.meta(obj);
25006
25007      // finish any current chains node watchers that reference obj
25008      var chainWatchers = m.readableChainWatchers();
25009      if (chainWatchers) {
25010        chainWatchers.revalidateAll();
25011      }
25012      // ensure that if we have inherited any chains they have been
25013      // copied onto our own meta.
25014      if (m.readableChains()) {
25015        m.writableChains();
25016      }
25017    }
25018  }
25019
25020  exports.removeChainWatcher = removeChainWatcher;
25021  exports.ChainNode = ChainNode;
25022});
25023enifed('ember-metal/computed', ['exports', 'ember-metal/debug', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/expand_properties', 'ember-metal/error', 'ember-metal/properties', 'ember-metal/property_events', 'ember-metal/dependent_keys'], function (exports, _emberMetalDebug, _emberMetalProperty_set, _emberMetalUtils, _emberMetalMeta, _emberMetalExpand_properties, _emberMetalError, _emberMetalProperties, _emberMetalProperty_events, _emberMetalDependent_keys) {
25024  'use strict';
25025
25026  exports.default = computed;
25027
25028  /**
25029  @module ember
25030  @submodule ember-metal
25031  */
25032
25033  function UNDEFINED() {}
25034
25035  var DEEP_EACH_REGEX = /\.@each\.[^.]+\./;
25036
25037  /**
25038    A computed property transforms an object literal with object's accessor function(s) into a property.
25039  
25040    By default the function backing the computed property will only be called
25041    once and the result will be cached. You can specify various properties
25042    that your computed property depends on. This will force the cached
25043    result to be recomputed if the dependencies are modified.
25044  
25045    In the following example we declare a computed property - `fullName` - by calling
25046    `.Ember.computed()` with property dependencies (`firstName` and `lastName`) as leading arguments and getter accessor function. The `fullName` getter function
25047    will be called once (regardless of how many times it is accessed) as long
25048    as its dependencies have not changed. Once `firstName` or `lastName` are updated
25049    any future calls (or anything bound) to `fullName` will incorporate the new
25050    values.
25051  
25052    ```javascript
25053    let Person = Ember.Object.extend({
25054      // these will be supplied by `create`
25055      firstName: null,
25056      lastName: null,
25057  
25058      fullName: Ember.computed('firstName', 'lastName', function() {
25059        let firstName = this.get('firstName'),
25060            lastName  = this.get('lastName');
25061  
25062        return firstName + ' ' + lastName;
25063      })
25064    });
25065  
25066    let tom = Person.create({
25067      firstName: 'Tom',
25068      lastName: 'Dale'
25069    });
25070  
25071    tom.get('fullName') // 'Tom Dale'
25072    ```
25073  
25074    You can also define what Ember should do when setting a computed property by providing additional function (`set`) in hash argument.
25075    If you try to set a computed property, it will try to invoke setter accessor function with the key and
25076    value you want to set it to as arguments.
25077  
25078    ```javascript
25079    let Person = Ember.Object.extend({
25080      // these will be supplied by `create`
25081      firstName: null,
25082      lastName: null,
25083  
25084      fullName: Ember.computed('firstName', 'lastName', {
25085        get(key) {
25086          let firstName = this.get('firstName'),
25087              lastName  = this.get('lastName');
25088  
25089          return firstName + ' ' + lastName;
25090        },
25091        set(key, value) {
25092          let [firstName, lastName] = value.split(' ');
25093  
25094          this.set('firstName', firstName);
25095          this.set('lastName', lastName);
25096  
25097          return value;
25098        }
25099      })
25100    });
25101  
25102    let person = Person.create();
25103  
25104    person.set('fullName', 'Peter Wagenet');
25105    person.get('firstName'); // 'Peter'
25106    person.get('lastName');  // 'Wagenet'
25107    ```
25108  
25109    You can overwrite computed property with normal property (no longer computed), that won't 
25109change if dependencies change, if you set computed property and it won't have setter accessor function defined.
25110  
25111    You can also mark computed property as `.readOnly()` and block all attempts to set it.
25112  
25113    ```javascript
25114    let Person = Ember.Object.extend({
25115      // these will be supplied by `create`
25116      firstName: null,
25117      lastName: null,
25118  
25119      fullName: Ember.computed('firstName', 'lastName', {
25120        get(key) {
25121          let firstName = this.get('firstName');
25122          let lastName  = this.get('lastName');
25123  
25124          return firstName + ' ' + lastName;
25125        }
25126      }).readOnly()
25127    });
25128  
25129    let person = Person.create();
25130    person.set('fullName', 'Peter Wagenet'); // Uncaught Error: Cannot set read-only property "fullName" on object: <(...):emberXXX>
25131    ```
25132  
25133    Additional resources:
25134    - [New CP syntax RFC](https://github.com/emberjs/rfcs/blob/master/text/0011-improved-cp-syntax.md)
25135    - [New computed syntax explained in "Ember 1.12 released" ](http://emberjs.com/blog/2015/05/13/ember-1-12-released.html#toc_new-computed-syntax)
25136  
25137    @class ComputedProperty
25138    @namespace Ember
25139    @public
25140  */
25141  function ComputedProperty(config, opts) {
25142    this.isDescriptor = true;
25143    if (typeof config === 'function') {
25144      this._getter = config;
25145    } else {
25146      _emberMetalDebug.assert('Ember.computed expects a function or an object as last argument.', typeof config === 'object' && !Array.isArray(config));
25147      _emberMetalDebug.assert('Config object pased to a Ember.computed can only contain `get` or `set` keys.', (function () {
25148        var keys = Object.keys(config);
25149        for (var i = 0; i < keys.length; i++) {
25150          if (keys[i] !== 'get' && keys[i] !== 'set') {
25151            return false;
25152          }
25153        }
25154        return true;
25155      })());
25156      this._getter = config.get;
25157      this._setter = config.set;
25158    }
25159    _emberMetalDebug.assert('Computed properties must receive a getter or a setter, you passed none.', !!this._getter || !!this._setter);
25160    this._dependentKeys = undefined;
25161    this._suspended = undefined;
25162    this._meta = undefined;
25163    this._volatile = false;
25164    this._dependentKeys = opts && opts.dependentKeys;
25165    this._readOnly = false;
25166  }
25167
25168  ComputedProperty.prototype = new _emberMetalProperties.Descriptor();
25169
25170  var ComputedPropertyPrototype = ComputedProperty.prototype;
25171
25172  /**
25173    Call on a computed property to set it into non-cached mode. When in this
25174    mode the computed property will not automatically cache the return value.
25175  
25176    It also does not automatically fire any change events. You must manually notify
25177    any changes if you want to observe this property.
25178  
25179    Dependency keys have no effect on volatile properties as they are for cache
25180    invalidation and notification when cached value is invalidated.
25181  
25182    ```javascript
25183    let outsideService = Ember.Object.extend({
25184      value: Ember.computed(function() {
25185        return OutsideService.getValue();
25186      }).volatile()
25187    }).create();
25188    ```
25189  
25190    @method volatile
25191    @return {Ember.ComputedProperty} this
25192    @chainable
25193    @public
25194  */
25195  ComputedPropertyPrototype.volatile = function () {
25196    this._volatile = true;
25197    return this;
25198  };
25199
25200  /**
25201    Call on a computed property to set it into read-only mode. When in this
25202    mode the computed property will throw an error when set.
25203  
25204    ```javascript
25205    let Person = Ember.Object.extend({
25206      guid: Ember.computed(function() {
25207        return 'guid-guid-guid';
25208      }).readOnly()
25209    });
25210  
25211    let person = Person.create();
25212  
25213    person.set('guid', 'new-guid'); // will throw an exception
25214    ```
25215  
25216    @method readOnly
25217    @return {Ember.ComputedProperty} this
25218    @chainable
25219    @public
25220  */
25221  ComputedPropertyPrototype.readOnly = function () {
25222    this._readOnly = true;
25223    _emberMetalDebug.assert('Computed properties that define a setter using the new syntax cannot be read-only', !(this._readOnly && this._setter && this._setter !== this._getter));
25224    return this;
25225  };
25226
25227  /**
25228    Sets the dependent keys on this computed property. Pass any number of
25229    arguments containing key paths that this computed property depen
25229ds on.
25230  
25231    ```javascript
25232    let President = Ember.Object.extend({
25233      fullName: Ember.computed(function() {
25234        return this.get('firstName') + ' ' + this.get('lastName');
25235  
25236        // Tell Ember that this computed property depends on firstName
25237        // and lastName
25238      }).property('firstName', 'lastName')
25239    });
25240  
25241    let president = President.create({
25242      firstName: 'Barack',
25243      lastName: 'Obama'
25244    });
25245  
25246    president.get('fullName'); // 'Barack Obama'
25247    ```
25248  
25249    @method property
25250    @param {String} path* zero or more property paths
25251    @return {Ember.ComputedProperty} this
25252    @chainable
25253    @public
25254  */
25255  ComputedPropertyPrototype.property = function () {
25256    var args;
25257
25258    var addArg = function (property) {
25259      _emberMetalDebug.warn('Dependent keys containing @each only work one level deep. ' + 'You cannot use nested forms like [email protected] or [email protected][email protected]. ' + 'Please create an intermediary computed property.', DEEP_EACH_REGEX.test(property) === false, { id: 'ember-metal.computed-deep-each' });
25260      args.push(property);
25261    };
25262
25263    args = [];
25264    for (var i = 0, l = arguments.length; i < l; i++) {
25265      _emberMetalExpand_properties.default(arguments[i], addArg);
25266    }
25267
25268    this._dependentKeys = args;
25269    return this;
25270  };
25271
25272  /**
25273    In some cases, you may want to annotate computed properties with additional
25274    metadata about how they function or what values they operate on. For example,
25275    computed property functions may close over variables that are then no longer
25276    available for introspection.
25277  
25278    You can pass a hash of these values to a computed property like this:
25279  
25280    ```
25281    person: Ember.computed(function() {
25282      let personId = this.get('personId');
25283      return App.Person.create({ id: personId });
25284    }).meta({ type: App.Person })
25285    ```
25286  
25287    The hash that you pass to the `meta()` function will be saved on the
25288    computed property descriptor under the `_meta` key. Ember runtime
25289    exposes a public API for retrieving these values from classes,
25290    via the `metaForProperty()` function.
25291  
25292    @method meta
25293    @param {Object} meta
25294    @chainable
25295    @public
25296  */
25297  ComputedPropertyPrototype.meta = function (meta) {
25298    if (arguments.length === 0) {
25299      return this._meta || {};
25300    } else {
25301      this._meta = meta;
25302      return this;
25303    }
25304  };
25305
25306  // invalidate cache when CP key changes
25307  ComputedPropertyPrototype.didChange = function (obj, keyName) {
25308    // _suspended is set via a CP.set to ensure we don't clear
25309    // the cached value set by the setter
25310    if (this._volatile || this._suspended === obj) {
25311      return;
25312    }
25313
25314    // don't create objects just to invalidate
25315    var meta = _emberMetalMeta.peekMeta(obj);
25316    if (!meta || meta.source !== obj) {
25317      return;
25318    }
25319
25320    var cache = meta.readableCache();
25321    if (cache && cache[keyName] !== undefined) {
25322      cache[keyName] = undefined;
25323      _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, meta);
25324    }
25325  };
25326
25327  ComputedPropertyPrototype.get = function (obj, keyName) {
25328    if (this._volatile) {
25329      return this._getter.call(obj, keyName);
25330    }
25331
25332    var meta = _emberMetalMeta.meta(obj);
25333    var cache = meta.writableCache();
25334
25335    var result = cache[keyName];
25336    if (result === UNDEFINED) {
25337      return undefined;
25338    } else if (result !== undefined) {
25339      return result;
25340    }
25341
25342    var ret = this._getter.call(obj, keyName);
25343    if (ret === undefined) {
25344      cache[keyName] = UNDEFINED;
25345    } else {
25346      cache[keyName] = ret;
25347    }
25348
25349    var chainWatchers = meta.readableChainWatchers();
25350    if (chainWatchers) {
25351      chainWatchers.revalidate(keyName);
25352    }
25353    _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, meta);
25354
25355    return ret;
25356  };
25357
25358  ComputedPropertyPrototype.set = function computedPropertySetEntry(obj, keyName, value) {
25359    if (this._readOnly) {
25360      this._throwReadOnlyError(obj, keyName);
25361    }
25362
25363    if (!this._setter) {
25364      return this.clobberSet(obj, keyName, value);
25365    }
25366
25367    if (this._volatile) {
25368      return this.volatileSet(obj, keyName, value);
25369    }
25370
25371    return this.setWithSuspend(obj, keyName, value);
25372  };
25373
25374  ComputedPropertyPrototype._throwReadOnlyError = function computedPropertyThrowReadOnlyError(obj, keyName) {
25375    throw new _emberMetalError.default('Cannot set read-only property "' + keyName + '" on object: ' + _emberMetalUtils.inspect(obj));
25376  };
25377
25378  ComputedPropertyPrototype.clobberSet = function computedPropertyClobberSet(obj, keyName, value) {
25379    var cachedValue = cacheFor(obj, keyName);
25380    _emberMetalProperties.defineProperty(obj, keyName, null, cachedValue);
25381    _emberMetalProperty_set.set(obj, keyName, value);
25382    return value;
25383  };
25384
25385  ComputedPropertyPrototype.volatileSet = function computedPropertyVolatileSet(obj, keyName, value) {
25386    return this._setter.call(obj, keyName, value);
25387  };
25388
25389  ComputedPropertyPrototype.setWithSuspend = function computedPropertySetWithSuspend(obj, keyName, value) {
25390    var oldSuspended = this._suspended;
25391    this._suspended = obj;
25392    try {
25393      return this._set(obj, keyName, value);
25394    } finally {
25395      this._suspended = oldSuspended;
25396    }
25397  };
25398
25399  ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, value) {
25400    // cache requires own meta
25401    var meta = _emberMetalMeta.meta(obj);
25402    // either there is a writable cache or we need one to update
25403    var cache = meta.writableCache();
25404    var hadCachedValue = false;
25405    var cachedValue = undefined;
25406    if (cache[keyName] !== undefined) {
25407      if (cache[keyName] !== UNDEFINED) {
25408        cachedValue = cache[keyName];
25409      }
25410      hadCachedValue = true;
25411    }
25412
25413    var ret = this._setter.call(obj, keyName, value, cachedValue);
25414
25415    // allows setter to return the same value that is cached already
25416    if (hadCachedValue && cachedValue === ret) {
25417      return ret;
25418    }
25419
25420    var watched = meta.peekWatching(keyName);
25421    if (watched) {
25422      _emberMetalProperty_events.propertyWillChange(obj, keyName);
25423    }
25424
25425    if (hadCachedValue) {
25426      cache[keyName] = undefined;
25427    }
25428
25429    if (!hadCachedValue) {
25430      _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, meta);
25431    }
25432
25433    if (ret === undefined) {
25434      cache[keyName] = UNDEFINED;
25435    } else {
25436      cache[keyName] = ret;
25437    }
25438
25439    if (watched) {
25440      _emberMetalProperty_events.propertyDidChange(obj, keyName);
25441    }
25442
25443    return ret;
25444  };
25445
25446  /* called before property is overridden */
25447  ComputedPropertyPrototype.teardown = function (obj, keyName) {
25448    if (this._volatile) {
25449      return;
25450    }
25451    var meta = _emberMetalMeta.meta(obj);
25452    var cache = meta.readableCache();
25453    if (cache && cache[keyName] !== undefined) {
25454      _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, meta);
25455      cache[keyName] = undefined;
25456    }
25457  };
25458
25459  /**
25460    This helper returns a new property descriptor that wraps the passed
25461    computed property function. You can use this helper to define properties
25462    with mixins or via `Ember.defineProperty()`.
25463  
25464    If you pass a function as an argument, it will be used as a getter. A computed
25465    property defined in this way might look like this:
25466  
25467    ```js
25468    let Person = Ember.Object.extend({
25469      init() {
25470        this._super(...arguments);
25471  
25472        this.firstName = 'Betty';
25473        this.lastName = 'Jones';
25474      },
25475  
25476      fullName: Ember.computed('firstName', 'lastName', function() {
25477        return `${this.get('firstName')} ${this.get('lastName')}`;
25478      })
25479    });
25480  
25481    let client = Person.create();
25482  
25483    client.get('fullName'); // 'Betty Jones'
25484  
25485    client.set('lastName', 'Fuller');
25486    client.get('fullName'); // 'Betty Fuller'
25487    ```
25488  
25489    You can pass a hash with two functions, `get` and `set`, as an
25490    argument to provide both a getter and setter:
25491  
25492    ```js
25493    let Person = Ember.Object.extend({
25494      init() {
25495        this._super(...arguments);
25496  
25497        this.firstName = 'Betty';
25498        this.lastName = 'Jones';
25499      },
25500  
25501      fullName: Ember.computed('firstName', 'lastName', {
25502        get(key) {
25503          return `${this.get('firstName')} ${this.get('lastName')}`;
25504        },
25505        set(key, value) {
25506          let [firstName, lastName] = value.split(/\s+/);
25507          this.setProperties({ firstName, lastName });
25508          return value;
25509        }
25510      });
25511    })
25512  
25513    let client = Person.create();
25514    client.get('firstName'); // 'Betty'
25515  
25516    client.set('fullName', 'Carroll Fuller');
25517    client.get('firstName'); // 'Carroll'
25518    ```
25519  
25520    The `set` function should accept two parameters, `key` and `value`. The value
25521    returned from `set` will be the new value of the property.
25522  
25523    _Note: This is the preferred way to define computed properties when writing third-party
25524    libraries that depend on or use Ember, since there is no guarantee that the user
25525    will have [prototype Extensions](http://emberjs.com/guides/configuring-ember/disabling-prototype-extensions/) enabled._
25526  
25527    The alternative syntax, with prototype extensions, might look like:
25528  
25529    ```js
25530    fullName() {
25531      return this.get('firstName') + ' ' + this.get('lastName');
25532    }.property('firstName', 'lastName')
25533    ```
25534  
25535    @class computed
25536    @namespace Ember
25537    @constructor
25538    @static
25539    @param {String} [dependentKeys*] Optional dependent keys that trigger this computed property.
25540    @param {Function} func The computed property function.
25541    @return {Ember.ComputedProperty} property descriptor instance
25542    @public
25543  */
25544
25545  function computed(func) {
25546    var args;
25547
25548    if (arguments.length > 1) {
25549      args = [].slice.call(arguments);
25550      func = args.pop();
25551    }
25552
25553    var cp = new ComputedProperty(func);
25554
25555    if (args) {
25556      cp.property.apply(cp, args);
25557    }
25558
25559    return cp;
25560  }
25561
25562  /**
25563    Returns the cached value for a property, if one exists.
25564    This can be useful for peeking at the value of a computed
25565    property that is generated lazily, without accidentally causing
25566    it to be created.
25567  
25568    @method cacheFor
25569    @for Ember
25570    @param {Object} obj the object whose property you want to check
25571    @param {String} key the name of the property whose cached value you want
25572      to return
25573    @return {Object} the cached value
25574    @public
25575  */
25576  function cacheFor(obj, key) {
25577    var meta = _emberMetalMeta.peekMeta(obj);
25578    var cache = meta && meta.source === obj && meta.readableCache();
25579    var ret = cache && cache[key];
25580
25581    if (ret === UNDEFINED) {
25582      return undefined;
25583    }
25584    return ret;
25585  }
25586
25587  cacheFor.set = function (cache, key, value) {
25588    if (value === undefined) {
25589      cache[key] = UNDEFINED;
25590    } else {
25591      cache[key] = value;
25592    }
25593  };
25594
25595  cacheFor.get = function (cache, key) {
25596    var ret = cache[key];
25597    if (ret === UNDEFINED) {
25598      return undefined;
25599    }
25600    return ret;
25601  };
25602
25603  cacheFor.remove = function (cache, key) {
25604    cache[key] = undefined;
25605  };
25606
25607  exports.ComputedProperty = ComputedProperty;
25608  exports.computed = computed;
25609  exports.cacheFor = cacheFor;
25610});
25611enifed('ember-metal/computed_macros', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/computed', 'ember-metal/is_empty', 'ember-metal/is_none', 'ember-metal/alias'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalComputed, _emberMetalIs_empty, _emberMetalIs_none, _emberMetalAlias) {
25612  'use strict';
25613
25614  exports.empty = empty;
25615  exports.notEmpty = notEmpty;
25616  exports.none = none;
25617  exports.not = not;
25618  exports.bool = bool;
25619  exports.match = match;
25620  exports.equal = equal;
25621  exports.gt = gt;
25622  exports.gte = gte;
25623  exports.lt = lt;
25624  exports.lte = lte;
25625  exports.oneWay = oneWay;
25626  exports.readOnly = readOnly;
25627  exports.deprecatingAlias = deprecatingAlias;
25628
25629  /**
25630  @module ember
25631  @submodule ember-metal
25632  */
25633
25634  function getProperties(self, propertyNames) {
25635    var ret = {};
25636    for (var i = 0; i < propertyNames.length; i++) {
25637      ret[propertyNames[i]] = _emberMetalProperty_get.get(self, propertyNames[i]);
25638    }
25639    return ret;
25640  }
25641
25642  function generateComputedWithProperties(macro) {
25643    return function () {
25644      for (var _len = arguments.length, properties = Array(_len), _key = 0; _key < _len; _key++) {
25645        properties[_key] = arguments[_key];
25646      }
25647
25648      var computedFunc = _emberMetalComputed.computed(function () {
25649        return macro.apply(this, [getProperties(this, properties)]);
25650      });
25651
25652      return computedFunc.property.apply(computedFunc, properties);
25653    };
25654  }
25655
25656  /**
25657    A computed property that returns true if the value of the dependent
25658    property is null, an empty string, empty array, or empty function.
25659  
25660    Example
25661  
25662    ```javascript
25663    var ToDoList = Ember.Object.extend({
25664      isDone: Ember.computed.empty('todos')
25665    });
25666  
25667    var todoList = ToDoList.create({
25668      todos: ['Unit Test', 'Documentation', 'Release']
25669    });
25670  
25671    todoList.get('isDone'); // false
25672    todoList.get('todos').clear();
25673    todoList.get('isDone'); // true
25674    ```
25675  
25676    @since 1.6.0
25677    @method empty
25678    @for Ember.computed
25679    @param {String} dependentKey
25680    @return {Ember.ComputedProperty} computed property which negate
25681    the original value for property
25682    @public
25683  */
25684
25685  function empty(dependentKey) {
25686    return _emberMetalComputed.computed(dependentKey + '.length', function () {
25687      return _emberMetalIs_empty.default(_emberMetalProperty_get.get(this, dependentKey));
25688    });
25689  }
25690
25691  /**
25692    A computed property that returns true if the value of the dependent
25693    property is NOT null, an empty string, empty array, or empty function.
25694  
25695    Example
25696  
25697    ```javascript
25698    var Hamster = Ember.Object.extend({
25699      hasStuff: Ember.computed.notEmpty('backpack')
25700    });
25701  
25702    var hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] });
25703  
25704    hamster.get('hasStuff');         // true
25705    hamster.get('backpack').clear(); // []
25706    hamster.get('hasStuff');         // false
25707    ```
25708  
25709    @method notEmpty
25710    @for Ember.computed
25711    @param {String} dependentKey
25712    @return {Ember.ComputedProperty} computed property which returns true if
25713    original value for property is not empty.
25714    @public
25715  */
25716
25717  function notEmpty(dependentKey) {
25718    return _emberMetalComputed.computed(dependentKey + '.length', function () {
25719      return !_emberMetalIs_empty.default(_emberMetalProperty_get.get(this, dependentKey));
25720    });
25721  }
25722
25723  /**
25724    A computed property that returns true if the value of the dependent
25725    property is null or undefined. This avoids errors from JSLint complaining
25726    about use of ==, which can be technically confusing.
25727  
25728    Example
25729  
25730    ```javascript
25731    var Hamster = Ember.Object.extend({
25732      isHungry: Ember.computed.none('food')
25733    });
25734  
25735    var hamster = Hamster.create();
25736  
25737    hamster.get('isHungry'); // true
25738    hamster.set('food', 'Banana');
25739    hamster.get('isHungry'); // false
25740    hamster.set('food', null);
25741    hamster.get('isHungry'); // true
25742    ```
25743  
25744    @method none
25745    @for Ember.computed
25746    @param {String} dependentKey
25747    @return {Ember.ComputedProperty} computed property which
25748    returns true if original value for property is null or undefined.
25749    @public
25750  */
25751
25752  function none(dependentKey) {
25753    return _emberMetalComputed.computed(dependentKey, function () {
25754      return _emberMetalIs_none.default(_emberMetalProperty_get.get(this, dependentKey));
25755    });
25756  }
25757
25758  /**
25759    A computed property that returns the inverse boolean value
25760    of the original value for the dependent property.
25761  
25762    Example
25763  
25764    ```javascript
25765    var User = Ember.Object.extend({
25766      isAnonymous: Ember.computed.not('loggedIn')
25767    });
25768  
25769    var user = User.create({loggedIn: false});
25770  
25771    user.get('isAnonymous'); // true
25772    user.set('loggedIn', true);
25773    user.get('isAnonymous'); // false
25774    ```
25775  
25776    @method not
25777    @for Ember.computed
25778    @param {String} dependentKey
25779    @return {Ember.ComputedProperty} computed property which returns
25780    inverse of the original value for property
25781    @public
25782  */
25783
25784  function not(dependentKey) {
25785    return _emberMetalComputed.computed(dependentKey, function () {
25786      return !_emberMetalProperty_get.get(this, dependentKey);
25787    });
25788  }
25789
25790  /**
25791    A computed property that converts the provided dependent property
25792    into a boolean value.
25793  
25794    ```javascript
25795    var Hamster = Ember.Object.extend({
25796      hasBananas: Ember.computed.bool('numBananas')
25797    });
25798  
25799    var hamster = Hamster.create();
25800  
25801    hamster.get('hasBananas'); // false
25802    hamster.set('numBananas', 0);
25803    hamster.get('hasBananas'); // false
25804    hamster.set('numBananas', 1);
25805    hamster.get('hasBananas'); // true
25806    hamster.set('numBananas', null);
25807    hamster.get('hasBananas'); // false
25808    ```
25809  
25810    @method bool
25811    @for Ember.computed
25812    @param {String} dependentKey
25813    @return {Ember.ComputedProperty} computed property which converts
25814    to boolean the original value for property
25815    @public
25816  */
25817
25818  function bool(dependentKey) {
25819    return _emberMetalComputed.computed(dependentKey, function () {
25820      return !!_emberMetalProperty_get.get(this, dependentKey);
25821    });
25822  }
25823
25824  /**
25825    A computed property which matches the original value for the
25826    dependent property against a given RegExp, returning `true`
25827    if the value matches the RegExp and `false` if it does not.
25828  
25829    Example
25830  
25831    ```javascript
25832    var User = Ember.Object.extend({
25833      hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/)
25834    });
25835  
25836    var user = User.create({loggedIn: false});
25837  
25838    user.get('hasValidEmail'); // false
25839    user.set('email', '');
25840    user.get('hasValidEmail'); // false
25841    user.set('email', '[email protected]');
25842    user.get('hasValidEmail'); // true
25843    ```
25844  
25845    @method match
25846    @for Ember.computed
25847    @param {String} dependentKey
25848    @param {RegExp} regexp
25849    @return {Ember.ComputedProperty} computed property which match
25850    the original value for property against a given RegExp
25851    @public
25852  */
25853
25854  function match(dependentKey, regexp) {
25855    return _emberMetalComputed.computed(dependentKey, function () {
25856      var value = _emberMetalProperty_get.get(this, dependentKey);
25857
25858      return typeof value === 'string' ? regexp.test(value) : false;
25859    });
25860  }
25861
25862  /**
25863    A computed property that returns true if the provided dependent property
25864    is equal to the given value.
25865  
25866    Example
25867  
25868    ```javascript
25869    var Hamster = Ember.Object.extend({
25870      napTime: Ember.computed.equal('state', 'sleepy')
25871    });
25872  
25873    var hamster = Hamster.create();
25874  
25875    hamster.get('napTime'); // false
25876    hamster.set('state', 'sleepy');
25877    hamster.get('napTime'); // true
25878    hamster.set('state', 'hungry');
25879    hamster.get('napTime'); // false
25880    ```
25881  
25882    @method equal
25883    @for Ember.computed
25884    @param {String} dependentKey
25885    @param {String|Number|Object} value
25886    @return {Ember.ComputedProperty} computed property which returns true if
25887    the original value for property is equal to the given value.
25888    @public
25889  */
25890
25891  function equal(dependentKey, value) {
25892    return _emberMetalComputed.computed(dependentKey, function () {
25893      return _emberMetalProperty_get.get(this, dependentKey) === value;
25894    });
25895  }
25896
25897  /**
25898    A computed property that returns true if the provided dependent property
25899    is greater than the provided value.
25900  
25901    Example
25902  
25903    ```javascript
25904    var Hamster = Ember.Object.extend({
25905      hasTooManyBananas: Ember.computed.gt('numBananas', 10)
25906    });
25907  
25908    var hamster = Hamster.create();
25909  
25910    hamster.get('hasTooManyBananas'); // false
25911    hamster.set('numBananas', 3);
25912    hamster.get('hasTooManyBananas'); // false
25913    hamster.set('numBananas', 11);
25914    hamster.get('hasTooManyBananas'); // true
25915    ```
25916  
25917    @method gt
25918    @for Ember.computed
25919    @param {String} dependentKey
25920    @param {Number} value
25921    @return {Ember.ComputedProperty} computed property which returns true if
25922    the original value for property is greater than given value.
25923    @public
25924  */
25925
25926  function gt(dependentKey, value) {
25927    return _emberMetalComputed.computed(dependentKey, function () {
25928      return _emberMetalProperty_get.get(this, dependentKey) > value;
25929    });
25930  }
25931
25932  /**
25933    A computed property that returns true if the provided dependent property
25934    is greater than or equal to the provided value.
25935  
25936    Example
25937  
25938    ```javascript
25939    var Hamster = Ember.Object.extend({
25940      hasTooManyBananas: Ember.computed.gte('numBananas', 10)
25941    });
25942  
25943    var hamster = Hamster.create();
25944  
25945    hamster.get('hasTooManyBananas'); // false
25946    hamster.set('numBananas', 3);
25947    hamster.get('hasTooManyBananas'); // false
25948    hamster.set('numBananas', 10);
25949    hamster.get('hasTooManyBananas'); // true
25950    ```
25951  
25952    @method gte
25953    @for Ember.computed
25954    @param {String} dependentKey
25955    @param {Number} value
25956    @return {Ember.ComputedProperty} computed property which returns true if
25957    the original value for property is greater or equal then given value.
25958    @public
25959  */
25960
25961  function gte(dependentKey, value) {
25962    return _emberMetalComputed.computed(dependentKey, function () {
25963      return _emberMetalProperty_get.get(this, dependentKey) >= value;
25964    });
25965  }
25966
25967  /**
25968    A computed property that returns true if the provided dependent property
25969    is less than the provided value.
25970  
25971    Example
25972  
25973    ```javascript
25974    var Hamster = Ember.Object.extend({
25975      needsMoreBananas: Ember.computed.lt('numBananas', 3)
25976    });
25977  
25978    var hamster = Hamster.create();
25979  
25980    hamster.get('needsMoreBananas'); // true
25981    hamster.set('numBananas', 3);
25982    hamster.get('needsMoreBananas'); // false
25983    hamster.set('numBananas', 2);
25984    hamster.get('needsMoreBananas'); // true
25985    ```
25986  
25987    @method lt
25988    @for Ember.computed
25989    @param {String} dependentKey
25990    @param {Number} value
25991    @return {Ember.ComputedProperty} computed property which returns true if
25992    the original value for property is less then given value.
25993    @public
25994  */
25995
25996  function lt(dependentKey, value) {
25997    return _emberMetalComputed.computed(dependentKey, function () {
25998      return _emberMetalProperty_get.get(this, dependentKey) < value;
25999    });
26000  }
26001
26002  /**
26003    A computed property that returns true if the provided dependent property
26004    is less than or equal to the provided value.
26005  
26006    Example
26007  
26008    ```javascript
26009    var Hamster = Ember.Object.extend({
26010      needsMoreBananas: Ember.computed.lte('numBananas', 3)
26011    });
26012  
26013    var hamster = Hamster.create();
26014  
26015    hamster.get('needsMoreBananas'); // true
26016    hamster.set('numBananas', 5);
26017    hamster.get('needsMoreBananas'); // false
26018    hamster.set('numBananas', 3);
26019    hamster.get('needsMoreBananas'); // true
26020    ```
26021  
26022    @method lte
26023    @for Ember.computed
26024    @param {String} dependentKey
26025    @param {Number} value
26026    @return {Ember.ComputedProperty} computed property which returns true if
26027    the original value for property is less or equal than given value.
26028    @public
26029  */
26030
26031  function lte(dependentKey, value) {
26032    return _emberMetalComputed.computed(dependentKey, function () {
26033      return _emberMetalProperty_get.get(this, dependentKey) <= value;
26034    });
26035  }
26036
26037  /**
26038    A computed property that performs a logical `and` on the
26039    original values for the provided dependent properties.
26040  
26041    Example
26042  
26043    ```javascript
26044    var Hamster = Ember.Object.extend({
26045      readyForCamp: Ember.computed.and('hasTent', 'hasBackpack')
26046    });
26047  
26048    var hamster = Hamster.create();
26049  
26050    hamster.get('readyForCamp'); // false
26051    hamster.set('hasTent', true);
26052    hamster.get('readyForCamp'); // false
26053    hamster.set('hasBackpack', true);
26054    hamster.get('readyForCamp'); // true
26055    hamster.set('hasBackpack', 'Yes');
26056    hamster.get('readyForCamp'); // 'Yes'
26057    ```
26058  
26059    @method and
26060    @for Ember.computed
26061    @param {String} dependentKey*
26062    @return {Ember.ComputedProperty} computed property which performs
26063    a logical `and` on the values of all the original values for properties.
26064    @public
26065  */
26066  var and = generateComputedWithProperties(function (properties) {
26067    var value;
26068    for (var key in properties) {
26069      value = properties[key];
26070      if (properties.hasOwnProperty(key) && !value) {
26071        return false;
26072      }
26073    }
26074    return value;
26075  });
26076
26077  exports.and = and;
26078  /**
26079    A computed property which performs a logical `or` on the
26080    original values for the provided dependent properties.
26081  
26082    Example
26083  
26084    ```javascript
26085    var Hamster = Ember.Object.extend({
26086      readyForRain: Ember.computed.or('hasJacket', 'hasUmbrella')
26087    });
26088  
26089    var hamster = Hamster.create();
26090  
26091    hamster.get('readyForRain'); // false
26092    hamster.set('hasUmbrella', true);
26093    hamster.get('readyForRain'); // true
26094    hamster.set('hasJacket', 'Yes');
26095    hamster.get('readyForRain'); // 'Yes'
26096    ```
26097  
26098    @method or
26099    @for Ember.computed
26100    @param {String} dependentKey*
26101    @return {Ember.ComputedProperty} computed property which performs
26102    a logical `or` on the values of all the original values for properties.
26103    @public
26104  */
26105  var or = generateComputedWithProperties(function (properties) {
26106    var value;
26107    for (var key in properties) {
26108      value = properties[key];
26109      if (properties.hasOwnProperty(key) && value) {
26110        return value;
26111      }
26112    }
26113    return value;
26114  });
26115
26116  exports.or = or;
26117  /**
26118    Creates a new property that is an alias for another property
26119    on an object. Calls to `get` or `set` this property behave as
26120    though they were called on the original property.
26121  
26122    ```javascript
26123    var Person = Ember.Object.extend({
26124      name: 'Alex Matchneer',
26125      nomen: Ember.computed.alias('name')
26126    });
26127  
26128    var alex = Person.create();
26129  
26130    alex.get('nomen'); // 'Alex Matchneer'
26131    alex.get('name');  // 'Alex Matchneer'
26132  
26133    alex.set('nomen', '@machty');
26134    alex.get('name');  // '@machty'
26135    ```
26136  
26137    @method alias
26138    @for Ember.computed
26139    @param {String} dependentKey
26140    @return {Ember.ComputedProperty} computed property which creates an
26141    alias to the original value for property.
26142    @public
26143  */
26144
26145  /**
26146    Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
26147    data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
26148    not mutate the upstream property, rather causes the current property to
26149    become the value set. This causes the downstream property to permanently
26150    diverge from the upstream property.
26151  
26152    Example
26153  
26154    ```javascript
26155    var User = Ember.Object.extend({
26156      firstName: null,
26157      lastName: null,
26158      nickName: Ember.computed.oneWay('firstName')
26159    });
26160  
26161    var teddy = User.create({
26162      firstName: 'Teddy',
26163      lastName:  'Zeenny'
26164    });
26165  
26166    teddy.get('nickName');              // 'Teddy'
26167    teddy.set('nickName', 'TeddyBear'); // 'TeddyBear'
26168    teddy.get('firstName');             // 'Teddy'
26169    ```
26170  
26171    @method oneWay
26172    @for Ember.computed
26173    @param {String} dependentKey
26174    @return {Ember.ComputedProperty} computed property which creates a
26175    one way computed property to the original value for property.
26176    @public
26177  */
26178
26179  function oneWay(dependentKey) {
26180    return _emberMetalAlias.default(dependentKey).oneWay();
26181  }
26182
26183  /**
26184    This is a more semantically meaningful alias of `computed.oneWay`,
26185    whose name is somewhat ambiguous as to which direction the data flows.
26186  
26187    @method reads
26188    @for Ember.computed
26189    @param {String} dependentKey
26190    @return {Ember.ComputedProperty} computed property which creates a
26191      one way computed property to the original value for property.
26192    @public
26193   */
26194
26195  /**
26196    Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides
26197    a readOnly one way binding. Very often when using `computed.oneWay` one does
26198    not also want changes to propagate back up, as they will replace the value.
26199  
26200    This prevents the reverse flow, and also throws an exception when it occurs.
26201  
26202    Example
26203  
26204    ```javascript
26205    var User = Ember.Object.extend({
26206      firstName: null,
26207      lastName: null,
26208      nickName: Ember.computed.readOnly('firstName')
26209    });
26210  
26211    var teddy = User.create({
26212      firstName: 'Teddy',
26213      lastName:  'Zeenny'
26214    });
26215  
26216    teddy.get('nickName');              // 'Teddy'
26217    teddy.set('nickName', 'TeddyBear'); // throws Exception
26218    // throw new Ember.Error('Cannot Set: nickName on: <User:ember27288>' );`
26219    teddy.get('firstName');             // 'Teddy'
26220    ```
26221  
26222    @method readOnly
26223    @for Ember.computed
26224    @param {String} dependentKey
26225    @return {Ember.ComputedProperty} computed property which creates a
26226    one way computed property to the original value for property.
26227    @since 1.5.0
26228    @public
26229  */
26230
26231  function readOnly(dependentKey) {
26232    return _emberMetalAlias.default(dependentKey).readOnly();
26233  }
26234
26235  /**
26236    Creates a new property that is an alias for another property
26237    on an object. Calls to `get` or `set` this property behave as
26238    though they were called on the original property, but also
26239    print a deprecation warning.
26240  
26241    @method deprecatingAlias
26242    @for Ember.computed
26243    @param {String} dependentKey
26244    @return {Ember.ComputedProperty} computed property which creates an
26245    alias with a deprecation to the original value for property.
26246    @since 1.7.0
26247    @public
26248  */
26249
26250  function deprecatingAlias(dependentKey, options) {
26251    return _emberMetalComputed.computed(dependentKey, {
26252      get: function (key) {
26253        _emberMetalDebug.deprecate('Usage of `' + key + '` is deprecated, use `' + depen
26253dentKey + '` instead.', false, options);
26254        return _emberMetalProperty_get.get(this, dependentKey);
26255      },
26256      set: function (key, value) {
26257        _emberMetalDebug.deprecate('Usage of `' + key + '` is deprecated, use `' + dependentKey + '` instead.', false, options);
26258        _emberMetalProperty_set.set(this, dependentKey, value);
26259        return value;
26260      }
26261    });
26262  }
26263});
26264enifed('ember-metal/core', ['exports', 'require'], function (exports, _require) {
26265  /*globals Ember:true,ENV,EmberENV */
26266
26267  'use strict';
26268
26269  /**
26270  @module ember
26271  @submodule ember-metal
26272  */
26273
26274  /**
26275    This namespace contains all Ember methods and functions. Future versions of
26276    Ember may overwrite this namespace and therefore, you should avoid adding any
26277    new properties.
26278  
26279    At the heart of Ember is Ember-Runtime, a set of core functions that provide
26280    cross-platform compatibility and object property observing.  Ember-Runtime is
26281    small and performance-focused so you can use it alongside other
26282    cross-platform libraries such as jQuery. For more details, see
26283    [Ember-Runtime](http://emberjs.com/api/modules/ember-runtime.html).
26284  
26285    @class Ember
26286    @static
26287    @version 2.5.1
26288    @public
26289  */
26290
26291  if ('undefined' === typeof Ember) {
26292    // Create core object. Make it act like an instance of Ember.Namespace so that
26293    // objects assigned to it are given a sane string representation.
26294    Ember = {};
26295  }
26296
26297  // Default imports, exports and lookup to the global object;
26298  var global = mainContext || {}; // jshint ignore:line
26299  Ember.imports = Ember.imports || global;
26300  Ember.lookup = Ember.lookup || global;
26301  var emExports = Ember.exports = Ember.exports || global;
26302
26303  // aliases needed to keep minifiers from removing the global context
26304  emExports.Em = emExports.Ember = Ember;
26305
26306  // Make sure these are set whether Ember was already defined or not
26307
26308  Ember.isNamespace = true;
26309
26310  Ember.toString = function () {
26311    return 'Ember';
26312  };
26313
26314  // The debug functions are exported to globals with `require` to
26315  // prevent babel-plugin-filter-imports from removing them.
26316  var debugModule = _require.default('ember-metal/debug');
26317  Ember.assert = debugModule.assert;
26318  Ember.warn = debugModule.warn;
26319  Ember.debug = debugModule.debug;
26320  Ember.deprecate = debugModule.deprecate;
26321  Ember.deprecateFunc = debugModule.deprecateFunc;
26322  Ember.runInDebug = debugModule.runInDebug;
26323
26324  /**
26325    The semantic version.
26326  
26327    @property VERSION
26328    @type String
26329    @default '2.5.1'
26330    @static
26331    @public
26332  */
26333  Ember.VERSION = '2.5.1';
26334
26335  /**
26336    The hash of environment variables used to control various configuration
26337    settings. To specify your own or override default settings, add the
26338    desired properties to a global hash named `EmberENV` (or `ENV` for
26339    backwards compatibility with earlier versions of Ember). The `EmberENV`
26340    hash must be created before loading Ember.
26341  
26342    @property ENV
26343    @type Object
26344    @public
26345  */
26346
26347  if (Ember.ENV) {
26348    // do nothing if Ember.ENV is already setup
26349    Ember.assert('Ember.ENV should be an object.', 'object' !== typeof Ember.ENV);
26350  } else if ('undefined' !== typeof EmberENV) {
26351    Ember.ENV = EmberENV;
26352  } else if ('undefined' !== typeof ENV) {
26353    Ember.ENV = ENV;
26354  } else {
26355    Ember.ENV = {};
26356  }
26357
26358  // ENABLE_ALL_FEATURES was documented, but you can't actually enable non optional features.
26359  if (Ember.ENV.ENABLE_ALL_FEATURES) {
26360    Ember.ENV.ENABLE_OPTIONAL_FEATURES = Ember.ENV.ENABLE_ALL_FEATURES;
26361  }
26362
26363  Ember.config = Ember.config || {};
26364
26365  // ..........................................................
26366  // BOOTSTRAP
26367  //
26368
26369  /**
26370    Determines whether Ember should add to `Array`, `Function`, and `String`
26371    native object prototypes, a few extra methods in order to provide a more
26372    friendly API.
26373  
26374    We generally recommend leaving this option set to true however, if you need
26375    to turn it off, you can add the configuration property
26376    `EXTEND_PROTOTYPES` to `EmberENV` and set it to `false`.
26377  
26378    Note, when disabled (the default configuration for Ember Addons), you will
26379    instead have to access all methods and functions from the Ember
26380    namespace.
26381  
26382    @property EXTEND_PROTOTYPES
26383    @type Boolean
26384    @default true
26385    @for Ember
26386    @public
26387  */
26388  Ember.EXTEND_PROTOTYPES = Ember.ENV.EXTEND_PROTOTYPES;
26389
26390  if (typeof Ember.EXTEND_PROTOTYPES === 'undefined') {
26391    Ember.EXTEND_PROTOTYPES = true;
26392  }
26393
26394  /**
26395    The `LOG_STACKTRACE_ON_DEPRECATION` property, when true, tells Ember to log
26396    a full stack trace during deprecation warnings.
26397  
26398    @property LOG_STACKTRACE_ON_DEPRECATION
26399    @type Boolean
26400    @default true
26401    @public
26402  */
26403  Ember.LOG_STACKTRACE_ON_DEPRECATION = Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !== false;
26404
26405  /**
26406    The `LOG_VERSION` property, when true, tells Ember to log versions of all
26407    dependent libraries in use.
26408  
26409    @property LOG_VERSION
26410    @type Boolean
26411    @default true
26412    @public
26413  */
26414  Ember.LOG_VERSION = Ember.ENV.LOG_VERSION === false ? false : true;
26415
26416  /**
26417    An empty function useful for some operations. Always returns `this`.
26418  
26419    @method K
26420    @return {Object}
26421    @public
26422  */
26423  function K() {
26424    return this;
26425  }
26426  exports.K = K;
26427
26428  Ember.K = K;
26429  //TODO: ES6 GLOBAL TODO
26430
26431  exports.default = Ember;
26432});
26433enifed("ember-metal/debug", ["exports"], function (exports) {
26434  "use strict";
26435
26436  exports.getDebugFunction = getDebugFunction;
26437  exports.setDebugFunction = setDebugFunction;
26438  exports.assert = assert;
26439  exports.info = info;
26440  exports.warn = warn;
26441  exports.debug = debug;
26442  exports.deprecate = deprecate;
26443  exports.deprecateFunc = deprecateFunc;
26444  exports.runInDebug = runInDebug;
26445  exports.debugSeal = debugSeal;
26446  var debugFunctions = {
26447    assert: function () {},
26448    info: function () {},
26449    warn: function () {},
26450    debug: function () {},
26451    deprecate: function () {},
26452    deprecateFunc: function () {
26453      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
26454        args[_key] = arguments[_key];
26455      }
26456
26457      return args[args.length - 1];
26458    },
26459    runInDebug: function () {},
26460    debugSeal: function () {}
26461  };
26462
26463  exports.debugFunctions = debugFunctions;
26464
26465  function getDebugFunction(name) {
26466    return debugFunctions[name];
26467  }
26468
26469  function setDebugFunction(name, fn) {
26470    debugFunctions[name] = fn;
26471  }
26472
26473  function assert() {
26474    return debugFunctions.assert.apply(undefined, arguments);
26475  }
26476
26477  function info() {
26478    return debugFunctions.info.apply(undefined, arguments);
26479  }
26480
26481  function warn() {
26482    return debugFunctions.warn.apply(undefined, arguments);
26483  }
26484
26485  function debug() {
26486    return debugFunctions.debug.apply(undefined, arguments);
26487  }
26488
26489  function deprecate() {
26490    return debugFunctions.deprecate.apply(undefined, arguments);
26491  }
26492
26493  function deprecateFunc() {
26494    return debugFunctions.deprecateFunc.apply(undefined, arguments);
26495  }
26496
26497  function runInDebug() {
26498    return debugFunctions.runInDebug.apply(undefined, arguments);
26499  }
26500
26501  function debugSeal() {
26502    return debugFunctions.debugSeal.apply(undefined, arguments);
26503  }
26504});
26505enifed('ember-metal/dependent_keys', ['exports', 'ember-metal/watching'], function (exports, _emberMetalWatching) {
26506  'no use strict';
26507  // Remove "use strict"; from transpiled module until
26508  // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
26509
26510  exports.addDependentKeys = addDependentKeys;
26511  exports.removeDependentKeys = removeDependentKeys;
26512
26513  /**
26514  @module ember
26515  @submodule ember-metal
26516  */
26517
26518  // ..........................................................
26519  // DEPENDENT KEYS
26520  //
26521
26522  function addDependentKeys(desc, obj, keyName, meta) {
26523    // the descriptor has a list of dependent keys, so
26524    // add all of its dependent keys.
26525    var idx, len, depKey;
26526    var depKeys = desc._dependentKeys;
26527    if (!depKeys) {
26528      return;
26529    }
26530
26531    for (idx = 0, len = depKeys.length; idx < len; idx++) {
26532      depKey = depKeys[idx];
26533      // Increment the number of times depKey depends on keyName.
26534      meta.writeDeps(depKey, keyName, (meta.peekDeps(depKey, keyName) || 0) + 1);
26535      // Watch the depKey
26536      _emberMetalWatching.watch(obj, depKey, meta);
26537    }
26538  }
26539
26540  function removeDependentKeys(desc, obj, keyName, meta) {
26541    // the descriptor has a list of dependent keys, so
26542    // remove all of its dependent keys.
26543    var depKeys = desc._dependentKeys;
26544    var idx, len, depKey;
26545    if (!depKeys) {
26546      return;
26547    }
26548
26549    for (idx = 0, len = depKeys.length; idx < len; idx++) {
26550      depKey = depKeys[idx];
26551      // Decrement the number of times depKey depends on keyName.
26552      meta.writeDeps(depKey, keyName, (meta.peekDeps(depKey, keyName) || 0) - 1);
26553      // Unwatch the depKey
26554      _emberMetalWatching.unwatch(obj, depKey, meta);
26555    }
26556  }
26557});
26558enifed('ember-metal/deprecate_property', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set) {
26559  /**
26560  @module ember
26561  @submodule ember-metal
26562  */
26563
26564  'use strict';
26565
26566  exports.deprecateProperty = deprecateProperty;
26567
26568  /**
26569    Used internally to allow changing properties in a backwards compatible way, and print a helpful
26570    deprecation warning.
26571  
26572    @method deprecateProperty
26573    @param {Object} object The object to add the deprecated property to.
26574    @param {String} deprecatedKey The property to add (and print deprecation warnings upon accessing).
26575    @param {String} newKey The property that will be aliased.
26576    @private
26577    @since 1.7.0
26578  */
26579
26580  function deprecateProperty(object, deprecatedKey, newKey, options) {
26581    function _deprecate() {
26582      _emberMetalDebug.deprecate('Usage of `' + deprecatedKey + '` is deprecated, use `' + newKey + '` instead.', false, options);
26583    }
26584
26585    Object.defineProperty(object, deprecatedKey, {
26586      configurable: true,
26587      enumerable: false,
26588      set: function (value) {
26589        _deprecate();
26590        _emberMetalProperty_set.set(this, newKey, value);
26591      },
26592      get: function () {
26593        _deprecate();
26594        return _emberMetalProperty_get.get(this, newKey);
26595      }
26596    });
26597  }
26598});
26599enifed('ember-metal/dictionary', ['exports', 'ember-metal/empty_object'], function (exports, _emberMetalEmpty_object) {
26600  'use strict';
26601
26602  exports.default = makeDictionary;
26603
26604  // the delete is meant to hint at runtimes that this object should remain in
26605  // dictionary mode. This is clearly a runtime specific hack, but currently it
26606  // appears worthwhile in some usecases. Please note, these deletes do increase
26607  // the cost of creation dramatically over a plain Object.create. And as this
26608  // only makes sense for long-lived dictionaries that aren't instantiated often.
26609
26610  function makeDictionary(parent) {
26611    var dict;
26612    if (parent === null) {
26613      dict = new _emberMetalEmpty_object.default();
26614    } else {
26615      dict = Object.create(parent);
26616    }
26617    dict['_dict'] = null;
26618    delete dict['_dict'];
26619    return dict;
26620  }
26621});
26622enifed("ember-metal/empty_object", ["exports"], function (exports) {
26623  // This exists because `Object.create(null)` is absurdly slow compared
26624  // to `new EmptyObject()`. In either case, you want a null prototype
26625  // when you're treating the object instances as arbitrary dictionaries
26626  // and don't want your keys colliding with build-in methods on the
26627  // default object prototype.
26628
26629  "use strict";
26630
26631  var proto = Object.create(null, {
26632    // without this, we will always still end up with (new
26633    // EmptyObject()).constructor === Object
26634    constructor: {
26635      value: undefined,
26636      enumerable: false,
26637      writable: true
26638    }
26639  });
26640
26641  function EmptyObject() {}
26642  EmptyObject.prototype = proto;
26643  exports.default = EmptyObject;
26644});
26645enifed('ember-metal/environment', ['exports', 'ember-metal/core'], function (exports, _emberMetalCore) {
26646  'use strict';
26647
26648  /*
26649    Ember can run in many different environments, including environments like
26650    Node.js where the DOM is unavailable. This object serves as an abstraction
26651    over the browser features that Ember relies on, so that code does not
26652    explode when trying to boot in an environment that doesn't have them.
26653  
26654    This is a private abstraction. In the future, we hope that other
26655    abstractions (like `Location`, `Renderer`, `dom-helper`) can fully abstract
26656    over the differences in environment.
26657  */
26658  var environment;
26659
26660  // This code attempts to automatically detect an environment with DOM
26661  // by searching for window and document.createElement. An environment
26662  // with DOM may disable the DOM functionality of Ember explicitly by
26663  // defining a `disableBrowserEnvironment` ENV.
26664  var hasDOM = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof document.createElement !== 'undefined' && !_emberMetalCore.default.ENV.disableBrowserEnvironment;
26665
26666  if (hasDOM) {
26667    environment = {
26668      hasDOM: true,
26669      isChrome: !!window.chrome && !window.opera,
26670      isFirefox: typeof InstallTrigger !== 'undefined',
26671      isPhantom: !!window.callPhantom,
26672      location: window.location,
26673      history: window.history,
26674      userAgent: window.navigator.userAgent,
26675      global: window
26676    };
26677  } else {
26678    environment = {
26679      hasDOM: false,
26680      isChrome: false,
26681      isFirefox: false,
26682      isPhantom: false,
26683      location: null,
26684      history: null,
26685      userAgent: 'Lynx (textmode)',
26686      global: null
26687    };
26688  }
26689
26690  exports.default = environment;
26691});
26692enifed('ember-metal/error', ['exports', 'ember-metal/core'], function (exports, _emberMetalCore) {
26693  'use strict';
26694
26695  exports.default = EmberError;
26696
26697  var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
26698
26699  /**
26700    A subclass of the JavaScript Error object for use in Ember.
26701  
26702    @class Error
26703    @namespace Ember
26704    @extends Error
26705    @constructor
26706    @public
26707  */
26708
26709  function EmberError() {
26710    var tmp = Error.apply(this, arguments);
26711
26712    // Adds a `stack` property to the given error object that will yield the
26713    // stack trace at the time captureStackTrace was called.
26714    // When collecting the stack trace all frames above the topmost call
26715    // to this function, including that call, will be left out of the
26716    // stack trace.
26717    // This is useful because we can hide Ember implementation details
26718    // that are not very helpful for the user.
26719    if (Error.captureStackTrace) {
26720      Error.captureStackTrace(this, _emberMetalCore.default.Error);
26721    }
26722    // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
26723    for (var idx = 0; idx < errorProps.length; idx++) {
26724      this[errorProps[idx]] = tmp[errorProps[idx]];
26725    }
26726  }
26727
26728  EmberError.prototype = Object.create(Error.prototype);
26729});
26730enifed('ember-metal/events', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/meta_listeners'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberMetalMeta, _emberMetalMeta_listeners) {
26731  'no use strict';
26732  // Remove "use strict"; from transpiled module until
26733  // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
26734
26735  /**
26736  @module ember
26737  @submodule ember-metal
26738  */
26739  exports.accumulateListeners = accumulateListeners;
26740  exports.addListener = addListener;
26741  exports.removeListener = removeListener;
26742  exports.suspendListener = suspendListener;
26743  exports.suspendListeners = suspendListeners;
26744  exports.watchedEvents = watchedEvents;
26745  exports.sendEvent = sendEvent;
26746  exports.hasListeners = hasListeners;
26747  exports.listenersFor = listenersFor;
26748  exports.on = on;
26749
26750  /*
26751    The event system uses a series of nested hashes to store listeners on an
26752    object. When a listener is registered, or when an event arrives, these
26753    hashes are consulted to determine which target and action pair to invoke.
26754  
26755    The hashes are stored in the object's meta hash, and look like this:
26756  
26757        // Object's meta hash
26758        {
26759          listeners: {       // variable name: `listenerSet`
26760            "foo:changed": [ // variable name: `actions`
26761              target, method, flags
26762            ]
26763          }
26764        }
26765  
26766  */
26767
26768  function indexOf(array, target, method) {
26769    var index = -1;
26770    // hashes are added to the end of the event array
26771    // so it makes sense to start searching at the end
26772    // of the array and search in reverse
26773    for (var i = array.length - 3; i >= 0; i -= 3) {
26774      if (target === array[i] && method === array[i + 1]) {
26775        index = i;
26776        break;
26777      }
26778    }
26779    return index;
26780  }
26781
26782  function accumulateListeners(obj, eventName, otherActions) {
26783    var meta = _emberMetalMeta.peekMeta(obj);
26784    if (!meta) {
26785      return;
26786    }
26787    var actions = meta.matchingListeners(eventName);
26788    var newActions = [];
26789
26790    for (var i = actions.length - 3; i >= 0; i -= 3) {
26791      var target = actions[i];
26792      var method = actions[i + 1];
26793      var flags = actions[i + 2];
26794      var actionIndex = indexOf(otherActions, target, method);
26795
26796      if (actionIndex === -1) {
26797        otherActions.push(target, method, flags);
26798        newActions.push(target, method, flags);
26799      }
26800    }
26801
26802    return newActions;
26803  }
26804
26805  /**
26806    Add an event listener
26807  
26808    @method addListener
26809    @for Ember
26810    @param obj
26811    @param {String} eventName
26812    @param {Object|Function} target A target object or a function
26813    @param {Function|String} method A function or the name of a function to be called on `target`
26814    @param {Boolean} once A flag whether a function should only be called once
26815    @public
26816  */
26817
26818  function addListener(obj, eventName, target, method, once) {
26819    _emberMetalDebug.assert('You must pass at least an object and event name to Ember.addListener', !!obj && !!eventName);
26820
26821    if (!method && 'function' === typeof target) {
26822      method = target;
26823      target = null;
26824    }
26825
26826    var flags = 0;
26827    if (once) {
26828      flags |= _emberMetalMeta_listeners.ONCE;
26829    }
26830
26831    _emberMetalMeta.meta(obj).addToListeners(eventName, target, method, flags);
26832
26833    if ('function' === typeof obj.didAddListener) {
26834      obj.didAddListener(eventName, target, method);
26835    }
26836  }
26837
26838  /**
26839    Remove an event listener
26840  
26841    Arguments should match those passed to `Ember.addListener`.
26842  
26843    @method removeListener
26844    @for Ember
26845    @param obj
26846    @param {String} eventName
26847    @param {Object|Function} target A target object or a function
26848    @param {Function|String} method A function or the name of a function to be called on `target`
26849    @public
26850  */
26851
26852  function removeListener(obj, eventName, target, method) {
26853    _emberMetalDebug.assert('You must pass at least an object and event name to Ember.removeListener', !!obj && !!eventName);
26854
26855    if (!method && 'function' === typeof target) {
26856      method = target;
26857      target = null;
26858    }
26859
26860    _emberMetalMeta.meta(obj).removeFromListeners(eventName, target, method, function () {
26861      if ('function' === typeof obj.didRemoveListener) {
26862        obj.didRemoveListener.apply(obj, arguments);
26863      }
26864    });
26865  }
26866
26867  /**
26868    Suspend listener during callback.
26869  
26870    This should only be used by the target of the event listener
26871    when it is taking an action that would cause the event, e.g.
26872    an object might suspend its property change listener while it is
26873    setting that property.
26874  
26875    @method suspendListener
26876    @for Ember
26877  
26878    @private
26879    @param obj
26880    @param {String} eventName
26881    @param {Object|Function} target A target object or a function
26882    @param {Function|String} method A function or the name of a function to be called on `target`
26883    @param {Function} callback
26884  */
26885
26886  function suspendListener(obj, eventName, target, method, callback) {
26887    return suspendListeners(obj, [eventName], target, method, callback);
26888  }
26889
26890  /**
26891    Suspends multiple listeners during a callback.
26892  
26893    @method suspendListeners
26894    @for Ember
26895  
26896    @private
26897    @param obj
26898    @param {Array} eventNames Array of event names
26899    @param {Object|Function} target A target object or a function
26900    @param {Function|String} method A function or the name of a function to be called on `target`
26901    @param {Function} callback
26902  */
26903
26904  function suspendListeners(obj, eventNames, target, method, callback) {
26905    if (!method && 'function' === typeof target) {
26906      method = target;
26907      target = null;
26908    }
26909    return _emberMetalMeta.meta(obj).suspendListeners(eventNames, target, method, callback);
26910  }
26911
26912  /**
26913    Return a list of currently watched events
26914  
26915    @private
26916    @method watchedEvents
26917    @for Ember
26918    @param obj
26919  */
26920
26921  function watchedEvents(obj) {
26922    return _emberMetalMeta.meta(obj).watchedEvents();
26923  }
26924
26925  /**
26926    Send an event. The execution of suspended listeners
26927    is skipped, and once listeners are removed. A listener without
26928    a target is executed on the passed object. If an array of actions
26929    is not passed, the actions stored on the passed object are invoked.
26930  
26931    @method sendEvent
26932    @for Ember
26933    @param obj
26934    @param {String} eventName
26935    @param {Array} params Optional parameters for each listener.
26936    @param {Array} actions Optional array of actions (listeners).
26937    @return true
26938    @public
26939  */
26940
26941  function sendEvent(obj, eventName, params, actions) {
26942    if (!actions) {
26943      var meta = _emberMetalMeta.peekMeta(obj);
26944      actions = meta && meta.matchingListeners(eventName);
26945    }
26946
26947    if (!actions || actions.length === 0) {
26948      return;
26949    }
26950
26951    for (var i = actions.length - 3; i >= 0; i -= 3) {
26952      // looping in reverse for once listeners
26953      var target = actions[i];
26954      var method = actions[i + 1];
26955      var flags = actions[i + 2];
26956
26957      if (!method) {
26958        continue;
26959      }
26960      if (flags & _emberMetalMeta_listeners.SUSPENDED) {
26961        continue;
26962      }
26963      if (flags & _emberMetalMeta_listeners.ONCE) {
26964        removeListener(obj, eventName, target, method);
26965      }
26966      if (!target) {
26967        target = obj;
26968      }
26969      if ('string' === typeof method) {
26970        if (params) {
26971          _emberMetalUtils.applyStr(target, method, params);
26972        } else {
26973          target[method]();
26974        }
26975      } else {
26976        if (params) {
26977          _emberMetalUtils.apply(target, method, params);
26978        } else {
26979          method.call(target);
26980        }
26981      }
26982    }
26983    return true;
26984  }
26985
26986  /**
26987    @private
26988    @method hasListeners
26989    @for Ember
26990    @param obj
26991    @param {String} eventName
26992  */
26993
26994  function hasListeners(obj, eventName) {
26995    var meta = _emberMetalMeta.peekMeta(obj);
26996    if (!meta) {
26997      return false;
26998    }
26999    return meta.matchingListeners(eventName).length > 0;
27000  }
27001
27002  /**
27003    @private
27004    @method listenersFor
27005    @for Ember
27006    @param obj
27007    @param {String} eventName
27008  */
27009
27010  function listenersFor(obj, eventName) {
27011    var ret = [];
27012    var meta = _emberMetalMeta.peekMeta(obj);
27013    var actions = meta && meta.matchingListeners(eventName);
27014
27015    if (!actions) {
27016      return ret;
27017    }
27018
27019    for (var i = 0, l = actions.length; i < l; i += 3) {
27020      var target = actions[i];
27021      var method = actions[i + 1];
27022      ret.push([target, method]);
27023    }
27024
27025    return ret;
27026  }
27027
27028  /**
27029    Define a property as a function that should be executed when
27030    a specified event or events are triggered.
27031  
27032  
27033    ``` javascript
27034    var Job = Ember.Object.extend({
27035      logCompleted: Ember.on('completed', function() {
27036        console.log('Job completed!');
27037      })
27038    });
27039  
27040    var job = Job.create();
27041  
27042    Ember.sendEvent(job, 'completed'); // Logs 'Job completed!'
27043   ```
27044  
27045    @method on
27046    @for Ember
27047    @param {String} eventNames*
27048    @param {Function} func
27049    @return func
27050    @public
27051  */
27052
27053  function on() {
27054    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
27055      args[_key] = arguments[_key];
27056    }
27057
27058    var func = args.pop();
27059    var events = args;
27060    func.__ember_listens__ = events;
27061    return func;
27062  }
27063});
27064enifed('ember-metal/expand_properties', ['exports', 'ember-metal/debug'], function (exports, _emberMetalDebug) {
27065  'use strict';
27066
27067  exports.default = expandProperties;
27068
27069  /**
27070  @module ember
27071  @submodule ember-metal
27072  */
27073
27074  var SPLIT_REGEX = /\{|\}/;
27075  var END_WITH_EACH_REGEX = /\.@each$/;
27076
27077  /**
27078    Expands `pattern`, invoking `callback` for each expansion.
27079  
27080    The only pattern supported is brace-expansion, anything else will be passed
27081    once to `callback` directly.
27082  
27083    Example
27084  
27085    ```js
27086    function echo(arg){ console.log(arg); }
27087  
27088    Ember.expandProperties('foo.bar', echo);              //=> 'foo.bar'
27089    Ember.expandProperties('{foo,bar}', echo);            //=> 'foo', 'bar'
27090    Ember.expandProperties('foo.{bar,baz}', echo);        //=> 'foo.bar', 'foo.baz'
27091    Ember.expandProperties('{foo,bar}.baz', echo);        //=> 'foo.baz', 'bar.baz'
27092    Ember.expandProperties('foo.{bar,baz}.[]', echo)      //=> 'foo.bar.[]', 'foo.baz.[]'
27093    Ember.expandProperties('{foo,bar}.{spam,eggs}', echo) //=> 'foo.spam', 'foo.eggs', 'bar.spam', 'bar.eggs'
27094    Ember.expandProperties('{foo}.bar.{baz}')             //=> 'foo.bar.baz'
27095    ```
27096  
27097    @method expandProperties
27098    @for Ember
27099    @private
27100    @param {String} pattern The property pattern to expand.
27101    @param {Function} callback The callback to invoke.  It is invoked once per
27102    expansion, and is passed the expansion.
27103  */
27104
27105  function expandProperties(pattern, callback) {
27106    _emberMetalDebug.assert('A computed property key must be a string', typeof pattern === 'string');
27107    _emberMetalDebug.assert('Brace expanded properties cannot contain spaces, e.g. "user.{firstName, lastName}" should be "user.{firstName,lastName}"', pattern.indexOf(' ') === -1);
27108
27109    var parts = pattern.split(SPLIT_REGEX);
27110    var properties = [parts];
27111
27112    for (var i = 0; i < parts.length; i++) {
27113      var part = parts[i];
27114      if (part.indexOf(',') >= 0) {
27115        properties = duplicateAndReplace(properties, part.split(','), i);
27116      }
27117    }
27118
27119    for (var i = 0; i < properties.length; i++) {
27120      callback(properties[i].join('').replace(END_WITH_EACH_REGEX, '.[]'));
27121    }
27122  }
27123
27124  function duplicateAndReplace(properties, currentParts, index) {
27125    var all = [];
27126
27127    properties.forEach(function (property) {
27128      currentParts.forEach(function (part) {
27129        var current = property.slice(0);
27130        current[index] = part;
27131        all.push(current);
27132      });
27133    });
27134
27135    return all;
27136  }
27137});
27138enifed('ember-metal/features', ['exports', 'ember-metal/core', 'ember-metal/assign'], function (exports, _emberMetalCore, _emberMetalAssign) {
27139  'use strict';
27140
27141  exports.default = isEnabled;
27142
27143  /**
27144    The hash of enabled Canary features. Add to this, any canary features
27145    before creating your application.
27146  
27147    Alternatively (and recommended), you can also define `EmberENV.FEATURES`
27148    if you need to enable features flagged at runtime.
27149  
27150    @class FEATURES
27151    @namespace Ember
27152    @static
27153    @since 1.1.0
27154    @public
27155  */
27156  var KNOWN_FEATURES = {};exports.KNOWN_FEATURES = KNOWN_FEATURES;
27157  // jshint ignore:line
27158  var FEATURES = _emberMetalAssign.default(KNOWN_FEATURES, _emberMetalCore.default.ENV.FEATURES);
27159
27160  exports.FEATURES = FEATURES;
27161  /**
27162    Determine whether the specified `feature` is enabled. Used by Ember's
27163    build tools to exclude experimental features from beta/stable builds.
27164  
27165    You can define the following configuration options:
27166  
27167    * `EmberENV.ENABLE_OPTIONAL_FEATURES` - enable any features that have not been explicitly
27168      enabled/disabled.
27169  
27170    @method isEnabled
27171    @param {String} feature The feature to check
27172    @return {Boolean}
27173    @for Ember.FEATURES
27174    @since 1.1.0
27175    @public
27176  */
27177
27178  function isEnabled(feature) {
27179    var featureValue = FEATURES[feature];
27180
27181    if (featureValue === true || featureValue === false || featureValue === undefined) {
27182      return featureValue;
27183    } else if (_emberMetalCore.default.ENV.ENABLE_OPTIONAL_FEATURES) {
27184      return true;
27185    } else {
27186      return false;
27187    }
27188  }
27189});
27190enifed('ember-metal/get_properties', ['exports', 'ember-metal/property_get'], function (exports, _emberMetalProperty_get) {
27191  'use strict';
27192
27193  exports.default = getProperties;
27194
27195  /**
27196    To get multiple properties at once, call `Ember.getProperties`
27197    with an object followed by a list of strings or an array:
27198  
27199    ```javascript
27200    Ember.getProperties(record, 'firstName', 'lastName', 'zipCode');
27201    // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
27202    ```
27203  
27204    is equivalent to:
27205  
27206    ```javascript
27207    Ember.getProperties(record, ['firstName', 'lastName', 'zipCode']);
27208    // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
27209    ```
27210  
27211    @method getProperties
27212    @for Ember
27213    @param {Object} obj
27214    @param {String...|Array} list of keys to get
27215    @return {Object}
27216    @public
27217  */
27218
27219  function getProperties(obj) {
27220    var ret = {};
27221    var propertyNames = arguments;
27222    var i = 1;
27223
27224    if (arguments.length === 2 && Array.isArray(arguments[1])) {
27225      i = 0;
27226      propertyNames = arguments[1];
27227    }
27228    for (var len = propertyNames.length; i < len; i++) {
27229      ret[propertyNames[i]] = _emberMetalProperty_get.get(obj, propertyNames[i]);
27230    }
27231    return ret;
27232  }
27233});
27234enifed('ember-metal/index', ['exports', 'require', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/assign', 'ember-metal/merge', 'ember-metal/instrumentation', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/error', 'ember-metal/cache', 'ember-metal/logger', 'ember-metal/property_get', 'ember-metal/events', 'ember-metal/observer_set', 'ember-metal/property_events', 'ember-metal/properties', 'ember-metal/property_set', 'ember-metal/map', 'ember-metal/get_properties', 'ember-metal/set_properties', 'ember-metal/watch_key', 'ember-metal/chains', 'ember-metal/watch_path', 'ember-metal/watching', 'ember-metal/expand_properties', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/computed_macros', 'ember-metal/observer', 'ember-metal/mixin', 'ember-metal/binding', 'ember-metal/path_cache', 'ember-metal/run_loop', 'ember-metal/libraries', 'ember-metal/is_none', 'ember-metal/is_empty', 'ember-metal/is_blank', 'ember-metal/is_present', 'backburner'], function (exports, _require, _emberMetalCore, _emberMetalDebug, _emberMetalFeatures, _emberMetalAssign, _emberMetalMerge, _emberMetalInstrumentation, _emberMetalUtils, _emberMetalMeta, _emberMetalError, _emberMetalCache, _emberMetalLogger, _emberMetalProperty_get, _emberMetalEvents, _emberMetalObserver_set, _emberMetalProperty_events, _emberMetalProperties, _emberMetalProperty_set, _emberMetalMap, _emberMetalGet_properties, _emberMetalSet_properties, _emberMetalWatch_key, _emberMetalChains, _emberMetalWatch_path, _emberMetalWatching, _emberMetalExpand_properties, _emberMetalComputed, _emberMetalAlias, _emberMetalComputed_macros, _emberMetalObserver, _emberMetalMixin, _emberMetalBinding, _emberMetalPath_cache, _emberMetalRun_loop, _emberMetalLibraries, _emberMetalIs_none, _emberMetalIs_empty, _emberMetalIs_blank, _emberMetalIs_present, _backburner) {
27235  /**
27236  @module ember
27237  @submodule ember-metal
27238  */
27239
27240  // BEGIN IMPORTS
27241  'use strict';
27242
27243  _emberMetalComputed.computed.empty = _emberMetalComputed_macros.empty;
27244  _emberMetalComputed.computed.notEmpty = _emberMetalComputed_macros.notEmpty;
27245  _emberMetalComputed.computed.none = _emberMetalComputed_macros.none;
27246  _emberMetalComputed.computed.not = _emberMetalComputed_macros.not;
27247  _emberMetalComputed.computed.bool = _emberMetalComputed_macros.bool;
27248  _emberMetalComputed.computed.match = _emberMetalComputed_macros.match;
27249  _emberMetalComputed.computed.equal = _emberMetalComputed_macros.equal;
27250  _emberMetalComputed.computed.gt = _emberMetalComputed_macros.gt;
27251  _emberMetalComputed.computed.gte = _emberMetalComputed_macros.gte;
27252  _emberMetalComputed.computed.lt = _emberMetalComputed_macros.lt;
27253  _emberMetalComputed.computed.lte = _emberMetalComputed_macros.lte;
27254  _emberMetalComputed.computed.alias = _emberMetalAlias.default;
27255  _emberMetalComputed.computed.oneWay = _emberMetalComputed_macros.oneWay;
27256  _emberMetalComputed.computed.reads = _emberMetalComputed_macros.oneWay;
27257  _emberMetalComputed.computed.readOnly = _emberMetalComputed_macros.readOnly;
27258  _emberMetalComputed.computed.defaultTo = _emberMetalComputed_macros.defaultTo;
27259  _emberMetalComputed.computed.deprecatingAlias = _emberMetalComputed_macros.deprecatingAlias;
27260  _emberMetalComputed.computed.and = _emberMetalComputed_macros.and;
27261  _emberMetalComputed.computed.or = _emberMetalComputed_macros.or;
27262  _emberMetalComputed.computed.any = _emberMetalComputed_macros.any;
27263
27264  // END IMPORTS
27265
27266  // BEGIN EXPORTS
27267  var EmberInstrumentation = _emberMetalCore.default.Instrumentation = {};
27268  EmberInstrumentation.instrument = _emberMetalInstrumentation.instrument;
27269  EmberInstrumentation.subscribe = _emberMetalInstrumentation.subscribe;
27270  EmberInstrumentation.unsubscribe = _emberMetalInstrumentation.unsubscribe;
27271  EmberInstrumentation.reset = _emberMetalInstrumentation.reset;
27272
27273  _emberMetalCore.default.instrument = _emberMetalInstrumentation.instrument;
27274  _emberMetalCore.default.subscribe = _emberMetalInstrumentation.subscribe;
27275
27276  _emberMetalCore.default._Cache = _emberMetalCache.default;
27277
27278  _emberMetalCore.default.generateGuid = _emberMetalUtils.generateGuid;
27279  _emberMetalCore.default.GUID_KEY = _emberMetalUtils.GUID_KEY;
27280  _emberMetalCore.default.platform = {
27281    defineProperty: true,
27282    hasPropertyAccessors: true
27283  };
27284
27285  _emberMetalCore.default.Error = _emberMetalError.default;
27286  _emberMetalCore.default.guidFor = _emberMetalUtils.guidFor;
27287  _emberMetalCore.default.META_DESC = _emberMetalMeta.META_DESC;
27288  _emberMetalCore.default.meta = _emberMetalMeta.meta;
27289  _emberMetalCore.default.inspect = _emberMetalUtils.inspect;
27290
27291  _emberMetalCore.default.tryCatchFinally = _emberMetalUtils.deprecatedTryCatchFinally;
27292  _emberMetalCore.default.makeArray = _emberMetalUtils.makeArray;
27293  _emberMetalCore.default.canInvoke = _emberMetalUtils.canInvoke;
27294  _emberMetalCore.default.tryInvoke = _emberMetalUtils.tryInvoke;
27295  _emberMetalCore.default.wrap = _emberMetalUtils.wrap;
27296  _emberMetalCore.default.apply = _emberMetalUtils.apply;
27297  _emberMetalCore.default.applyStr = _emberMetalUtils.applyStr;
27298  _emberMetalCore.default.uuid = _emberMetalUtils.uuid;
27299
27300  _emberMetalCore.default.Logger = _emberMetalLogger.default;
27301
27302  _emberMetalCore.default.get = _emberMetalProperty_get.get;
27303  _emberMetalCore.default.getWithDefault = _emberMetalProperty_get.getWithDefault;
27304  _emberMetalCore.default._getPath = _emberMetalProperty_get._getPath;
27305
27306  _emberMetalCore.default.on = _emberMetalEvents.on;
27307  _emberMetalCore.default.addListener = _emberMetalEvents.addListener;
27308  _emberMetalCore.default.removeListener = _emberMetalEvents.removeListener;
27309  _emberMetalCore.default._suspendListener = _emberMetalEvents.suspendListener;
27310  _emberMetalCore.default._suspendListeners = _emberMetalEvents.suspendListeners;
27311  _emberMetalCore.default.sendEvent = _emberMetalEvents.sendEvent;
27312  _emberMetalCore.default.hasListeners = _emberMetalEvents.hasListeners;
27313  _emberMetalCore.default.watchedEvents = _emberMetalEvents.watchedEvents;
27314  _emberMetalCore.default.listenersFor = _emberMetalEvents.listenersFor;
27315  _emberMetalCore.default.accumulateListeners = _emberMetalEvents.accumulateListeners;
27316
27317  _emberMetalCore.default._ObserverSet = _emberMetalObserver_set.default;
27318
27319  _emberMetalCore.default.propertyWillChange = _emberMetalProperty_events.propertyWillChange;
27320  _emberMetalCore.default.propertyDidChange = _emberMetalProperty_events.propertyDidChange;
27321  _emberMetalCore.default.overrideChains = _emberMetalProperty_events.overrideChains;
27322  _emberMetalCore.default.beginPropertyChanges = _emberMetalProperty_events.beginPropertyChanges;
27323  _emberMetalCore.default.endPropertyChanges = _emberMetalProperty_events.endPropertyChanges;
27324  _emberMetalCore.default.changeProperties = _emberMetalProperty_events.changeProperties;
27325
27326  _emberMetalCore.default.defineProperty = _emberMetalProperties.defineProperty;
27327
27328  _emberMetalCore.default.set = _emberMetalProperty_set.set;
27329  _emberMetalCore.default.trySet = _emberMetalProperty_set.trySet;
27330
27331  _emberMetalCore.default.OrderedSet = _emberMetalMap.OrderedSet;
27332  _emberMetalCore.default.Map = _emberMetalMap.Map;
27333  _emberMetalCore.default.MapWithDefault = _emberMetalMap.MapWithDefault;
27334
27335  _emberMetalCore.default.getProperties = _emberMetalGet_properties.default;
27336  _emberMetalCore.default.setProperties = _emberMetalSet_properties.default;
27337
27338  _emberMetalCore.default.watchKey = _emberMetalWatch_key.watchKey;
27339  _emberMetalCore.default.unwatchKey = _emberMetalWatch_key.unwatchKey;
27340
27341  _emberMetalCore.default.removeChainWatcher = _emberMetalChains.removeChainWatcher;
27342  _emberMetalCore.default._ChainNode = _emberMetalChains.ChainNode;
27343  _emberMetalCore.default.finishChains = _emberMetalChains.finishChains;
27344
27345  _emberMetalCore.default.watchPath = _emberMetalWatch_path.watchPath;
27346  _emberMetalCore.default.unwatchPath = _emberMetalWatch_path.unwatchPath;
27347
27348  _emberMetalCore.default.watch = _emberMetalWatching.watch;
27349  _emberMetalCore.default.isWatching = _emberMetalWatching.isWatching;
27350  _emberMetalCore.default.unwatch = _emberMetalWatching.unwatch;
27351  _emberMetalCore.default.rewatch = _emberMetalWatching.rewatch;
27352  _emberMetalCore.default.destroy = _emberMetalWatching.destroy;
27353
27354  _emberMetalCore.default.expandProperties = _emberMetalExpand_properties.default;
27355
27356  _emberMetalCore.default.ComputedProperty = _emberMetalComputed.ComputedProperty;
27357  _emberMetalCore.default.computed = _emberMetalComputed.computed;
27358  _emberMetalCore.default.cacheFor = _emberMetalComputed.cacheFor;
27359
27360  _emberMetalCore.default.addObserver = _emberMetalObserver.addObserver;
27361  _emberMetalCore.default.observersFor = _emberMetalObserver.observersFor;
27362  _emberMetalCore.default.removeObserver = _emberMetalObserver.removeObserver;
27363  _emberMetalCore.default._suspendObserver = _emberMetalObserver._suspendObserver;
27364  _emberMetalCore.default._suspendObservers = _emberMetalObserver._suspendObservers;
27365
27366  _emberMetalCore.default.IS_BINDING = _emberMetalMixin.IS_BINDING;
27367  _emberMetalCore.default.required = _emberMetalMixin.required;
27368  _emberMetalCore.default.aliasMethod = _emberMetalMixin.aliasMethod;
27369  _emberMetalCore.default.observer = _emberMetalMixin.observer;
27370  _emberMetalCore.default.immediateObserver = _emberMetalMixin._immediateObserver;
27371  _emberMetalCore.default.mixin = _emberMetalMixin.mixin;
27372  _emberMetalCore.default.Mixin = _emberMetalMixin.Mixin;
27373
27374  _emberMetalCore.default.bind = _emberMetalBinding.bind;
27375  _emberMetalCore.default.Binding = _emberMetalBinding.Binding;
27376  _emberMetalCore.default.isGlobalPath = _emberMetalPath_cache.isGlobalPath;
27377
27378  _emberMetalCore.default.run = _emberMetalRun_loop.default;
27379
27380  /**
27381  @class Backburner
27382  @for Ember
27383  @private
27384  */
27385  _emberMetalCore.default.Backburner = _backburner.default;
27386  // this is the new go forward, once Ember Data updates to using `_Backburner` we
27387  // can remove the non-underscored version.
27388  _emberMetalCore.default._Backburner = _backburner.default;
27389
27390  _emberMetalCore.default.libraries = new _emberMetalLibraries.default();
27391  _emberMetalCore.default.libraries.registerCoreLibrary('Ember', _emberMetalCore.default.VERSION);
27392
27393  _emberMetalCore.default.isNone = _emberMetalIs_none.default;
27394  _emberMetalCore.default.isEmpty = _emberMetalIs_empty.default;
27395  _emberMetalCore.default.isBlank = _emberMetalIs_blank.default;
27396  _emberMetalCore.default.isPresent = _emberMetalIs_present.default;
27397
27398  _emberMetalCore.default.assign = Object.assign || _emberMetalAssign.default;
27399  _emberMetalCore.default.merge = _emberMetalMerge.default;
27400
27401  _emberMetalCore.default.FEATURES = _emberMetalFeatures.FEATURES;
27402  _emberMetalCore.default.FEATURES.isEnabled = _emberMetalFeatures.default;
27403
27404  /**
27405    A function may be assigned to `Ember.onerror` to be called when Ember
27406    internals encounter an error. This is useful for specialized error handling
27407    and reporting code.
27408  
27409    ```javascript
27410    Ember.onerror = function(error) {
27411      Em.$.ajax('/report-error', 'POST', {
27412        stack: error.stack,
27413        otherInformation: 'whatever app state you want to provide'
27414      });
27415    };
27416    ```
27417  
27418    Internally, `Ember.onerror` is used as Backburner's error handler.
27419  
27420    @event onerror
27421    @for Ember
27422    @param {Exception} error the error object
27423    @public
27424  */
27425  _emberMetalCore.default.onerror = null;
27426  // END EXPORTS
27427
27428  // do this for side-effects of updating Ember.assert, warn, etc when
27429  // ember-debug is present
27430  // This needs to be called before any deprecateFunc
27431  if (_require.has('ember-debug')) {
27432    _require.default('ember-debug');
27433  } else {
27434    _emberMetalCore.default.Debug = {};
27435
27436    _emberMetalCore.default.Debug.registerDeprecationHandler = function () {};
27437    _emberMetalCore.default.Debug.registerWarnHandler = function () {};
27438  }
27439
27440  _emberMetalCore.default.create = _emberMetalDebug.deprecateFunc('Ember.create is deprecated in favor of Object.create', { id: 'ember-metal.ember-create', until: '3.0.0' }, Object.create);
27441  _emberMetalCore.default.keys = _emberMetalDebug.deprecateFunc('Ember.keys is deprecated in favor of Object.keys', { id: 'ember-metal.ember.keys', until: '3.0.0' }, Object.keys);
27442
27443  exports.default = _emberMetalCore.default;
27444});
27445enifed('ember-metal/injected_property', ['exports', 'ember-metal/debug', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/properties', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalComputed, _emberMetalAlias, _emberMetalProperties, _containerOwner) {
27446  'use strict';
27447
27448  /**
27449    Read-only property that returns the result of a container lookup.
27450  
27451    @class InjectedProperty
27452    @namespace Ember
27453    @constructor
27454    @param {String} type The container type the property will lookup
27455    @param {String} name (optional) The name the property will lookup, defaults
27456           to the property's name
27457    @private
27458  */
27459  function InjectedProperty(type, name) {
27460    this.type = type;
27461    this.name = name;
27462
27463    this._super$Constructor(injectedPropertyGet);
27464    AliasedPropertyPrototype.oneWay.call(this);
27465  }
27466
27467  function injectedPropertyGet(keyName) {
27468    var desc = this[keyName];
27469    var owner = _containerOwner.getOwner(this) || this.container; // fallback to `container` for backwards compat
27470
27471    _emberMetalDebug.assert('InjectedProperties should be defined with the Ember.inject computed property macros.', desc && desc.isDescriptor && desc.type);
27472    _emberMetalDebug.assert('Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container.', owner);
27473
27474    return owner.lookup(desc.type + ':' + (desc.name || keyName));
27475  }
27476
27477  InjectedProperty.prototype = Object.create(_emberMetalProperties.Descriptor.prototype);
27478
27479  var InjectedPropertyPrototype = InjectedProperty.prototype;
27480  var ComputedPropertyPrototype = _emberMetalComputed.ComputedProperty.prototype;
27481  var AliasedPropertyPrototype = _emberMetalAlias.AliasedProperty.prototype;
27482
27483  InjectedPropertyPrototype._super$Constructor = _emberMetalComputed.ComputedProperty;
27484
27485  InjectedPropertyPrototype.get = ComputedPropertyPrototype.get;
27486  InjectedPropertyPrototype.readOnly = ComputedPropertyPrototype.readOnly;
27487
27488  InjectedPropertyPrototype.teardown = ComputedPropertyPrototype.teardown;
27489
27490  exports.default = InjectedProperty;
27491});
27492enifed('ember-metal/instrumentation', ['exports', 'ember-metal/core'], function (exports, _emberMetalCore) {
27493  'use strict';
27494
27495  exports.instrument = instrument;
27496  exports._instrumentStart = _instrumentStart;
27497  exports.subscribe = subscribe;
27498  exports.unsubscribe = unsubscribe;
27499  exports.reset = reset;
27500
27501  /**
27502    The purpose of the Ember Instrumentation module is
27503    to provide efficient, general-purpose instrumentation
27504    for Ember.
27505  
27506    Subscribe to a listener by using `Ember.subscribe`:
27507  
27508    ```javascript
27509    Ember.subscribe("render", {
27510      before: function(name, timestamp, payload) {
27511  
27512      },
27513  
27514      after: function(name, timestamp, payload) {
27515  
27516      }
27517    });
27518    ```
27519  
27520    If you return a value from the `before` callback, that same
27521    value will be passed as a fourth parameter to the `after`
27522    callback.
27523  
27524    Instrument a block of code by using `Ember.instrument`:
27525  
27526    ```javascript
27527    Ember.instrument("render.handlebars", payload, function() {
27528      // rendering logic
27529    }, binding);
27530    ```
27531  
27532    Event names passed to `Ember.instrument` are namespaced
27533    by periods, from more general to more specific. Subscribers
27534    can listen for events by whatever level of granularity they
27535    are interested in.
27536  
27537    In the above example, the event is `render.handlebars`,
27538    and the subscriber listened for all events beginning with
27539    `render`. It would receive callbacks for events named
27540    `render`, `render.handlebars`, `render.container`, or
27541    even `render.handlebars.layout`.
27542  
27543    @class Instrumentation
27544    @namespace Ember
27545    @static
27546    @private
27547  */
27548  var subscribers = [];
27549  exports.subscribers = subscribers;
27550  var cache = {};
27551
27552  var populateListeners = function (name) {
27553    var listeners = [];
27554    var subscriber;
27555
27556    for (var i = 0, l = subscribers.length; i < l; i++) {
27557      subscriber = subscribers[i];
27558      if (subscriber.regex.test(name)) {
27559        listeners.push(subscriber.object);
27560      }
27561    }
27562
27563    cache[name] = listeners;
27564    return listeners;
27565  };
27566
27567  var time = (function () {
27568    var perf = 'undefined' !== typeof window ? window.performance || {} : {};
27569    var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
27570    // fn.bind will be available in all the browsers that support the advanced window.performance... ;-)
27571    return fn ? fn.bind(perf) : function () {
27572      return +new Date();
27573    };
27574  })();
27575
27576  /**
27577    Notifies event's subscribers, calls `before` and `after` hooks.
27578  
27579    @method instrument
27580    @namespace Ember.Instrumentation
27581  
27582    @param {String} [name] Namespaced event name.
27583    @param {Object} _payload
27584    @param {Function} callback Function that you're instrumenting.
27585    @param {Object} binding Context that instrument function is called with.
27586    @private
27587  */
27588
27589  function instrument(name, _payload, callback, binding) {
27590    if (arguments.length <= 3 && typeof _payload === 'function') {
27591      binding = callback;
27592      callback = _payload;
27593      _payload = undefined;
27594    }
27595    if (subscribers.length === 0) {
27596      return callback.call(binding);
27597    }
27598    var payload = _payload || {};
27599    var finalizer = _instrumentStart(name, function () {
27600      return payload;
27601    });
27602
27603    if (finalizer) {
27604      return withFinalizer(callback, finalizer, payload, binding);
27605    } else {
27606      return callback.call(binding);
27607    }
27608  }
27609
27610  function withFinalizer(callback, finalizer, payload, binding) {
27611    try {
27612      return callback.call(binding);
27613    } catch (e) {
27614      payload.exception = e;
27615      return payload;
27616    } finally {
27617      return finalizer();
27618    }
27619  }
27620
27621  // private for now
27622
27623  function _instrumentStart(name, _payload) {
27624    var listeners = cache[name];
27625
27626    if (!listeners) {
27627      listeners = populateListeners(name);
27628    }
27629
27630    if (listeners.length === 0) {
27631      return;
27632    }
27633
27634    var payload = _payload();
27635
27636    var STRUCTURED_PROFILE = _emberMetalCore.default.STRUCTURED_PROFILE;
27637    var timeName;
27638    if (STRUCTURED_PROFILE) {
27639      timeName = name + ': ' + payload.object;
27640      console.time(timeName);
27641    }
27642
27643    var l = listeners.length;
27644    var beforeValues = new Array(l);
27645    var i, listener;
27646    var timestamp = time();
27647    for (i = 0; i < l; i++) {
27648      listener = listeners[i];
27649      beforeValues[i] = listener.before(name, timestamp, payload);
27650    }
27651
27652    return function _instrumentEnd() {
27653      var i, l, listener;
27654      var timestamp = time();
27655      for (i = 0, l = listeners.length; i < l; i++) {
27656        listener = listeners[i];
27657        listener.after(name, timestamp, payload, beforeValues[i]);
27658      }
27659
27660      if (STRUCTURED_PROFILE) {
27661        console.timeEnd(timeName);
27662      }
27663    };
27664  }
27665
27666  /**
27667    Subscribes to a particular event or instrumented block of code.
27668  
27669    @method subscribe
27670    @namespace Ember.Instrumentation
27671  
27672    @param {String} [pattern] Namespaced event name.
27673    @param {Object} [object] Before and After hooks.
27674  
27675    @return {Subscriber}
27676    @private
27677  */
27678
27679  function subscribe(pattern, object) {
27680    var paths = pattern.split('.');
27681    var path;
27682    var regex = [];
27683
27684    for (var i = 0, l = paths.length; i < l; i++) {
27685      path = paths[i];
27686      if (path === '*') {
27687        regex.push('[^\\.]*');
27688      } else {
27689        regex.push(path);
27690      }
27691    }
27692
27693    regex = regex.join('\\.');
27694    regex = regex + '(\\..*)?';
27695
27696    var subscriber = {
27697      pattern: pattern,
27698      regex: new RegExp('^' + regex + '$'),
27699      object: object
27700    };
27701
27702    subscribers.push(subscriber);
27703    cache = {};
27704
27705    return subscriber;
27706  }
27707
27708  /**
27709    Unsubscribes from a particular event or instrumented block of code.
27710  
27711    @method unsubscribe
27712    @namespace Ember.Instrumentation
27713  
27714    @param {Object} [subscriber]
27715    @private
27716  */
27717
27718  function unsubscribe(subscriber) {
27719    var index;
27720
27721    for (var i = 0, l = subscribers.length; i < l; i++) {
27722      if (subscribers[i] === subscriber) {
27723        index = i;
27724      }
27725    }
27726
27727    subscribers.splice(index, 1);
27728    cache = {};
27729  }
27730
27731  /**
27732    Resets `Ember.Instrumentation` by flushing list of subscribers.
27733  
27734    @method reset
27735    @namespace Ember.Instrumentation
27736    @private
27737  */
27738
27739  function reset() {
27740    subscribers.length = 0;
27741    cache = {};
27742  }
27743});
27744enifed('ember-metal/is_blank', ['exports', 'ember-metal/is_empty'], function (exports, _emberMetalIs_empty) {
27745  'use strict';
27746
27747  exports.default = isBlank;
27748
27749  /**
27750    A value is blank if it is empty or a whitespace string.
27751  
27752    ```javascript
27753    Ember.isBlank();                // true
27754    Ember.isBlank(null);            // true
27755    Ember.isBlank(undefined);       // true
27756    Ember.isBlank('');              // true
27757    Ember.isBlank([]);              // true
27758    Ember.isBlank('\n\t');          // true
27759    Ember.isBlank('  ');            // true
27760    Ember.isBlank({});              // false
27761    Ember.isBlank('\n\t Hello');    // false
27762    Ember.isBlank('Hello world');   // false
27763    Ember.isBlank([1,2,3]);         // false
27764    ```
27765  
27766    @method isBlank
27767    @for Ember
27768    @param {Object} obj Value to test
27769    @return {Boolean}
27770    @since 1.5.0
27771    @public
27772  */
27773
27774  function isBlank(obj) {
27775    return _emberMetalIs_empty.default(obj) || typeof obj === 'string' && obj.match(/\S/) === null;
27776  }
27777});
27778enifed('ember-metal/is_empty', ['exports', 'ember-metal/property_get', 'ember-metal/is_none'], function (exports, _emberMetalProperty_get, _emberMetalIs_none) {
27779  'use strict';
27780
27781  /**
27782    Verifies that a value is `null` or an empty string, empty array,
27783    or empty function.
27784  
27785    Constrains the rules on `Ember.isNone` by returning true for empty
27786    string and empty arrays.
27787  
27788    ```javascript
27789    Ember.isEmpty();                // true
27790    Ember.isEmpty(null);            // true
27791    Ember.isEmpty(undefined);       // true
27792    Ember.isEmpty('');              // true
27793    Ember.isEmpty([]);              // true
27794    Ember.isEmpty({});              // false
27795    Ember.isEmpty('Adam Hawkins');  // false
27796    Ember.isEmpty([0,1,2]);         // false
27797    Ember.isEmpty('\n\t');          // false
27798    Ember.isEmpty('  ');            // false
27799    ```
27800  
27801    @method isEmpty
27802    @for Ember
27803    @param {Object} obj Value to test
27804    @return {Boolean}
27805    @public
27806  */
27807  function isEmpty(obj) {
27808    var none = _emberMetalIs_none.default(obj);
27809    if (none) {
27810      return none;
27811    }
27812
27813    if (typeof obj.size === 'number') {
27814      return !obj.size;
27815    }
27816
27817    var objectType = typeof obj;
27818
27819    if (objectType === 'object') {
27820      var size = _emberMetalProperty_get.get(obj, 'size');
27821      if (typeof size === 'number') {
27822        return !size;
27823      }
27824    }
27825
27826    if (typeof obj.length === 'number' && objectType !== 'function') {
27827      return !obj.length;
27828    }
27829
27830    if (objectType === 'object') {
27831      var length = _emberMetalProperty_get.get(obj, 'length');
27832      if (typeof length === 'number') {
27833        return !length;
27834      }
27835    }
27836
27837    return false;
27838  }
27839
27840  exports.default = isEmpty;
27841});
27842enifed("ember-metal/is_none", ["exports"], function (exports) {
27843  /**
27844    Returns true if the passed value is null or undefined. This avoids errors
27845    from JSLint complaining about use of ==, which can be technically
27846    confusing.
27847  
27848    ```javascript
27849    Ember.isNone();              // true
27850    Ember.isNone(null);          // true
27851    Ember.isNone(undefined);     // true
27852    Ember.isNone('');            // false
27853    Ember.isNone([]);            // false
27854    Ember.isNone(function() {}); // false
27855    ```
27856  
27857    @method isNone
27858    @for Ember
27859    @param {Object} obj Value to test
27860    @return {Boolean}
27861    @public
27862  */
27863  "use strict";
27864
27865  exports.default = isNone;
27866
27867  function isNone(obj) {
27868    return obj === null || obj === undefined;
27869  }
27870});
27871enifed('ember-metal/is_present', ['exports', 'ember-metal/is_blank'], function (exports, _emberMetalIs_blank) {
27872  'use strict';
27873
27874  exports.default = isPresent;
27875
27876  /**
27877    A value is present if it not `isBlank`.
27878  
27879    ```javascript
27880    Ember.isPresent();                // false
27881    Ember.isPresent(null);            // false
27882    Ember.isPresent(undefined);       // false
27883    Ember.isPresent('');              // false
27884    Ember.isPresent('  ');            // false
27885    Ember.isPresent('\n\t');          // false
27886    Ember.isPresent([]);              // false
27887    Ember.isPresent({ length: 0 })    // false
27888    Ember.isPresent(false);           // true
27889    Ember.isPresent(true);            // true
27890    Ember.isPresent('string');        // true
27891    Ember.isPresent(0);               // true
27892    Ember.isPresent(function() {})    // true
27893    Ember.isPresent({});              // true
27894    Ember.isPresent(false);           // true
27895    Ember.isPresent('\n\t Hello');    // true
27896    Ember.isPresent([1,2,3]);         // true
27897    ```
27898  
27899    @method isPresent
27900    @for Ember
27901    @param {Object} obj Value to test
27902    @return {Boolean}
27903    @since 1.8.0
27904    @public
27905  */
27906
27907  function isPresent(obj) {
27908    return !_emberMetalIs_blank.default(obj);
27909  }
27910});
27911enifed('ember-metal/libraries', ['exports', 'ember-metal/debug', 'ember-metal/features'], function (exports, _emberMetalDebug, _emberMetalFeatures) {
27912  'use strict';
27913
27914  /**
27915    Helper class that allows you to register your library with Ember.
27916  
27917    Singleton created at `Ember.libraries`.
27918  
27919    @class Libraries
27920    @constructor
27921    @private
27922  */
27923  function Libraries() {
27924    this._registry = [];
27925    this._coreLibIndex = 0;
27926  }
27927
27928  Libraries.prototype = {
27929    constructor: Libraries,
27930
27931    _getLibraryByName: function (name) {
27932      var libs = this._registry;
27933      var count = libs.length;
27934
27935      for (var i = 0; i < count; i++) {
27936        if (libs[i].name === name) {
27937          return libs[i];
27938        }
27939      }
27940    },
27941
27942    register: function (name, version, isCoreLibrary) {
27943      var index = this._registry.length;
27944
27945      if (!this._getLibraryByName(name)) {
27946        if (isCoreLibrary) {
27947          index = this._coreLibIndex++;
27948        }
27949        this._registry.splice(index, 0, { name: name, version: version });
27950      } else {
27951        _emberMetalDebug.warn('Library "' + name + '" is already registered with Ember.', false, { id: 'ember-metal.libraries-register' });
27952      }
27953    },
27954
27955    registerCoreLibrary: function (name, version) {
27956      this.register(name, version, true);
27957    },
27958
27959    deRegister: function (name) {
27960      var lib = this._getLibraryByName(name);
27961      var index;
27962
27963      if (lib) {
27964        index = this._registry.indexOf(lib);
27965        this._registry.splice(index, 1);
27966      }
27967    }
27968  };
27969
27970  exports.default = Libraries;
27971});
27972enifed('ember-metal/logger', ['exports', 'ember-metal/core', 'ember-metal/error'], function (exports, _emberMetalCore, _emberMetalError) {
27973  'use strict';
27974
27975  function K() {
27976    return this;
27977  }
27978
27979  function consoleMethod(name) {
27980    var consoleObj, logToConsole;
27981    if (_emberMetalCore.default.imports.console) {
27982      consoleObj = _emberMetalCore.default.imports.console;
27983    } else if (typeof console !== 'undefined') {
27984      consoleObj = console;
27985    }
27986
27987    var method = typeof consoleObj === 'object' ? consoleObj[name] : null;
27988
27989    if (method) {
27990      // Older IE doesn't support bind, but Chrome needs it
27991      if (typeof method.bind === 'function') {
27992        logToConsole = method.bind(consoleObj);
27993        logToConsole.displayName = 'console.' + name;
27994        return logToConsole;
27995      } else if (typeof method.apply === 'function') {
27996        logToConsole = function () {
27997          method.apply(consoleObj, arguments);
27998        };
27999        logToConsole.displayName = 'console.' + name;
28000        return logToConsole;
28001      } else {
28002        return function () {
28003          var message = Array.prototype.join.call(arguments, ', ');
28004          method(message);
28005        };
28006      }
28007    }
28008  }
28009
28010  function assertPolyfill(test, message) {
28011    if (!test) {
28012      try {
28013        // attempt to preserve the stack
28014        throw new _emberMetalError.default('assertion failed: ' + message);
28015      } catch (error) {
28016        setTimeout(function () {
28017          throw error;
28018        }, 0);
28019      }
28020    }
28021  }
28022
28023  /**
28024    Inside Ember-Metal, simply uses the methods from `imports.console`.
28025    Override this to provide more robust logging functionality.
28026  
28027    @class Logger
28028    @namespace Ember
28029    @public
28030  */
28031  exports.default = {
28032    /**
28033     Logs the arguments to the console.
28034     You can pass as many arguments as you want and they will be joined together with a space.
28035       ```javascript
28036      var foo = 1;
28037      Ember.Logger.log('log value of foo:', foo);
28038      // "log value of foo: 1" will be printed to the console
28039      ```
28040      @method log
28041     @for Ember.Logger
28042     @param {*} arguments
28043     @public
28044    */
28045    log: consoleMethod('log') || K,
28046
28047    /**
28048     Prints the arguments to the console with a warning icon.
28049     You can pass as many arguments as you want and they will be joined together with a space.
28050       ```javascript
28051      Ember.Logger.warn('Something happened!');
28052      // "Something happened!" will be printed to the console with a warning icon.
28053      ```
28054      @method warn
28055     @for Ember.Logger
28056     @param {*} arguments
28057     @public
28058    */
28059    warn: consoleMethod('warn') || K,
28060
28061    /**
28062     Prints the arguments to the console with an error icon, red text and a stack trace.
28063     You can pass as many arguments as you want and they will be joined together with a space.
28064       ```javascript
28065      Ember.Logger.error('Danger! Danger!');
28066      // "Danger! Danger!" will be printed to the console in red text.
28067      ```
28068      @method error
28069     @for Ember.Logger
28070     @param {*} arguments
28071     @public
28072    */
28073    error: consoleMethod('error') || K,
28074
28075    /**
28076     Logs the arguments to the console.
28077     You can pass as many arguments as you want and they will be joined together with a space.
28078       ```javascript
28079      var foo = 1;
28080      Ember.Logger.info('log value of foo:', foo);
28081      // "log value of foo: 1" will be printed to the console
28082      ```
28083      @method info
28084     @for Ember.Logger
28085     @param {*} arguments
28086     @public
28087    */
28088    info: consoleMethod('info') || K,
28089
28090    /**
28091     Logs the arguments to the console in blue text.
28092     You can pass as many arguments as you want and they will be joined together with a space.
28093       ```javascript
28094      var foo = 1;
28095      Ember.Logger.debug('log value of foo:', foo);
28096      // "log value of foo: 1" will be printed to the console
28097      ```
28098      @method debug
28099     @for Ember.Logger
28100     @param {*} arguments
28101     @public
28102    */
28103    debug: consoleMethod('debug') || consoleMethod('info') || K,
28104
28105    /**
28106     If the value passed into `Ember.Logger.assert` is not truthy it will throw an error with a stack trace.
28107       ```javascript
28108      Ember.Logger.assert(true); // undefined
28109      Ember.Logger.assert(true === false); // Throws an Assertion failed error.
28110      ```
28111      @method assert
28112     @for Ember.Logger
28113     @param {Boolean} bool Value to test
28114     @public
28115    */
28116    assert: consoleMethod('assert') || assertPolyfill
28117  };
28118});
28119// Ember.imports
28120enifed('ember-metal/map', ['exports', 'ember-metal/core', 'ember-metal/utils', 'ember-metal/empty_object'], function (exports, _emberMetalCore, _emberMetalUtils, _emberMetalEmpty_object) {
28121  /**
28122  @module ember
28123  @submodule ember-metal
28124  */
28125
28126  /*
28127    JavaScript (before ES6) does not have a Map implementation. Objects,
28128    which are often used as dictionaries, may only have Strings as keys.
28129  
28130    Because Ember has a way to get a unique identifier for every object
28131    via `Ember.guidFor`, we can implement a performant Map with arbitrary
28132    keys. Because it is commonly used in low-level bookkeeping, Map is
28133    implemented as a pure JavaScript object for performance.
28134  
28135    This implementation follows the current iteration of the ES6 proposal for
28136    maps (http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets),
28137    with one exception:  as we do not have the luxury of in-VM iteration, we implement a
28138    forEach method for iteration.
28139  
28140    Map is mocked out to look like an Ember object, so you can do
28141    `Ember.Map.create()` for symmetry with other Ember classes.
28142  */
28143
28144  'use strict';
28145
28146  function missingFunction(fn) {
28147    throw new TypeError(Object.prototype.toString.call(fn) + ' is not a function');
28148  }
28149
28150  function missingNew(name) {
28151    throw new TypeError('Constructor ' + name + ' requires \'new\'');
28152  }
28153
28154  function copyNull(obj) {
28155    var output = new _emberMetalEmpty_object.default();
28156
28157    for (var prop in obj) {
28158      // hasOwnPropery is not needed because obj is new EmptyObject();
28159      output[prop] = obj[prop];
28160    }
28161
28162    return output;
28163  }
28164
28165  function copyMap(original, newObject) {
28166    var keys = original._keys.copy();
28167    var values = copyNull(original._values);
28168
28169    newObject._keys = keys;
28170    newObject._values = values;
28171    newObject.size = original.size;
28172
28173    return newObject;
28174  }
28175
28176  /**
28177    This class is used internally by Ember and Ember Data.
28178    Please do not use it at this time. We plan to clean it up
28179    and add many tests soon.
28180  
28181    @class OrderedSet
28182    @namespace Ember
28183    @constructor
28184    @private
28185  */
28186  function OrderedSet() {
28187    if (this instanceof OrderedSet) {
28188      this.clear();
28189      this._silenceRemoveDeprecation = false;
28190    } else {
28191      missingNew('OrderedSet');
28192    }
28193  }
28194
28195  /**
28196    @method create
28197    @static
28198    @return {Ember.OrderedSet}
28199    @private
28200  */
28201  OrderedSet.create = function () {
28202    var Constructor = this;
28203
28204    return new Constructor();
28205  };
28206
28207  OrderedSet.prototype = {
28208    constructor: OrderedSet,
28209    /**
28210      @method clear
28211      @private
28212    */
28213    clear: function () {
28214      this.presenceSet = new _emberMetalEmpty_object.default();
28215      this.list = [];
28216      this.size = 0;
28217    },
28218
28219    /**
28220      @method add
28221      @param obj
28222      @param guid (optional, and for internal use)
28223      @return {Ember.OrderedSet}
28224      @private
28225    */
28226    add: function (obj, _guid) {
28227      var guid = _guid || _emberMetalUtils.guidFor(obj);
28228      var presenceSet = this.presenceSet;
28229      var list = this.list;
28230
28231      if (presenceSet[guid] !== true) {
28232        presenceSet[guid] = true;
28233        this.size = list.push(obj);
28234      }
28235
28236      return this;
28237    },
28238
28239    /**
28240      @since 1.8.0
28241      @method delete
28242      @param obj
28243      @param _guid (optional and for internal use only)
28244      @return {Boolean}
28245      @private
28246    */
28247    delete: function (obj, _guid) {
28248      var guid = _guid || _emberMetalUtils.guidFor(obj);
28249      var presenceSet = this.presenceSet;
28250      var list = this.list;
28251
28252      if (presenceSet[guid] === true) {
28253        delete presenceSet[guid];
28254        var index = list.indexOf(obj);
28255        if (index > -1) {
28256          list.splice(index, 1);
28257        }
28258        this.size = list.length;
28259        return true;
28260      } else {
28261        return false;
28262      }
28263    },
28264
28265    /**
28266      @method isEmpty
28267      @return {Boolean}
28268      @private
28269    */
28270    isEmpty: function () {
28271      return this.size === 0;
28272    },
28273
28274    /**
28275      @method has
28276      @param obj
28277      @return {Boolean}
28278      @private
28279    */
28280    has: function (obj) {
28281      if (this.size === 0) {
28282        return false;
28283      }
28284
28285      var guid = _emberMetalUtils.guidFor(obj);
28286      var presenceSet = this.presenceSet;
28287
28288      return presenceSet[guid] === true;
28289    },
28290
28291    /**
28292      @method forEach
28293      @param {Function} fn
28294      @param self
28295      @private
28296    */
28297    forEach: function (fn /*, ...thisArg*/) {
28298      if (typeof fn !== 'function') {
28299        missingFunction(fn);
28300      }
28301
28302      if (this.size === 0) {
28303        return;
28304      }
28305
28306      var list = this.list;
28307      var length = arguments.length;
28308      var i;
28309
28310      if (length === 2) {
28311        for (i = 0; i < list.length; i++) {
28312          fn.call(arguments[1], list[i]);
28313        }
28314      } else {
28315        for (i = 0; i < list.length; i++) {
28316          fn(list[i]);
28317        }
28318      }
28319    },
28320
28321    /**
28322      @method toArray
28323      @return {Array}
28324      @private
28325    */
28326    toArray: function () {
28327      return this.list.slice();
28328    },
28329
28330    /**
28331      @method copy
28332      @return {Ember.OrderedSet}
28333      @private
28334    */
28335    copy: function () {
28336      var Constructor = this.constructor;
28337      var set = new Constructor();
28338
28339      set._silenceRemoveDeprecation = this._silenceRemoveDeprecation;
28340      set.presenceSet = copyNull(this.presenceSet);
28341      set.list = this.toArray();
28342      set.size = this.size;
28343
28344      return set;
28345    }
28346  };
28347
28348  /**
28349    A Map stores values indexed by keys. Unlike JavaScript's
28350    default Objects, the keys of a Map can be any JavaScript
28351    object.
28352  
28353    Internally, a Map has two data structures:
28354  
28355    1. `keys`: an OrderedSet of all of the existing keys
28356    2. `values`: a JavaScript Object indexed by the `Ember.guidFor(key)`
28357  
28358    When a key/value pair is added for the first time, we
28359    add the key to the `keys` OrderedSet, and create or
28360    replace an entry in `values`. When an entry is deleted,
28361    we delete its entry in `keys` and `values`.
28362  
28363    @class Map
28364    @namespace Ember
28365    @private
28366    @constructor
28367  */
28368  function Map() {
28369    if (this instanceof this.constructor) {
28370      this._keys = OrderedSet.create();
28371      this._keys._silenceRemoveDeprecation = true;
28372      this._values = new _emberMetalEmpty_object.default();
28373      this.size = 0;
28374    } else {
28375      missingNew('OrderedSet');
28376    }
28377  }
28378
28379  _emberMetalCore.default.Map = Map;
28380
28381  /**
28382    @method create
28383    @static
28384    @private
28385  */
28386  Map.create = function () {
28387    var Constructor = this;
28388    return new Constructor();
28389  };
28390
28391  Map.prototype = {
28392    constructor: Map,
28393
28394    /**
28395      This property will change as the number of objects in the map changes.
28396       @since 1.8.0
28397      @property size
28398      @type number
28399      @default 0
28400      @private
28401    */
28402    size: 0,
28403
28404    /**
28405      Retrieve the value associated with a given key.
28406       @method get
28407      @param {*} key
28408      @return {*} the value associated with the key, or `undefined`
28409      @private
28410    */
28411    get: function (key) {
28412      if (this.size === 0) {
28413        return;
28414      }
28415
28416      var values = this._values;
28417      var guid = _emberMetalUtils.guidFor(key);
28418
28419      return values[guid];
28420    },
28421
28422    /**
28423      Adds a value to the map. If a value for the given key has already been
28424      provided, the new value will replace the old value.
28425       @method set
28426      @param {*} key
28427      @param {*} value
28428      @return {Ember.Map}
28429      @private
28430    */
28431    set: function (key, value) {
28432      var keys = this._keys;
28433      var values = this._values;
28434      var guid = _emberMetalUtils.guidFor(key);
28435
28436      // ensure we don't store -0
28437      var k = key === -0 ? 0 : key;
28438
28439      keys.add(k, guid);
28440
28441      values[guid] = value;
28442
28443      this.size = keys.size;
28444
28445      return this;
28446    },
28447
28448    /**
28449      Removes a value from the map for an associated key.
28450       @since 1.8.0
28451      @method delete
28452      @param {*} key
28453      @return {Boolean} true if an item was removed, false otherwise
28454      @private
28455    */
28456    delete: function (key) {
28457      if (this.size === 0) {
28458        return false;
28459      }
28460      // don't use ES6 "delete" because it will be annoying
28461      // to use in browsers that are not ES6 friendly;
28462      var keys = this._keys;
28463      var values = this._values;
28464      var guid = _emberMetalUtils.guidFor(key);
28465
28466      if (keys.delete(key, guid)) {
28467        delete values[guid];
28468        this.size = keys.size;
28469        return true;
28470      } else {
28471        return false;
28472      }
28473    },
28474
28475    /**
28476      Check whether a key is present.
28477       @method has
28478      @param {*} key
28479      @return {Boolean} true if the item was present, false otherwise
28480      @private
28481    */
28482    has: function (key) {
28483      return this._keys.has(key);
28484    },
28485
28486    /**
28487      Iterate over all the keys and values. Calls the function once
28488      for each key, passing in value, key, and the map being iterated over,
28489      in that order.
28490       The keys are guaranteed to be iterated over in insertion order.
28491       @method forEach
28492      @param {Function} callback
28493      @param {*} self if passed, the `this` value inside the
28494        callback. By default, `this` is the map.
28495      @private
28496    */
28497    forEach: function (callback /*, ...thisArg*/) {
28498      if (typeof callback !== 'function') {
28499        missingFunction(callback);
28500      }
28501
28502      if (this.size === 0) {
28503        return;
28504      }
28505
28506      var length = arguments.length;
28507      var map = this;
28508      var cb, thisArg;
28509
28510      if (length === 2) {
28511        thisArg = arguments[1];
28512        cb = function (key) {
28513          callback.call(thisArg, map.get(key), key, map);
28514        };
28515      } else {
28516        cb = function (key) {
28517          callback(map.get(key), key, map);
28518        };
28519      }
28520
28521      this._keys.forEach(cb);
28522    },
28523
28524    /**
28525      @method clear
28526      @private
28527    */
28528    clear: function () {
28529      this._keys.clear();
28530      this._values = new _emberMetalEmpty_object.default();
28531      this.size = 0;
28532    },
28533
28534    /**
28535      @method copy
28536      @return {Ember.Map}
28537      @private
28538    */
28539    copy: function () {
28540      return copyMap(this, new Map());
28541    }
28542  };
28543
28544  /**
28545    @class MapWithDefault
28546    @namespace Ember
28547    @extends Ember.Map
28548    @private
28549    @constructor
28550    @param [options]
28551      @param {*} [options.defaultValue]
28552  */
28553  function MapWithDefault(options) {
28554    this._super$constructor();
28555    this.defaultValue = options.defaultValue;
28556  }
28557
28558  /**
28559    @method create
28560    @static
28561    @param [options]
28562      @param {*} [options.defaultValue]
28563    @return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
28564      `Ember.MapWithDefault` otherwise returns `Ember.Map`
28565    @private
28566  */
28567  MapWithDefault.create = function (options) {
28568    if (options) {
28569      return new MapWithDefault(options);
28570    } else {
28571      return new Map();
28572    }
28573  };
28574
28575  MapWithDefault.prototype = Object.create(Map.prototype);
28576  MapWithDefault.prototype.constructor = MapWithDefault;
28577  MapWithDefault.prototype._super$constructor = Map;
28578  MapWithDefault.prototype._super$get = Map.prototype.get;
28579
28580  /**
28581    Retrieve the value associated with a given key.
28582  
28583    @method get
28584    @param {*} key
28585    @return {*} the value associated with the key, or the default value
28586    @private
28587  */
28588  MapWithDefault.prototype.get = function (key) {
28589    var hasValue = this.has(key);
28590
28591    if (hasValue) {
28592      return this._super$get(key);
28593    } else {
28594      var defaultValue = this.defaultValue(key);
28595      this.set(key, defaultValue);
28596      return defaultValue;
28597    }
28598  };
28599
28600  /**
28601    @method copy
28602    @return {Ember.MapWithDefault}
28603    @private
28604  */
28605  MapWithDefault.prototype.copy = function () {
28606    var Constructor = this.constructor;
28607    return copyMap(this, new Constructor({
28608      defaultValue: this.defaultValue
28609    }));
28610  };
28611
28612  exports.default = Map;
28613  exports.OrderedSet = OrderedSet;
28614  exports.Map = Map;
28615  exports.MapWithDefault = MapWithDefault;
28616});
28617enifed('ember-metal/merge', ['exports'], function (exports) {
28618  /**
28619    Merge the contents of two objects together into the first object.
28620  
28621    ```javascript
28622    Ember.merge({first: 'Tom'}, {last: 'Dale'}); // {first: 'Tom', last: 'Dale'}
28623    var a = {first: 'Yehuda'};
28624    var b = {last: 'Katz'};
28625    Ember.merge(a, b); // a == {first: 'Yehuda', last: 'Katz'}, b == {last: 'Katz'}
28626    ```
28627  
28628    @method merge
28629    @for Ember
28630    @param {Object} original The object to merge into
28631    @param {Object} updates The object to copy properties from
28632    @return {Object}
28633    @public
28634  */
28635  'use strict';
28636
28637  exports.default = merge;
28638
28639  function merge(original, updates) {
28640    if (!updates || typeof updates !== 'object') {
28641      return original;
28642    }
28643
28644    var props = Object.keys(updates);
28645    var prop;
28646    var length = props.length;
28647
28648    for (var i = 0; i < length; i++) {
28649      prop = props[i];
28650      original[prop] = updates[prop];
28651    }
28652
28653    return original;
28654  }
28655});
28656enifed('ember-metal/meta', ['exports', 'ember-metal/meta_listeners', 'ember-metal/empty_object'], function (exports, _emberMetalMeta_listeners, _emberMetalEmpty_object) {
28657  'no use strict';
28658  // Remove "use strict"; from transpiled module until
28659  // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
28660
28661  exports.meta = meta;
28662  exports.peekMeta = peekMeta;
28663  exports.deleteMeta = deleteMeta;
28664
28665  /**
28666  @module ember-metal
28667  */
28668
28669  /*
28670   This declares several meta-programmed members on the Meta class. Such
28671   meta!
28672  
28673   In general, the `readable` variants will give you an object (if it
28674   already exists) that you can read but should not modify. The
28675   `writable` variants will give you a mutable object, and they will
28676   create it if it didn't already exist.
28677  
28678   The following methods will get generated metaprogrammatically, and
28679   I'm including them here for greppability:
28680  
28681   writableCache, readableCache, writeWatching,
28682   peekWatching, clearWatching, writeMixins,
28683   peekMixins, clearMixins, writeBindings,
28684   peekBindings, clearBindings, writeValues,
28685   peekValues, clearValues, writeDeps, forEachInDeps
28686   writableChainWatchers, readableChainWatchers, writableChains,
28687   readableChains
28688  
28689  */
28690  var members = {
28691    cache: ownMap,
28692    weak: ownMap,
28693    watching: inheritedMap,
28694    mixins: inheritedMap,
28695    bindings: inheritedMap,
28696    values: inheritedMap,
28697    deps: inheritedMapOfMaps,
28698    chainWatchers: ownCustomObject,
28699    chains: inheritedCustomObject
28700  };
28701
28702  var memberNames = Object.keys(members);
28703  var META_FIELD = '__ember_meta__';
28704
28705  function Meta(obj, parentMeta) {
28706    this._cache = undefined;
28707    this._weak = undefined;
28708    this._watching = undefined;
28709    this._mixins = undefined;
28710    this._bindings = undefined;
28711    this._values = undefined;
28712    this._deps = undefined;
28713    this._chainWatchers = undefined;
28714    this._chains = undefined;
28715    // used only internally
28716    this.source = obj;
28717
28718    // when meta(obj).proto === obj, the object is intended to be only a
28719    // prototype and doesn't need to actually be observable itself
28720    this.proto = undefined;
28721
28722    // The next meta in our inheritance chain. We (will) track this
28723    // explicitly instead of using prototypical inheritance because we
28724    // have detailed knowledge of how each property should really be
28725    // inherited, and we can optimize it much better than JS runtimes.
28726    this.parent = parentMeta;
28727
28728    this._initializeListeners();
28729  }
28730
28731  for (var _name in _emberMetalMeta_listeners.protoMethods) {
28732    Meta.prototype[_name] = _emberMetalMeta_listeners.protoMethods[_name];
28733  }
28734  memberNames.forEach(function (name) {
28735    return members[name](name, Meta);
28736  });
28737
28738  // Implements a member that is a lazily created, non-inheritable
28739  // POJO.
28740  function ownMap(name, Meta) {
28741    var key = memberProperty(name);
28742    var capitalized = capitalize(name);
28743    Meta.prototype['writable' + capitalized] = function () {
28744      return this._getOrCreateOwnMap(key);
28745    };
28746    Meta.prototype['readable' + capitalized] = function () {
28747      return this[key];
28748    };
28749  }
28750
28751  Meta.prototype._getOrCreateOwnMap = function (key) {
28752    var ret = this[key];
28753    if (!ret) {
28754      ret = this[key] = new _emberMetalEmpty_object.default();
28755    }
28756    return ret;
28757  };
28758
28759  // Implements a member that is a lazily created POJO with inheritable
28760  // values.
28761  function inheritedMap(name, Meta) {
28762    var key = memberProperty(name);
28763    var capitalized = capitalize(name);
28764
28765    Meta.prototype['write' + capitalized] = function (subkey, value) {
28766      var map = this._getOrCreateOwnMap(key);
28767      map[subkey] = value;
28768    };
28769
28770    Meta.prototype['peek' + capitalized] = function (subkey) {
28771      return this._findInherited(key, subkey);
28772    };
28773
28774    Meta.prototype['forEach' + capitalized] = function (fn) {
28775      var pointer = this;
28776      var seen = new _emberMetalEmpty_object.default();
28777      while (pointer !== undefined) {
28778        var map = pointer[key];
28779        if (map) {
28780          for (var _key in map) {
28781            if (!seen[_key]) {
28782              seen[_key] = true;
28783              fn(_key, map[_key]);
28784            }
28785          }
28786        }
28787        pointer = pointer.parent;
28788      }
28789    };
28790
28791    Meta.prototype['clear' + capitalized] = function () {
28792      this[key] = undefined;
28793    };
28794
28795    Meta.prototype['deleteFrom' + capitalized] = function (subkey) {
28796      delete this._getOrCreateOwnMap(key)[subkey];
28797    };
28798
28799    Meta.prototype['hasIn' + capitalized] = function (subkey) {
28800      return this._findInherited(key, subkey) !== undefined;
28801    };
28802  }
28803
28804  Meta.prototype._getInherited = function (key) {
28805    var pointer = this;
28806    while (pointer !== undefined) {
28807      if (pointer[key]) {
28808        return pointer[key];
28809      }
28810      pointer = pointer.parent;
28811    }
28812  };
28813
28814  Meta.prototype._findInherited = function (key, subkey) {
28815    var pointer = this;
28816    while (pointer !== undefined) {
28817      var map = pointer[key];
28818      if (map) {
28819        var value = map[subkey];
28820        if (value !== undefined) {
28821          return value;
28822        }
28823      }
28824      pointer = pointer.parent;
28825    }
28826  };
28827
28828  // Implements a member that provides a lazily created map of maps,
28829  // with inheritance at both levels.
28830  function inheritedMapOfMaps(name, Meta) {
28831    var key = memberProperty(name);
28832    var capitalized = capitalize(name);
28833
28834    Meta.prototype['write' + capitalized] = function (subkey, itemkey, value) {
28835      var outerMap = this._getOrCreateOwnMap(key);
28836      var innerMap = outerMap[subkey];
28837      if (!innerMap) {
28838        innerMap = outerMap[subkey] = new _emberMetalEmpty_object.default();
28839      }
28840      innerMap[itemkey] = value;
28841    };
28842
28843    Meta.prototype['peek' + capitalized] = function (subkey, itemkey) {
28844      var pointer = this;
28845      while (pointer !== undefined) {
28846        var map = pointer[key];
28847        if (map) {
28848          var value = map[subkey];
28849          if (value) {
28850            if (value[itemkey] !== undefined) {
28851              return value[itemkey];
28852            }
28853          }
28854        }
28855        pointer = pointer.parent;
28856      }
28857    };
28858
28859    Meta.prototype['has' + capitalized] = function (subkey) {
28860      var pointer = this;
28861      while (pointer !== undefined) {
28862        if (pointer[key] && pointer[key][subkey]) {
28863          return true;
28864        }
28865        pointer = pointer.parent;
28866      }
28867      return false;
28868    };
28869
28870    Meta.prototype['forEachIn' + capitalized] = function (subkey, fn) {
28871      return this._forEachIn(key, subkey, fn);
28872    };
28873  }
28874
28875  Meta.prototype._forEachIn = function (key, subkey, fn) {
28876    var pointer = this;
28877    var seen = new _emberMetalEmpty_object.default();
28878    var calls = [];
28879    while (pointer !== undefined) {
28880      var map = pointer[key];
28881      if (map) {
28882        var innerMap = map[subkey];
28883        if (innerMap) {
28884          for (var innerKey in innerMap) {
28885            if (!seen[innerKey]) {
28886              seen[innerKey] = true;
28887              calls.push([innerKey, innerMap[innerKey]]);
28888            }
28889          }
28890        }
28891      }
28892      pointer = pointer.parent;
28893    }
28894    for (var i = 0; i < calls.length; i++) {
28895      var _calls$i = calls[i];
28896      var innerKey = _calls$i[0];
28897      var value = _calls$i[1];
28898
28899      fn(innerKey, value);
28900    }
28901  };
28902
28903  // Implements a member that provides a non-heritable, lazily-created
28904  // object using the method you provide.
28905  function ownCustomObject(name, Meta) {
28906    var key = memberProperty(name);
28907    var capitalized = capitalize(name);
28908    Meta.prototype['writable' + capitalized] = function (create) {
28909      var ret = this[key];
28910      if (!ret) {
28911        ret = this[key] = create(this.source);
28912      }
28913      return ret;
28914    };
28915    Meta.prototype['readable' + capitalized] = function () {
28916      return this[key];
28917    };
28918  }
28919
28920  // Implements a member that provides an inheritable, lazily-created
28921  // object using the method you provide. We will derived children from
28922  // their parents by calling your object's `copy()` method.
28923  function inheritedCustomObject(name, Meta) {
28924    var key = memberProperty(name);
28925    var capitalized = capitalize(name);
28926    Meta.prototype['writable' + capitalized] = function (create) {
28927      var ret = this[key];
28928      if (!ret) {
28929        if (this.parent) {
28930          ret = this[key] = this.parent['writable' + capitalized](create).copy(this.source);
28931        } else {
28932          ret = this[key] = create(this.source);
28933        }
28934      }
28935      return ret;
28936    };
28937    Meta.prototype['readable' + capitalized] = function () {
28938      return this._getInherited(key);
28939    };
28940  }
28941
28942  function memberProperty(name) {
28943    return '_' + name;
28944  }
28945
28946  // there's a more general-purpose capitalize in ember-runtime, but we
28947  // don't want to make ember-metal depend on ember-runtime.
28948  function capitalize(name) {
28949    return name.replace(/^\w/, function (m) {
28950      return m.toUpperCase();
28951    });
28952  }
28953
28954  var META_DESC = {
28955    writable: true,
28956    configurable: true,
28957    enumerable: false,
28958    value: null
28959  };
28960
28961  exports.META_DESC = META_DESC;
28962  var EMBER_META_PROPERTY = {
28963    name: META_FIELD,
28964    descriptor: META_DESC
28965  };
28966
28967  // choose the one appropriate for given platform
28968  var setMeta = function (obj, meta) {
28969    // if `null` already, just set it to the new value
28970    // otherwise define property first
28971    if (obj[META_FIELD] !== null) {
28972      if (obj.__defineNonEnumerable) {
28973        obj.__defineNonEnumerable(EMBER_META_PROPERTY);
28974      } else {
28975        Object.defineProperty(obj, META_FIELD, META_DESC);
28976      }
28977    }
28978
28979    obj[META_FIELD] = meta;
28980  };
28981
28982  /**
28983    Retrieves the meta hash for an object. If `writable` is true ensures the
28984    hash is writable for this object as well.
28985  
28986    The meta object contains information about computed property descriptors as
28987    well as any watched properties and other information. You generally will
28988    not access this information directly but instead work with higher level
28989    methods that manipulate this hash indirectly.
28990  
28991    @method meta
28992    @for Ember
28993    @private
28994  
28995    @param {Object} obj The object to retrieve meta for
28996    @param {Boolean} [writable=true] Pass `false` if you do not intend to modify
28997      the meta hash, allowing the method to avoid making an unnecessary copy.
28998    @return {Object} the meta hash for an object
28999  */
29000
29001  function meta(obj) {
29002    var maybeMeta = peekMeta(obj);
29003    var parent = undefined;
29004
29005    // remove this code, in-favor of explicit parent
29006    if (maybeMeta) {
29007      if (maybeMeta.source === obj) {
29008        return maybeMeta;
29009      }
29010      parent = maybeMeta;
29011    }
29012
29013    var newMeta = new Meta(obj, parent);
29014    setMeta(obj, newMeta);
29015    return newMeta;
29016  }
29017
29018  function peekMeta(obj) {
29019    return obj[META_FIELD];
29020  }
29021
29022  function deleteMeta(obj) {
29023    if (typeof obj[META_FIELD] !== 'object') {
29024      return;
29025    }
29026    obj[META_FIELD] = null;
29027  }
29028});
29029enifed('ember-metal/meta_listeners', ['exports'], function (exports) {
29030  /*
29031   When we render a rich template hierarchy, the set of events that
29032   *might* happen tends to be much larger than the set of events that
29033   actually happen. This implies that we should make listener creation &
29034   destruction cheap, even at the cost of making event dispatch more
29035   expensive.
29036  
29037   Thus we store a new listener with a single push and no new
29038   allocations, without even bothering to do deduplication -- we can
29039   save that for dispatch time, if an event actually happens.
29040   */
29041
29042  /* listener flags */
29043  'use strict';
29044
29045  var ONCE = 1;
29046  exports.ONCE = ONCE;
29047  var SUSPENDED = 2;
29048
29049  exports.SUSPENDED = SUSPENDED;
29050  var protoMethods = {
29051
29052    addToListeners: function (eventName, target, method, flags) {
29053      if (!this._listeners) {
29054        this._listeners = [];
29055      }
29056      this._listeners.push(eventName, target, method, flags);
29057    },
29058
29059    _finalizeListeners: function () {
29060      if (this._listenersFinalized) {
29061        return;
29062      }
29063      if (!this._listeners) {
29064        this._listeners = [];
29065      }
29066      var pointer = this.parent;
29067      while (pointer) {
29068        var listeners = pointer._listeners;
29069        if (listeners) {
29070          this._listeners = this._listeners.concat(listeners);
29071        }
29072        if (pointer._listenersFinalized) {
29073          break;
29074        }
29075        pointer = pointer.parent;
29076      }
29077      this._listenersFinalized = true;
29078    },
29079
29080    removeFromListeners: function (eventName, target, method, didRemove) {
29081      var pointer = this;
29082      while (pointer) {
29083        var listeners = pointer._listeners;
29084        if (listeners) {
29085          for (var index = listeners.length - 4; index >= 0; index -= 4) {
29086            if (listeners[index] === eventName && (!method || listeners[index + 1] === target && listeners[index + 2] === method)) {
29087              if (pointer === this) {
29088                // we are modifying our own list, so we edit directly
29089                if (typeof didRemove === 'function') {
29090                  didRemove(eventName, target, listeners[index + 2]);
29091                }
29092                listeners.splice(index, 4);
29093              } else {
29094                // we are trying to remove an inherited listener, so we do
29095                // just-in-time copying to detach our own listeners from
29096                // our inheritance chain.
29097                this._finalizeListeners();
29098                return this.removeFromListeners(eventName, target, method);
29099              }
29100            }
29101          }
29102        }
29103        if (pointer._listenersFinalized) {
29104          break;
29105        }
29106        pointer = pointer.parent;
29107      }
29108    },
29109
29110    matchingListeners: function (eventName) {
29111      var pointer = this;
29112      var result = [];
29113      while (pointer) {
29114        var listeners = pointer._listeners;
29115        if (listeners) {
29116          for (var index = 0; index < listeners.length - 3; index += 4) {
29117            if (listeners[index] === eventName) {
29118              pushUniqueListener(result, listeners, index);
29119            }
29120          }
29121        }
29122        if (pointer._listenersFinalized) {
29123          break;
29124        }
29125        pointer = pointer.parent;
29126      }
29127      var sus = this._suspendedListeners;
29128      if (sus) {
29129        for (var susIndex = 0; susIndex < sus.length - 2; susIndex += 3) {
29130          if (eventName === sus[susIndex]) {
29131            for (var resultIndex = 0; resultIndex < result.length - 2; resultIndex += 3) {
29132              if (result[resultIndex] === sus[susIndex + 1] && result[resultIndex + 1] === sus[susIndex + 2]) {
29133                result[resultIndex + 2] |= SUSPENDED;
29134              }
29135            }
29136          }
29137        }
29138      }
29139      return result;
29140    },
29141
29142    suspendListeners: function (eventNames, target, method, callback) {
29143      var sus = this._suspendedListeners;
29144      if (!sus) {
29145        sus = this._suspendedListeners = [];
29146      }
29147      for (var i = 0; i < eventNames.length; i++) {
29148        sus.push(eventNames[i], target, method);
29149      }
29150      try {
29151        return callback.call(target);
29152      } finally {
29153        if (sus.length === eventNames.length) {
29154          this._suspendedListeners = undefined;
29155        } else {
29156          for (var i = sus.length - 3; i >= 0; i -= 3) {
29157            if (sus[i + 1] === target && sus[i + 2] === method && eventNames.indexOf(sus[i]) !== -1) {
29158              sus.splice(i, 3);
29159            }
29160          }
29161        }
29162      }
29163    },
29164
29165    watchedEvents: function () {
29166      var pointer = this;
29167      var names = {};
29168      while (pointer) {
29169        var listeners = pointer._listeners;
29170        if (listeners) {
29171          for (var index = 0; index < listeners.length - 3; index += 4) {
29172            names[listeners[index]] = true;
29173          }
29174        }
29175        if (pointer._listenersFinalized) {
29176          break;
29177        }
29178        pointer = pointer.parent;
29179      }
29180      return Object.keys(names);
29181    },
29182
29183    _initializeListeners: function () {
29184      this._listeners = undefined;
29185      this._listenersFinalized = undefined;
29186      this._suspendedListeners = undefined;
29187    }
29188  };
29189
29190  exports.protoMethods = protoMethods;
29191  function pushUniqueListener(destination, source, index) {
29192    var target = source[index + 1];
29193    var method = source[index + 2];
29194    for (var destinationIndex = 0; destinationIndex < destination.length - 2; destinationIndex += 3) {
29195      if (destination[destinationIndex] === target && destination[destinationIndex + 1] === method) {
29196        return;
29197      }
29198    }
29199    destination.push(target, method, source[index + 3]);
29200  }
29201});
29202enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/error', 'ember-metal/debug', 'ember-metal/assign', 'ember-metal/empty_object', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/expand_properties', 'ember-metal/properties', 'ember-metal/computed', 'ember-metal/binding', 'ember-metal/observer', 'ember-metal/events', 'ember-metal/stream
29202s/utils'], function (exports, _emberMetalCore, _emberMetalError, _emberMetalDebug, _emberMetalAssign, _emberMetalEmpty_object, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalUtils, _emberMetalMeta, _emberMetalExpand_properties, _emberMetalProperties, _emberMetalComputed, _emberMetalBinding, _emberMetalObserver, _emberMetalEvents, _emberMetalStreamsUtils) {
29203  'no use strict';
29204  // Remove "use strict"; from transpiled module until
29205  // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
29206
29207  /**
29208  @module ember
29209  @submodule ember-metal
29210  */
29211  exports.mixin = mixin;
29212  exports.default = Mixin;
29213  exports.required = required;
29214  exports.aliasMethod = aliasMethod;
29215  exports.observer = observer;
29216  exports._immediateObserver = _immediateObserver;
29217  exports._beforeObserver = _beforeObserver;
29218
29219  function ROOT() {}
29220  ROOT.__hasSuper = false;
29221
29222  var REQUIRED;
29223  var a_slice = [].slice;
29224
29225  function isMethod(obj) {
29226    return 'function' === typeof obj && obj.isMethod !== false && obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String;
29227  }
29228
29229  var CONTINUE = {};
29230
29231  function mixinProperties(mixinsMeta, mixin) {
29232    var guid;
29233
29234    if (mixin instanceof Mixin) {
29235      guid = _emberMetalUtils.guidFor(mixin);
29236      if (mixinsMeta.peekMixins(guid)) {
29237        return CONTINUE;
29238      }
29239      mixinsMeta.writeMixins(guid, mixin);
29240      return mixin.properties;
29241    } else {
29242      return mixin; // apply anonymous mixin properties
29243    }
29244  }
29245
29246  function concatenatedMixinProperties(concatProp, props, values, base) {
29247    var concats;
29248
29249    // reset before adding each new mixin to pickup concats from previous
29250    concats = values[concatProp] || base[concatProp];
29251    if (props[concatProp]) {
29252      concats = concats ? concats.concat(props[concatProp]) : props[concatProp];
29253    }
29254
29255    return concats;
29256  }
29257
29258  function giveDescriptorSuper(meta, key, property, values, descs, base) {
29259    var superProperty;
29260
29261    // Computed properties override methods, and do not call super to them
29262    if (values[key] === undefined) {
29263      // Find the original descriptor in a parent mixin
29264      superProperty = descs[key];
29265    }
29266
29267    // If we didn't find the original descriptor in a parent mixin, find
29268    // it on the original object.
29269    if (!superProperty) {
29270      var possibleDesc = base[key];
29271      var superDesc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
29272
29273      superProperty = superDesc;
29274    }
29275
29276    if (superProperty === undefined || !(superProperty instanceof _emberMetalComputed.ComputedProperty)) {
29277      return property;
29278    }
29279
29280    // Since multiple mixins may inherit from the same parent, we need
29281    // to clone the computed property so that other mixins do not receive
29282    // the wrapped version.
29283    property = Object.create(property);
29284    property._getter = _emberMetalUtils.wrap(property._getter, superProperty._getter);
29285    if (superProperty._setter) {
29286      if (property._setter) {
29287        property._setter = _emberMetalUtils.wrap(property._setter, superProperty._setter);
29288      } else {
29289        property._setter = superProperty._setter;
29290      }
29291    }
29292
29293    return property;
29294  }
29295
29296  function giveMethodSuper(obj, key, method, values, descs) {
29297    var superMethod;
29298
29299    // Methods overwrite computed properties, and do not call super to them.
29300    if (descs[key] === undefined) {
29301      // Find the original method in a parent mixin
29302      superMethod = values[key];
29303    }
29304
29305    // If we didn't find the original value in a parent mixin, find it in
29306    // the original object
29307    superMethod = superMethod || obj[key];
29308
29309    // Only wrap the new method if the original method was a function
29310    if (superMethod === undefined || 'function' !== typeof superMethod) {
29311      return method;
29312    }
29313
29314    return _emberMetalUtils.wrap(method, superMethod);
29315  }
29316
29317  function applyConcatenatedProperties(obj, key, value, values) {
29318    var baseValue = values[key] || obj[key];
29319
29320    if (baseValue) {
29321      if ('function' === typeof baseValue.concat) {
29322        if (value === null || value === undefined) {
29323          return baseValue;
29324        } else {
29325          return baseValue.concat(value);
29326        }
29327      } else {
29328        return _emberMetalUtils.makeArray(baseValue).concat(value);
29329      }
29330    } else {
29331      return _emberMetalUtils.makeArray(value);
29332    }
29333  }
29334
29335  function applyMergedProperties(obj, key, value, values) {
29336    var baseValue = values[key] || obj[key];
29337
29338    _emberMetalDebug.runInDebug(function () {
29339      if (Array.isArray(value)) {
29340        // use conditional to avoid stringifying every time
29341        _emberMetalDebug.assert('You passed in `' + JSON.stringify(value) + '` as the value for `' + key + '` but `' + key + '` cannot be an Array', false);
29342      }
29343    });
29344
29345    if (!baseValue) {
29346      return value;
29347    }
29348
29349    var newBase = _emberMetalAssign.default({}, baseValue);
29350    var hasFunction = false;
29351
29352    for (var prop in value) {
29353      if (!value.hasOwnProperty(prop)) {
29354        continue;
29355      }
29356
29357      var propValue = value[prop];
29358      if (isMethod(propValue)) {
29359        // TODO: support for Computed Properties, etc?
29360        hasFunction = true;
29361        newBase[prop] = giveMethodSuper(obj, prop, propValue, baseValue, {});
29362      } else {
29363        newBase[prop] = propValue;
29364      }
29365    }
29366
29367    if (hasFunction) {
29368      newBase._super = ROOT;
29369    }
29370
29371    return newBase;
29372  }
29373
29374  function addNormalizedProperty(base, key, value, meta, descs, values, concats, mergings) {
29375    if (value instanceof _emberMetalProperties.Descriptor) {
29376      if (value === REQUIRED && descs[key]) {
29377        return CONTINUE;
29378      }
29379
29380      // Wrap descriptor function to implement
29381      // _super() if needed
29382      if (value._getter) {
29383        value = giveDescriptorSuper(meta, key, value, values, descs, base);
29384      }
29385
29386      descs[key] = value;
29387      values[key] = undefined;
29388    } else {
29389      if (concats && concats.indexOf(key) >= 0 || key === 'concatenatedProperties' || key === 'mergedProperties') {
29390        value = applyConcatenatedProperties(base, key, value, values);
29391      } else if (mergings && mergings.indexOf(key) >= 0) {
29392        value = applyMergedProperties(base, key, value, values);
29393      } else if (isMethod(value)) {
29394        value = giveMethodSuper(base, key, value, values, descs);
29395      }
29396
29397      descs[key] = undefined;
29398      values[key] = value;
29399    }
29400  }
29401
29402  function mergeMixins(mixins, m, descs, values, base, keys) {
29403    var currentMixin, props, key, concats, mergings, meta;
29404
29405    function removeKeys(keyName) {
29406      delete descs[keyName];
29407      delete values[keyName];
29408    }
29409
29410    for (var i = 0, l = mixins.length; i < l; i++) {
29411      currentMixin = mixins[i];
29412      _emberMetalDebug.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(currentMixin), typeof currentMixin === 'object' && currentMixin !== null && Object.prototype.toString.call(currentMixin) !== '[object Array]');
29413
29414      props = mixinProperties(m, currentMixin);
29415      if (props === CONTINUE) {
29416        continue;
29417      }
29418
29419      if (props) {
29420        meta = _emberMetalMeta.meta(base);
29421        if (base.willMergeMixin) {
29422          base.willMergeMixin(props);
29423        }
29424        concats = concatenatedMixinProperties('concatenatedProperties', props, values, base);
29425        mergings = concatenatedMixinProperties('mergedProperties', props, values, base);
29426
29427        for (key in props) {
29428          if (!props.hasOwnProperty(key)) {
29429            continue;
29430          }
29431          keys.push(key);
29432          addNormalizedProperty(base, key, props[key], meta, descs, values, concats, mergings);
29433        }
29434
29435        // manually copy toString() because some JS engines do not enumerate it
29436        if (props.hasOwnProperty('toString')) {
29437          base.toString = props.toString;
29438        }
29439      } else if (currentMixin.mixins) {
29440        mergeMixins(currentMixin.mixins, m, descs, values, base, keys);
29441        if (currentMixin._without) {
29442          currentMixin._without.forEach(removeKeys);
29443        }
29444      }
29445    }
29446  }
29447
29448  var IS_BINDING = /^.+Binding$/;
29449
29450  function detectBinding(obj, key, value, m) {
29451    if (IS_BINDING.test(key)) {
29452      m.writeBindings(key, value);
29453    }
29454  }
29455
29456  function connectStreamBinding(obj, key, stream) {
29457    var onNotify = function (stream) {
29458      _emberMetalObserver._suspendObserver(obj, key, null, didChange, function () {
29459        _emberMetalProperty_set.trySet(obj, key, stream.value());
29460      });
29461    };
29462
29463    var didChange = function () {
29464      stream.setValue(_emberMetalProperty_get.get(obj, key), onNotify);
29465    };
29466
29467    // Initialize value
29468    _emberMetalProperty_set.set(obj, key, stream.value());
29469
29470    _emberMetalObserver.addObserver(obj, key, null, didChange);
29471
29472    stream.subscribe(onNotify);
29473
29474    if (obj._streamBindingSubscriptions === undefined) {
29475      obj._streamBindingSubscriptions = new _emberMetalEmpty_object.default();
29476    }
29477
29478    obj._streamBindingSubscriptions[key] = onNotify;
29479  }
29480
29481  function connectBindings(obj, m) {
29482    // TODO Mixin.apply(instance) should disconnect binding if exists
29483    m.forEachBindings(function (key, binding) {
29484      if (binding) {
29485        var to = key.slice(0, -7); // strip Binding off end
29486        if (_emberMetalStreamsUtils.isStream(binding)) {
29487          connectStreamBinding(obj, to, binding);
29488          return;
29489        } else if (binding instanceof _emberMetalBinding.Binding) {
29490          binding = binding.copy(); // copy prototypes' instance
29491          binding.to(to);
29492        } else {
29493          // binding is string path
29494          binding = new _emberMetalBinding.Binding(to, binding);
29495        }
29496        binding.connect(obj);
29497        obj[key] = binding;
29498      }
29499    });
29500    // mark as applied
29501    m.clearBindings();
29502  }
29503
29504  function finishPartial(obj, m) {
29505    connectBindings(obj, m || _emberMetalMeta.meta(obj));
29506    return obj;
29507  }
29508
29509  function followAlias(obj, desc, m, descs, values) {
29510    var altKey = desc.methodName;
29511    var value;
29512    var possibleDesc;
29513    if (descs[altKey] || values[altKey]) {
29514      value = values[altKey];
29515      desc = descs[altKey];
29516    } else if ((possibleDesc = obj[altKey]) && possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) {
29517      desc = possibleDesc;
29518      value = undefined;
29519    } else {
29520      desc = undefined;
29521      value = obj[altKey];
29522    }
29523
29524    return { desc: desc, value: value };
29525  }
29526
29527  function updateObserversAndListeners(obj, key, observerOrListener, pathsKey, updateMethod) {
29528    var paths = observerOrListener[pathsKey];
29529
29530    if (paths) {
29531      for (var i = 0, l = paths.length; i < l; i++) {
29532        updateMethod(obj, paths[i], null, key);
29533      }
29534    }
29535  }
29536
29537  function replaceObserversAndListeners(obj, key, observerOrListener) {
29538    var prev = obj[key];
29539
29540    if ('function' === typeof prev) {
29541      updateObserversAndListeners(obj, key, prev, '__ember_observesBefore__', _emberMetalObserver._removeBeforeObserver);
29542      updateObserversAndListeners(obj, key, prev, '__ember_observes__', _emberMetalObserver.removeObserver);
29543      updateObserversAndListeners(obj, key, prev, '__ember_listens__', _emberMetalEvents.removeListener);
29544    }
29545
29546    if ('function' === typeof observerOrListener) {
29547      updateObserversAndListeners(obj, key, observerOrListener, '__ember_observesBefore__', _emberMetalObserver._addBeforeObserver);
29548      updateObserversAndListeners(obj, key, observerOrListener, '__ember_observes__', _emberMetalObserver.addObserver);
29549      updateObserversAndListeners(obj, key, observerOrListener, '__ember_listens__', _emberMetalEvents.addListener);
29550    }
29551  }
29552
29553  function applyMixin(obj, mixins, partial) {
29554    var descs = {};
29555    var values = {};
29556    var m = _emberMetalMeta.meta(obj);
29557    var keys = [];
29558    var key, value, desc;
29559
29560    obj._super = ROOT;
29561
29562    // Go through all mixins and hashes passed in, and:
29563    //
29564    // * Handle concatenated properties
29565    // * Handle merged properties
29566    // * Set up _super wrapping if necessary
29567    // * Set up computed property descriptors
29568    // * Copying `toString` in broken browsers
29569    mergeMixins(mixins, m, descs, values, obj, keys);
29570
29571    for (var i = 0, l = keys.length; i < l; i++) {
29572      key = keys[i];
29573      if (key === 'constructor' || !values.hasOwnProperty(key)) {
29574        continue;
29575      }
29576
29577      desc = descs[key];
29578      value = values[key];
29579
29580      if (desc === REQUIRED) {
29581        continue;
29582      }
29583
29584      while (desc && desc instanceof Alias) {
29585        var followed = followAlias(obj, desc, m, descs, values);
29586        desc = followed.desc;
29587        value = followed.value;
29588      }
29589
29590      if (desc === undefined && value === undefined) {
29591        continue;
29592      }
29593
29594      replaceObserversAndListeners(obj, key, value);
29595      detectBinding(obj, key, value, m);
29596      _emberMetalProperties.defineProperty(obj, key, desc, value, m);
29597    }
29598
29599    if (!partial) {
29600      // don't apply to prototype
29601      finishPartial(obj, m);
29602    }
29603
29604    return obj;
29605  }
29606
29607  /**
29608    @method mixin
29609    @for Ember
29610    @param obj
29611    @param mixins*
29612    @return obj
29613    @private
29614  */
29615
29616  function mixin(obj) {
29617    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
29618      args[_key - 1] = arguments[_key];
29619    }
29620
29621    applyMixin(obj, args, false);
29622    return obj;
29623  }
29624
29625  /**
29626    The `Ember.Mixin` class allows you to create mixins, whose properties can be
29627    added to other classes. For instance,
29628  
29629    ```javascript
29630    App.Editable = Ember.Mixin.create({
29631      edit: function() {
29632        console.log('starting to edit');
29633        this.set('isEditing', true);
29634      },
29635      isEditing: false
29636    });
29637  
29638    // Mix mixins into classes by passing them as the first arguments to
29639    // .extend.
29640    App.CommentView = Ember.View.extend(App.Editable, {
29641      template: Ember.Handlebars.compile('{{#if view.isEditing}}...{{else}}...{{/if}}')
29642    });
29643  
29644    commentView = App.CommentView.create();
29645    commentView.edit(); // outputs 'starting to edit'
29646    ```
29647  
29648    Note that Mixins are created with `Ember.Mixin.create`, not
29649    `Ember.Mixin.extend`.
29650  
29651    Note that mixins extend a constructor's prototype so arrays and object literals
29652    defined as properties will be shared amongst objects that implement the mixin.
29653    If you want to define a property in a mixin that is not shared, you can define
29654    it either as a computed property or have it be created on initialization of the object.
29655  
29656    ```javascript
29657    //filters array will be shared amongst any object implementing mixin
29658    App.Filterable = Ember.Mixin.create({
29659      filters: Ember.A()
29660    });
29661  
29662    //filters will be a separate  array for every object implementing the mixin
29663    App.Filterable = Ember.Mixin.create({
29664      filters: Ember.computed(function() {return Ember.A();})
29665    });
29666  
29667    //filters will be created as a separate array during the object's initialization
29668    App.Filterable = Ember.Mixin.create({
29669      init: function() {
29670        this._super(...arguments);
29671        this.set("filters", Ember.A());
29672      }
29673    });
29674    ```
29675  
29676    @class Mixin
29677    @namespace Ember
29678    @public
29679  */
29680
29681  function Mixin(args, properties) {
29682    this.properties = properties;
29683
29684    var length = args && args.length;
29685
29686    if (length > 0) {
29687      var m = new Array(length);
29688
29689      for (var i = 0; i < length; i++) {
29690        var x = args[i];
29691        if (x instanceof Mixin) {
29692          m[i] = x;
29693        } else {
29694          m[i] = new Mixin(undefined, x);
29695        }
29696      }
29697
29698      this.mixins = m;
29699    } else {
29700      this.mixins = undefined;
29701    }
29702    this.ownerConstructor = undefined;
29703    this._without = undefined;
29704    this[_emberMetalUtils.GUID_KEY] = null;
29705    this[_emberMetalUtils.GUID_KEY + '_name'] = null;
29706    _emberMetalDebug.debugSeal(this);
29707  }
29708
29709  Mixin._apply = applyMixin;
29710
29711  Mixin.applyPartial = function (obj) {
29712    var args = a_slice.call(arguments, 1);
29713    return applyMixin(obj, args, true);
29714  };
29715
29716  Mixin.finishPartial = finishPartial;
29717
29718  // ES6TODO: this relies on a global state?
29719  _emberMetalCore.default.anyUnprocessedMixins = false;
29720
29721  /**
29722    @method create
29723    @static
29724    @param arguments*
29725    @public
29726  */
29727  Mixin.create = function () {
29728    // ES6TODO: this relies on a global state?
29729    _emberMetalCore.default.anyUnprocessedMixins = true;
29730    var M = this;
29731
29732    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
29733      args[_key2] = arguments[_key2];
29734    }
29735
29736    return new M(args, undefined);
29737  };
29738
29739  var MixinPrototype = Mixin.prototype;
29740
29741  /**
29742    @method reopen
29743    @param arguments*
29744    @private
29745  */
29746  MixinPrototype.reopen = function () {
29747    var currentMixin;
29748
29749    if (this.properties) {
29750      currentMixin = new Mixin(undefined, this.properties);
29751      this.properties = undefined;
29752      this.mixins = [currentMixin];
29753    } else if (!this.mixins) {
29754      this.mixins = [];
29755    }
29756
29757    var len = arguments.length;
29758    var mixins = this.mixins;
29759    var idx;
29760
29761    for (idx = 0; idx < len; idx++) {
29762      currentMixin = arguments[idx];
29763      _emberMetalDebug.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(currentMixin), typeof currentMixin === 'object' && currentMixin !== null && Object.prototype.toString.call(currentMixin) !== '[object Array]');
29764
29765      if (currentMixin instanceof Mixin) {
29766        mixins.push(currentMixin);
29767      } else {
29768        mixins.push(new Mixin(undefined, currentMixin));
29769      }
29770    }
29771
29772    return this;
29773  };
29774
29775  /**
29776    @method apply
29777    @param obj
29778    @return applied object
29779    @private
29780  */
29781  MixinPrototype.apply = function (obj) {
29782    return applyMixin(obj, [this], false);
29783  };
29784
29785  MixinPrototype.applyPartial = function (obj) {
29786    return applyMixin(obj, [this], true);
29787  };
29788
29789  MixinPrototype.toString = function Mixin_toString() {
29790    return '(unknown mixin)';
29791  };
29792
29793  function _detect(curMixin, targetMixin, seen) {
29794    var guid = _emberMetalUtils.guidFor(curMixin);
29795
29796    if (seen[guid]) {
29797      return false;
29798    }
29799    seen[guid] = true;
29800
29801    if (curMixin === targetMixin) {
29802      return true;
29803    }
29804    var mixins = curMixin.mixins;
29805    var loc = mixins ? mixins.length : 0;
29806    while (--loc >= 0) {
29807      if (_detect(mixins[loc], targetMixin, seen)) {
29808        return true;
29809      }
29810    }
29811    return false;
29812  }
29813
29814  /**
29815    @method detect
29816    @param obj
29817    @return {Boolean}
29818    @private
29819  */
29820  MixinPrototype.detect = function (obj) {
29821    if (!obj) {
29822      return false;
29823    }
29824    if (obj instanceof Mixin) {
29825      return _detect(obj, this, {});
29826    }
29827    var m = _emberMetalMeta.peekMeta(obj);
29828    if (!m) {
29829      return false;
29830    }
29831    return !!m.peekMixins(_emberMetalUtils.guidFor(this));
29832  };
29833
29834  MixinPrototype.without = function () {
29835    var ret = new Mixin([this]);
29836
29837    for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
29838      args[_key3] = arguments[_key3];
29839    }
29840
29841    ret._without = args;
29842    return ret;
29843  };
29844
29845  function _keys(ret, mixin, seen) {
29846    if (seen[_emberMetalUtils.guidFor(mixin)]) {
29847      return;
29848    }
29849    seen[_emberMetalUtils.guidFor(mixin)] = true;
29850
29851    if (mixin.properties) {
29852      var props = Object.keys(mixin.properties);
29853      for (var i = 0; i < props.length; i++) {
29854        var key = props[i];
29855        ret[key] = true;
29856      }
29857    } else if (mixin.mixins) {
29858      mixin.mixins.forEach(function (x) {
29859        return _keys(ret, x, seen);
29860      });
29861    }
29862  }
29863
29864  MixinPrototype.keys = function () {
29865    var keys = {};
29866    var seen = {};
29867
29868    _keys(keys, this, seen);
29869    var ret = Object.keys(keys);
29870    return ret;
29871  };
29872
29873  _emberMetalDebug.debugSeal(MixinPrototype);
29874
29875  // returns the mixins currently applied to the specified object
29876  // TODO: Make Ember.mixin
29877  Mixin.mixins = function (obj) {
29878    var m = _emberMetalMeta.peekMeta(obj);
29879    var ret = [];
29880    if (!m) {
29881      return ret;
29882    }
29883
29884    m.forEachMixins(function (key, currentMixin) {
29885      // skip primitive mixins since these are always anonymous
29886      if (!currentMixin.properties) {
29887        ret.push(currentMixin);
29888      }
29889    });
29890
29891    return ret;
29892  };
29893
29894  exports.REQUIRED = REQUIRED = new _emberMetalProperties.Descriptor();
29895  REQUIRED.toString = function () {
29896    return '(Required Property)';
29897  };
29898
29899  /**
29900    Denotes a required property for a mixin
29901  
29902    @method required
29903    @for Ember
29904    @private
29905  */
29906
29907  function required() {
29908    _emberMetalDebug.deprecate('Ember.required is deprecated as its behavior is inconsistent and unreliable.', false, { id: 'ember-metal.required', until: '3.0.0' });
29909    return REQUIRED;
29910  }
29911
29912  function Alias(methodName) {
29913    this.isDescriptor = true;
29914    this.methodName = methodName;
29915  }
29916
29917  Alias.prototype = new _emberMetalProperties.Descriptor();
29918
29919  /**
29920    Makes a method available via an additional name.
29921  
29922    ```javascript
29923    App.Person = Ember.Object.extend({
29924      name: function() {
29925        return 'Tomhuda Katzdale';
29926      },
29927      moniker: Ember.aliasMethod('name')
29928    });
29929  
29930    var goodGuy = App.Person.create();
29931  
29932    goodGuy.name();    // 'Tomhuda Katzdale'
29933    goodGuy.moniker(); // 'Tomhuda Katzdale'
29934    ```
29935  
29936    @method aliasMethod
29937    @for Ember
29938    @param {String} methodName name of the method to alias
29939    @public
29940  */
29941
29942  function aliasMethod(methodName) {
29943    return new Alias(methodName);
29944  }
29945
29946  // ..........................................................
29947  // OBSERVER HELPER
29948  //
29949
29950  /**
29951    Specify a method that observes property changes.
29952  
29953    ```javascript
29954    Ember.Object.extend({
29955      valueObserver: Ember.observer('value', function() {
29956        // Executes whenever the "value" property changes
29957      })
29958    });
29959    ```
29960  
29961    Also available as `Function.prototype.observes` if prototype extensions are
29962    enabled.
29963  
29964    @method observer
29965    @for Ember
29966    @param {String} propertyNames*
29967    @param {Function} func
29968    @return func
29969    @public
29970  */
29971
29972  function observer() {
29973    for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
29974      args[_key4] = arguments[_key4];
29975    }
29976
29977    var func = args.slice(-1)[0];
29978    var paths;
29979
29980    var addWatchedProperty = function (path) {
29981      paths.push(path);
29982    };
29983    var _paths = args.slice(0, -1);
29984
29985    if (typeof func !== 'function') {
29986      // revert to old, soft-deprecated argument ordering
29987      _emberMetalDebug.deprecate('Passing the dependentKeys after the callback function in Ember.observer is deprecated. Ensure the callback function is the last argument.', false, { id: 'ember-metal.observer-argument-order', until: '3.0.0' });
29988
29989      func = args[0];
29990      _paths = args.slice(1);
29991    }
29992
29993    paths = [];
29994
29995    for (var i = 0; i < _paths.length; ++i) {
29996      _emberMetalExpand_properties.default(_paths[i], addWatchedProperty);
29997    }
29998
29999    if (typeof func !== 'function') {
30000      throw new _emberMetalError.default('Ember.observer called without a function');
30001    }
30002
30003    func.__ember_observes__ = paths;
30004    return func;
30005  }
30006
30007  /**
30008    Specify a method that observes property changes.
30009  
30010    ```javascript
30011    Ember.Object.extend({
30012      valueObserver: Ember.immediateObserver('value', function() {
30013        // Executes whenever the "value" property changes
30014      })
30015    });
30016    ```
30017  
30018    In the future, `Ember.observer` may become asynchronous. In this event,
30019    `Ember.immediateObserver` will maintain the synchronous behavior.
30020  
30021    Also available as `Function.prototype.observesImmediately` if prototype extensions are
30022    enabled.
30023  
30024    @method _immediateObserver
30025    @for Ember
30026    @param {String} propertyNames*
30027    @param {Function} func
30028    @deprecated Use `Ember.observer` instead.
30029    @return func
30030    @private
30031  */
30032
30033  function _immediateObserver() {
30034    _emberMetalDebug.deprecate('Usage of `Ember.immediateObserver` is deprecated, use `Ember.observer` instead.', false, { id: 'ember-metal.immediate-observer', until: '3.0.0' });
30035
30036    for (var i = 0, l = arguments.length; i < l; i++) {
30037      var arg = arguments[i];
30038      _emberMetalDebug.assert('Immediate observers must observe internal properties only, not properties on other objects.', typeof arg !== 'string' || arg.indexOf('.') === -1);
30039    }
30040
30041    return observer.apply(this, arguments);
30042  }
30043
30044  /**
30045    When observers fire, they are called with the arguments `obj`, `keyName`.
30046  
30047    Note, `@each.property` observer is called per each add or replace of an element
30048    and it's not called with a specific enumeration item.
30049  
30050    A `_beforeObserver` fires before a property changes.
30051  
30052    A `_beforeObserver` is an alternative form of `.observesBefore()`.
30053  
30054    ```javascript
30055    App.PersonView = Ember.View.extend({
30056      friends: [{ name: 'Tom' }, { name: 'Stefan' }, { name: 'Kris' }],
30057  
30058      valueDidChange: Ember.observer('content.value', function(obj, keyName) {
30059          // only run if updating a value already in the DOM
30060          if (this.get('state') === 'inDOM') {
30061            var color = obj.get(keyName) > this.changingFrom ? 'green' : 'red';
30062            // logic
30063          }
30064      }),
30065  
30066      friendsDidChange: Ember.observer('[email protected]', function(obj, keyName) {
30067        // some logic
30068        // obj.get(keyName) returns friends array
30069      })
30070    });
30071    ```
30072  
30073    Also available as `Function.prototype.observesBefore` if prototype extensions are
30074    enabled.
30075  
30076    @method beforeObserver
30077    @for Ember
30078    @param {String} propertyNames*
30079    @param {Function} func
30080    @return func
30081    @deprecated
30082    @private
30083  */
30084
30085  function _beforeObserver() {
30086    for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
30087      args[_key5] = arguments[_key5];
30088    }
30089
30090    var func = args.slice(-1)[0];
30091    var paths;
30092
30093    var addWatchedProperty = function (path) {
30094      paths.push(path);
30095    };
30096
30097    var _paths = args.slice(0, -1);
30098
30099    if (typeof func !== 'function') {
30100      // revert to old, soft-deprecated argument ordering
30101
30102      func = args[0];
30103      _paths = args.slice(1);
30104    }
30105
30106    paths = [];
30107
30108    for (var i = 0; i < _paths.length; ++i) {
30109      _emberMetalExpand_properties.default(_paths[i], addWatchedProperty);
30110    }
30111
30112    if (typeof func !== 'function') {
30113      throw new _emberMetalCore.default.Error('Ember.beforeObserver called without a function');
30114    }
30115
30116    func.__ember_observesBefore__ = paths;
30117    return func;
30118  }
30119
30120  exports.IS_BINDING = IS_BINDING;
30121  exports.Mixin = Mixin;
30122  exports.required = required;
30123  exports.REQUIRED = REQUIRED;
30124});
30125// warn, assert, wrap, et;
30126enifed('ember-metal/observer', ['exports', 'ember-metal/watching', 'ember-metal/events'], function (exports, _emberMetalWatching, _emberMetalEvents) {
30127  'use strict';
30128
30129  exports.addObserver = addObserver;
30130  exports.observersFor = observersFor;
30131  exports.removeObserver = removeObserver;
30132  exports._addBeforeObserver = _addBeforeObserver;
30133  exports._suspendObserver = _suspendObserver;
30134  exports._suspendObservers = _suspendObservers;
30135  exports._removeBeforeObserver = _removeBeforeObserver;
30136
30137  /**
30138  @module ember-metal
30139  */
30140
30141  var AFTER_OBSERVERS = ':change';
30142  var BEFORE_OBSERVERS = ':before';
30143
30144  function changeEvent(keyName) {
30145    return keyName + AFTER_OBSERVERS;
30146  }
30147
30148  function beforeEvent(keyName) {
30149    return keyName + BEFORE_OBSERVERS;
30150  }
30151
30152  /**
30153    @method addObserver
30154    @for Ember
30155    @param obj
30156    @param {String} _path
30157    @param {Object|Function} target
30158    @param {Function|String} [method]
30159    @public
30160  */
30161
30162  function addObserver(obj, _path, target, method) {
30163    _emberMetalEvents.addListener(obj, changeEvent(_path), target, method);
30164    _emberMetalWatching.watch(obj, _path);
30165
30166    return this;
30167  }
30168
30169  function observersFor(obj, path) {
30170    return _emberMetalEvents.listenersFor(obj, changeEvent(path));
30171  }
30172
30173  /**
30174    @method removeObserver
30175    @for Ember
30176    @param obj
30177    @param {String} path
30178    @param {Object|Function} target
30179    @param {Function|String} [method]
30180    @public
30181  */
30182
30183  function removeObserver(obj, path, target, method) {
30184    _emberMetalWatching.unwatch(obj, path);
30185    _emberMetalEvents.removeListener(obj, changeEvent(path), target, method);
30186
30187    return this;
30188  }
30189
30190  /**
30191    @method _addBeforeObserver
30192    @for Ember
30193    @param obj
30194    @param {String} path
30195    @param {Object|Function} target
30196    @param {Function|String} [method]
30197    @deprecated
30198    @private
30199  */
30200
30201  function _addBeforeObserver(obj, path, target, method) {
30202    _emberMetalEvents.addListener(obj, beforeEvent(path), target, method);
30203    _emberMetalWatching.watch(obj, path);
30204
30205    return this;
30206  }
30207
30208  // Suspend observer during callback.
30209  //
30210  // This should only be used by the target of the observer
30211  // while it is setting the observed path.
30212
30213  function _suspendObserver(obj, path, target, method, callback) {
30214    return _emberMetalEvents.suspendListener(obj, changeEvent(path), target, method, callback);
30215  }
30216
30217  function _suspendObservers(obj, paths, target, method, callback) {
30218    var events = paths.map(changeEvent);
30219    return _emberMetalEvents.suspendListeners(obj, events, target, method, callback);
30220  }
30221
30222  /**
30223    @method removeBeforeObserver
30224    @for Ember
30225    @param obj
30226    @param {String} path
30227    @param {Object|Function} target
30228    @param {Function|String} [method]
30229    @deprecated
30230    @private
30231  */
30232
30233  function _removeBeforeObserver(obj, path, target, method) {
30234    _emberMetalWatching.unwatch(obj, path);
30235    _emberMetalEvents.removeListener(obj, beforeEvent(path), target, method);
30236
30237    return this;
30238  }
30239});
30240enifed('ember-metal/observer_set', ['exports', 'ember-metal/utils', 'ember-metal/events'], function (exports, _emberMetalUtils, _emberMetalEvents) {
30241  'use strict';
30242
30243  /*
30244    this.observerSet = {
30245      [senderGuid]: { // variable name: `keySet`
30246        [keyName]: listIndex
30247      }
30248    },
30249    this.observers = [
30250      {
30251        sender: obj,
30252        keyName: keyName,
30253        eventName: eventName,
30254        listeners: [
30255          [target, method, flags]
30256        ]
30257      },
30258      ...
30259    ]
30260  */
30261  exports.default = ObserverSet;
30262
30263  function ObserverSet() {
30264    this.clear();
30265  }
30266
30267  ObserverSet.prototype.add = function (sender, keyName, eventName) {
30268    var observerSet = this.observerSet;
30269    var observers = this.observers;
30270    var senderGuid = _emberMetalUtils.guidFor(sender);
30271    var keySet = observerSet[senderGuid];
30272    var index;
30273
30274    if (!keySet) {
30275      observerSet[senderGuid] = keySet = {};
30276    }
30277    index = keySet[keyName];
30278    if (index === undefined) {
30279      index = observers.push({
30280        sender: sender,
30281        keyName: keyName,
30282        eventName: eventName,
30283        listeners: []
30284      }) - 1;
30285      keySet[keyName] = index;
30286    }
30287    return observers[index].listeners;
30288  };
30289
30290  ObserverSet.prototype.flush = function () {
30291    var observers = this.observers;
30292    var i, len, observer, sender;
30293    this.clear();
30294    for (i = 0, len = observers.length; i < len; ++i) {
30295      observer = observers[i];
30296      sender = observer.sender;
30297      if (sender.isDestroying || sender.isDestroyed) {
30298        continue;
30299      }
30300      _emberMetalEvents.sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
30301    }
30302  };
30303
30304  ObserverSet.prototype.clear = function () {
30305    this.observerSet = {};
30306    this.observers = [];
30307  };
30308});
30309enifed('ember-metal/path_cache', ['exports', 'ember-metal/cache'], function (exports, _emberMetalCache) {
30310  'use strict';
30311
30312  exports.isGlobal = isGlobal;
30313  exports.isGlobalPath = isGlobalPath;
30314  exports.hasThis = hasThis;
30315  exports.isPath = isPath;
30316  exports.getFirstKey = getFirstKey;
30317  exports.getTailPath = getTailPath;
30318
30319  var IS_GLOBAL = /^[A-Z$]/;
30320  var IS_GLOBAL_PATH = /^[A-Z$].*[\.]/;
30321  var HAS_THIS = 'this.';
30322
30323  var isGlobalCache = new _emberMetalCache.default(1000, function (key) {
30324    return IS_GLOBAL.test(key);
30325  });
30326
30327  var isGlobalPathCache = new _emberMetalCache.default(1000, function (key) {
30328    return IS_GLOBAL_PATH.test(key);
30329  });
30330
30331  var hasThisCache = new _emberMetalCache.default(1000, function (key) {
30332    return key.lastIndexOf(HAS_THIS, 0) === 0;
30333  });
30334
30335  var firstDotIndexCache = new _emberMetalCache.default(1000, function (key) {
30336    return key.indexOf('.');
30337  });
30338
30339  var firstKeyCache = new _emberMetalCache.default(1000, function (path) {
30340    var index = firstDotIndexCache.get(path);
30341    if (index === -1) {
30342      return path;
30343    } else {
30344      return path.slice(0, index);
30345    }
30346  });
30347
30348  var tailPathCache = new _emberMetalCache.default(1000, function (path) {
30349    var index = firstDotIndexCache.get(path);
30350    if (index !== -1) {
30351      return path.slice(index + 1);
30352    }
30353  });
30354
30355  var caches = {
30356    isGlobalCache: isGlobalCache,
30357    isGlobalPathCache: isGlobalPathCache,
30358    hasThisCache: hasThisCache,
30359    firstDotIndexCache: firstDotIndexCache,
30360    firstKeyCache: firstKeyCache,
30361    tailPathCache: tailPathCache
30362  };
30363
30364  exports.caches = caches;
30365
30366  function isGlobal(path) {
30367    return isGlobalCache.get(path);
30368  }
30369
30370  function isGlobalPath(path) {
30371    return isGlobalPathCache.get(path);
30372  }
30373
30374  function hasThis(path) {
30375    return hasThisCache.get(path);
30376  }
30377
30378  function isPath(path) {
30379    return firstDotIndexCache.get(path) !== -1;
30380  }
30381
30382  function getFirstKey(path) {
30383    return firstKeyCache.get(path);
30384  }
30385
30386  function getTailPath(path) {
30387    return tailPathCache.get(path);
30388  }
30389});
30390enifed('ember-metal/properties', ['exports', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/meta', 'ember-metal/property_events'], function (exports, _emberMetalDebug, _emberMetalFeatures, _emberMetalMeta, _emberMetalProperty_events) {
30391  /**
30392  @module ember-metal
30393  */
30394
30395  'use strict';
30396
30397  exports.Descriptor = Descriptor;
30398  exports.MANDATORY_SETTER_FUNCTION = MANDATORY_SETTER_FUNCTION;
30399  exports.DEFAULT_GETTER_FUNCTION = DEFAULT_GETTER_FUNCTION;
30400  exports.INHERITING_GETTER_FUNCTION = INHERITING_GETTER_FUNCTION;
30401  exports.defineProperty = defineProperty;
30402
30403  // ..........................................................
30404  // DESCRIPTOR
30405  //
30406
30407  /**
30408    Objects of this type can implement an interface to respond to requests to
30409    get and set. The default implementation handles simple properties.
30410  
30411    @class Descriptor
30412    @private
30413  */
30414
30415  function Descriptor() {
30416    this.isDescriptor = true;
30417  }
30418
30419  var REDEFINE_SUPPORTED = (function () {
30420    // https://github.com/spalger/kibana/commit/b7e35e6737df585585332857a4c397dc206e7ff9
30421    var a = Object.create(Object.prototype, {
30422      prop: {
30423        configurable: true,
30424        value: 1
30425      }
30426    });
30427
30428    Object.defineProperty(a, 'prop', {
30429      configurable: true,
30430      value: 2
30431    });
30432
30433    return a.prop === 2;
30434  })();
30435  // ..........................................................
30436  // DEFINING PROPERTIES API
30437  //
30438
30439  function MANDATORY_SETTER_FUNCTION(name) {
30440    function SETTER_FUNCTION(value) {
30441      _emberMetalDebug.assert('You must use Ember.set() to set the `' + name + '` property (of ' + this + ') to `' + value + '`.', false);
30442    }
30443
30444    SETTER_FUNCTION.isMandatorySetter = true;
30445    return SETTER_FUNCTION;
30446  }
30447
30448  function DEFAULT_GETTER_FUNCTION(name) {
30449    return function GETTER_FUNCTION() {
30450      var meta = this['__ember_meta__'];
30451      return meta && meta.peekValues(name);
30452    };
30453  }
30454
30455  function INHERITING_GETTER_FUNCTION(name) {
30456    function IGETTER_FUNCTION() {
30457      var proto = Object.getPrototypeOf(this);
30458      return proto && proto[name];
30459    }
30460
30461    IGETTER_FUNCTION.isInheritingGetter = true;
30462    return IGETTER_FUNCTION;
30463  }
30464
30465  /**
30466    NOTE: This is a low-level method used by other parts of the API. You almost
30467    never want to call this method directly. Instead you should use
30468    `Ember.mixin()` to define new properties.
30469  
30470    Defines a property on an object. This method works much like the ES5
30471    `Object.defineProperty()` method except that it can also accept computed
30472    properties and other special descriptors.
30473  
30474    Normally this method takes only three parameters. However if you pass an
30475    instance of `Descriptor` as the third param then you can pass an
30476    optional value as the fourth parameter. This is often more efficient than
30477    creating new descriptor hashes for each property.
30478  
30479    ## Examples
30480  
30481    ```javascript
30482    // ES5 compatible mode
30483    Ember.defineProperty(contact, 'firstName', {
30484      writable: true,
30485      configurable: false,
30486      enumerable: true,
30487      value: 'Charles'
30488    });
30489  
30490    // define a simple property
30491    Ember.defineProperty(contact, 'lastName', undefined, 'Jolley');
30492  
30493    // define a computed property
30494    Ember.defineProperty(contact, 'fullName', Ember.computed('firstName', 'lastName', function() {
30495      return this.firstName+' '+this.lastName;
30496    }));
30497    ```
30498  
30499    @private
30500    @method defineProperty
30501    @for Ember
30502    @param {Object} obj the object to define this property on. This may be a prototype.
30503    @param {String} keyName the name of the property
30504    @param {Descriptor} [desc] an instance of `Descriptor` (typically a
30505      computed property) or an ES5 descriptor.
30506      You must provide this or `data` but not both.
30507    @param {*} [data] something other than a descriptor, that will
30508      become the explicit value of this property.
30509  */
30510
30511  function defineProperty(obj, keyName, desc, data, meta) {
30512    var possibleDesc, existingDesc, watching, value;
30513
30514    if (!meta) {
30515      meta = _emberMetalMeta.meta(obj);
30516    }
30517    var watchEntry = meta.peekWatching(keyName);
30518    possibleDesc = obj[keyName];
30519    existingDesc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
30520
30521    watching = watchEntry !== undefined && watchEntry > 0;
30522
30523    if (existingDesc) {
30524      existingDesc.teardown(obj, keyName);
30525    }
30526
30527    if (desc instanceof Descriptor) {
30528      value = desc;
30529
30530      if (watching) {
30531        Object.defineProperty(obj, keyName, {
30532          configurable: true,
30533          enumerable: true,
30534          writable: true,
30535          value: value
30536        });
30537      } else {
30538        obj[keyName] = value;
30539      }
30540
30541      if (desc.setup) {
30542        desc.setup(obj, keyName);
30543      }
30544    } else {
30545      if (desc == null) {
30546        value = data;
30547
30548        if (watching) {
30549          meta.writeValues(keyName, data);
30550
30551          var defaultDescriptor = {
30552            configurable: true,
30553            enumerable: true,
30554            set: MANDATORY_SETTER_FUNCTION(keyName),
30555            get: DEFAULT_GETTER_FUNCTION(keyName)
30556          };
30557
30558          if (REDEFINE_SUPPORTED) {
30559            Object.defineProperty(obj, keyName, defaultDescriptor);
30560          } else {
30561            handleBrokenPhantomDefineProperty(obj, keyName, defaultDescriptor);
30562          }
30563        } else {
30564          obj[keyName] = data;
30565        }
30566      } else {
30567        value = desc;
30568
30569        // fallback to ES5
30570        Object.defineProperty(obj, keyName, desc);
30571      }
30572    }
30573
30574    // if key is being watched, override chains that
30575    // were initialized with the prototype
30576    if (watching) {
30577      _emberMetalProperty_events.overrideChains(obj, keyName, meta);
30578    }
30579
30580    // The `value` passed to the `didDefineProperty` hook is
30581    // either the descriptor or data, whichever was passed.
30582    if (obj.didDefineProperty) {
30583      obj.didDefineProperty(obj, keyName, value);
30584    }
30585
30586    return this;
30587  }
30588
30589  function handleBrokenPhantomDefineProperty(obj, keyName, desc) {
30590    // https://github.com/ariya/phantomjs/issues/11856
30591    Object.defineProperty(obj, keyName, { configurable: true, writable: true, value: 'iCry' });
30592    Object.defineProperty(obj, keyName, desc);
30593  }
30594});
30595enifed('ember-metal/property_events', ['exports', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/events', 'ember-metal/observer_set', 'ember-metal/symbol'], function (exports, _emberMetalUtils, _emberMetalMeta, _emberMetalEvents, _emberMetalObserver_set, _emberMetalSymbol) {
30596  'use strict';
30597
30598  var PROPERTY_DID_CHANGE = _emberMetalSymbol.default('PROPERTY_DID_CHANGE');
30599
30600  exports.PROPERTY_DID_CHANGE = PROPERTY_DID_CHANGE;
30601  var beforeObserverSet = new _emberMetalObserver_set.default();
30602  var observerSet = new _emberMetalObserver_set.default();
30603  var deferred = 0;
30604
30605  // ..........................................................
30606  // PROPERTY CHANGES
30607  //
30608
30609  /**
30610    This function is called just before an object property is about to change.
30611    It will notify any before observers and prepare caches among other things.
30612  
30613    Normally you will not need to call this method directly but if for some
30614    reason you can't directly watch a property you can invoke this method
30615    manually along with `Ember.propertyDidChange()` which you should call just
30616    after the property value changes.
30617  
30618    @method propertyWillChange
30619    @for Ember
30620    @param {Object} obj The object with the property that will change
30621    @param {String} keyName The property key (or path) that will change.
30622    @return {void}
30623    @private
30624  */
30625  function propertyWillChange(obj, keyName) {
30626    var m = _emberMetalMeta.peekMeta(obj);
30627    var watching = m && m.peekWatching(keyName) > 0 || keyName === 'length';
30628    var proto = m && m.proto;
30629    var possibleDesc = obj[keyName];
30630    var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
30631
30632    if (!watching) {
30633      return;
30634    }
30635
30636    if (proto === obj) {
30637      return;
30638    }
30639
30640    if (desc && desc.willChange) {
30641      desc.willChange(obj, keyName);
30642    }
30643
30644    dependentKeysWillChange(obj, keyName, m);
30645    chainsWillChange(obj, keyName, m);
30646    notifyBeforeObservers(obj, keyName);
30647  }
30648
30649  /**
30650    This function is called just after an object property has changed.
30651    It will notify any observers and clear caches among other things.
30652  
30653    Normally you will not need to call this method directly but if for some
30654    reason you can't directly watch a property you can invoke this method
30655    manually along with `Ember.propertyWillChange()` which you should call just
30656    before the property value changes.
30657  
30658    @method propertyDidChange
30659    @for Ember
30660    @param {Object} obj The object with the property that will change
30661    @param {String} keyName The property key (or path) that will change.
30662    @return {void}
30663    @private
30664  */
30665  function propertyDidChange(obj, keyName) {
30666    var m = _emberMetalMeta.peekMeta(obj);
30667    var watching = m && m.peekWatching(keyName) > 0 || keyName === 'length';
30668    var proto = m && m.proto;
30669    var possibleDesc = obj[keyName];
30670    var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
30671
30672    if (proto === obj) {
30673      return;
30674    }
30675
30676    // shouldn't this mean that we're watching this key?
30677    if (desc && desc.didChange) {
30678      desc.didChange(obj, keyName);
30679    }
30680
30681    if (obj[PROPERTY_DID_CHANGE]) {
30682      obj[PROPERTY_DID_CHANGE](keyName);
30683    }
30684
30685    if (!watching && keyName !== 'length') {
30686      return;
30687    }
30688
30689    if (m && m.hasDeps(keyName)) {
30690      dependentKeysDidChange(obj, keyName, m);
30691    }
30692
30693    chainsDidChange(obj, keyName, m, false);
30694    notifyObservers(obj, keyName);
30695  }
30696
30697  var WILL_SEEN, DID_SEEN;
30698  // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
30699  function dependentKeysWillChange(obj, depKey, meta) {
30700    if (obj.isDestroying) {
30701      return;
30702    }
30703
30704    if (meta && meta.hasDeps(depKey)) {
30705      var seen = WILL_SEEN;
30706      var top = !seen;
30707
30708      if (top) {
30709        seen = WILL_SEEN = {};
30710      }
30711
30712      iterDeps(propertyWillChange, obj, depKey, seen, meta);
30713
30714      if (top) {
30715        WILL_SEEN = null;
30716      }
30717    }
30718  }
30719
30720  // called whenever a property has just changed to update dependent keys
30721  function dependentKeysDidChange(obj, depKey, meta) {
30722    if (obj.isDestroying) {
30723      return;
30724    }
30725
30726    if (meta && meta.hasDeps(depKey)) {
30727      var seen = DID_SEEN;
30728      var top = !seen;
30729
30730      if (top) {
30731        seen = DID_SEEN = {};
30732      }
30733
30734      iterDeps(propertyDidChange, obj, depKey, seen, meta);
30735
30736      if (top) {
30737        DID_SEEN = null;
30738      }
30739    }
30740  }
30741
30742  function iterDeps(method, obj, depKey, seen, meta) {
30743    var possibleDesc, desc;
30744    var guid = _emberMetalUtils.guidFor(obj);
30745    var current = seen[guid];
30746
30747    if (!current) {
30748      current = seen[guid] = {};
30749    }
30750
30751    if (current[depKey]) {
30752      return;
30753    }
30754
30755    current[depKey] = true;
30756
30757    meta.forEachInDeps(depKey, function (key, value) {
30758      if (!value) {
30759        return;
30760      }
30761
30762      possibleDesc = obj[key];
30763      desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
30764
30765      if (desc && desc._suspended === obj) {
30766        return;
30767      }
30768
30769      method(obj, key);
30770    });
30771  }
30772
30773  function chainsWillChange(obj, keyName, m) {
30774    var c = m.readableChainWatchers();
30775    if (c) {
30776      c.notify(keyName, false, propertyWillChange);
30777    }
30778  }
30779
30780  function chainsDidChange(obj, keyName, m) {
30781    var c = m.readableChainWatchers();
30782    if (c) {
30783      c.notify(keyName, true, propertyDidChange);
30784    }
30785  }
30786
30787  function overrideChains(obj, keyName, m) {
30788    var c = m.readableChainWatchers();
30789    if (c) {
30790      c.revalidate(keyName);
30791    }
30792  }
30793
30794  /**
30795    @method beginPropertyChanges
30796    @chainable
30797    @private
30798  */
30799  function beginPropertyChanges() {
30800    deferred++;
30801  }
30802
30803  /**
30804    @method endPropertyChanges
30805    @private
30806  */
30807  function endPropertyChanges() {
30808    deferred--;
30809    if (deferred <= 0) {
30810      beforeObserverSet.clear();
30811      observerSet.flush();
30812    }
30813  }
30814
30815  /**
30816    Make a series of property changes together in an
30817    exception-safe way.
30818  
30819    ```javascript
30820    Ember.changeProperties(function() {
30821      obj1.set('foo', mayBlowUpWhenSet);
30822      obj2.set('bar', baz);
30823    });
30824    ```
30825  
30826    @method changeProperties
30827    @param {Function} callback
30828    @param [binding]
30829    @private
30830  */
30831  function changeProperties(callback, binding) {
30832    beginPropertyChanges();
30833    try {
30834      callback.call(binding);
30835    } finally {
30836      endPropertyChanges.call(binding);
30837    }
30838  }
30839
30840  function notifyBeforeObservers(obj, keyName) {
30841    if (obj.isDestroying) {
30842      return;
30843    }
30844
30845    var eventName = keyName + ':before';
30846    var listeners, added;
30847    if (deferred) {
30848      listeners = beforeObserverSet.add(obj, keyName, eventName);
30849      added = _emberMetalEvents.accumulateListeners(obj, eventName, listeners);
30850      _emberMetalEvents.sendEvent(obj, eventName, [obj, keyName], added);
30851    } else {
30852      _emberMetalEvents.sendEvent(obj, eventName, [obj, keyName]);
30853    }
30854  }
30855
30856  function notifyObservers(obj, keyName) {
30857    if (obj.isDestroying) {
30858      return;
30859    }
30860
30861    var eventName = keyName + ':change';
30862    var listeners;
30863    if (deferred) {
30864      listeners = observerSet.add(obj, keyName, eventName);
30865      _emberMetalEvents.accumulateListeners(obj, eventName, listeners);
30866    } else {
30867      _emberMetalEvents.sendEvent(obj, eventName, [obj, keyName]);
30868    }
30869  }
30870
30871  exports.propertyWillChange = propertyWillChange;
30872  exports.propertyDidChange = propertyDidChange;
30873  exports.overrideChains = overrideChains;
30874  exports.beginPropertyChanges = beginPropertyChanges;
30875  exports.endPropertyChanges = endPropertyChanges;
30876  exports.changeProperties = changeProperties;
30877});
30878enifed('ember-metal/property_get', ['exports', 'ember-metal/debug', 'ember-metal/path_cache'], function (exports, _emberMetalDebug, _emberMetalPath_cache) {
30879  /**
30880  @module ember-metal
30881  */
30882
30883  'use strict';
30884
30885  exports.get = get;
30886  exports._getPath = _getPath;
30887  exports.getWithDefault = getWithDefault;
30888
30889  // ..........................................................
30890  // GET AND SET
30891  //
30892  // If we are on a platform that supports accessors we can use those.
30893  // Otherwise simulate accessors by looking up the property directly on the
30894  // object.
30895
30896  /**
30897    Gets the value of a property on an object. If the property is computed,
30898    the function will be invoked. If the property is not defined but the
30899    object implements the `unknownProperty` method then that will be invoked.
30900  
30901    If you plan to run on IE8 and older browsers then you should use this
30902    method anytime you want to retrieve a property on an object that you don't
30903    know for sure is private. (Properties beginning with an underscore '_'
30904    are considered private.)
30905  
30906    On all newer browsers, you only need to use this method to retrieve
30907    properties if the property might not be defined on the object and you want
30908    to respect the `unknownProperty` handler. Otherwise you can ignore this
30909    method.
30910  
30911    Note that if the object itself is `undefined`, this method will throw
30912    an error.
30913  
30914    @method get
30915    @for Ember
30916    @param {Object} obj The object to retrieve from.
30917    @param {String} keyName The property key to retrieve
30918    @return {Object} the property value or `null`.
30919    @public
30920  */
30921
30922  function get(obj, keyName) {
30923    _emberMetalDebug.assert('Get must be called with two arguments; an object and a property key', arguments.length === 2);
30924    _emberMetalDebug.assert('Cannot call get with \'' + keyName + '\' on an undefined object.', obj !== undefined && obj !== null);
30925    _emberMetalDebug.assert('The key provided to get must be a string, you passed ' + keyName, typeof keyName === 'string');
30926    _emberMetalDebug.assert('\'this\' in paths is not supported', !_emberMetalPath_cache.hasThis(keyName));
30927
30928    // Helpers that operate with 'this' within an #each
30929    if (keyName === '') {
30930      return obj;
30931    }
30932
30933    var value = obj[keyName];
30934    var desc = value !== null && typeof value === 'object' && value.isDescriptor ? value : undefined;
30935    var ret;
30936
30937    if (desc === undefined && _emberMetalPath_cache.isPath(keyName)) {
30938      return _getPath(obj, keyName);
30939    }
30940
30941    if (desc) {
30942      return desc.get(obj, keyName);
30943    } else {
30944      ret = value;
30945
30946      if (ret === undefined && 'object' === typeof obj && !(keyName in obj) && 'function' === typeof obj.unknownProperty) {
30947        return obj.unknownProperty(keyName);
30948      }
30949
30950      return ret;
30951    }
30952  }
30953
30954  function _getPath(root, path) {
30955    var obj = root;
30956    var parts = path.split('.');
30957    var len = parts.length;
30958
30959    for (var i = 0; i < len; i++) {
30960      if (obj == null) {
30961        return obj;
30962      }
30963
30964      obj = get(obj, parts[i]);
30965
30966      if (obj && obj.isDestroyed) {
30967        return undefined;
30968      }
30969    }
30970
30971    return obj;
30972  }
30973
30974  /**
30975    Retrieves the value of a property from an Object, or a default value in the
30976    case that the property returns `undefined`.
30977  
30978    ```javascript
30979    Ember.getWithDefault(person, 'lastName', 'Doe');
30980    ```
30981  
30982    @method getWithDefault
30983    @for Ember
30984    @param {Object} obj The object to retrieve from.
30985    @param {String} keyName The name of the property to retrieve
30986    @param {Object} defaultValue The value to return if the property value is undefined
30987    @return {Object} The property value or the defaultValue.
30988    @public
30989  */
30990
30991  function getWithDefault(root, key, defaultValue) {
30992    var value = get(root, key);
30993
30994    if (value === undefined) {
30995      return defaultValue;
30996    }
30997    return value;
30998  }
30999
31000  exports.default = get;
31001});
31002enifed('ember-metal/property_set', ['exports', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/property_get', 'ember-metal/property_events', 'ember-metal/properties', 'ember-metal/error', 'ember-metal/path_cache', 'ember-metal/meta', 'ember-metal/utils'], function (exports, _emberMetalDebug, _emberMetalFeatures, _emberMetalProperty_get, _emberMetalProperty_events, _emberMetalProperties, _emberMetalError, _emberMetalPath_cache, _emberMetalMeta, _emberMetalUtils) {
31003  'use strict';
31004
31005  exports.set = set;
31006  exports.trySet = trySet;
31007
31008  /**
31009    Sets the value of a property on an object, respecting computed properties
31010    and notifying observers and other listeners of the change. If the
31011    property is not defined but the object implements the `setUnknownProperty`
31012    method then that will be invoked as well.
31013  
31014    @method set
31015    @for Ember
31016    @param {Object} obj The object to modify.
31017    @param {String} keyName The property key to set
31018    @param {Object} value The value to set
31019    @return {Object} the passed value.
31020    @public
31021  */
31022
31023  function set(obj, keyName, value, tolerant) {
31024    _emberMetalDebug.assert('Set must be called with three or four arguments; an object, a property key, a value and tolerant true/false', arguments.length === 3 || arguments.length === 4);
31025    _emberMetalDebug.assert('Cannot call set with \'' + keyName + '\' on an undefined object.', obj !== undefined && obj !== null);
31026    _emberMetalDebug.assert('The key provided to set must be a string, you passed ' + keyName, typeof keyName === 'string');
31027    _emberMetalDebug.assert('\'this\' in paths is not supported', !_emberMetalPath_cache.hasThis(keyName));
31028
31029    var meta, possibleDesc, desc;
31030    if (obj) {
31031      meta = _emberMetalMeta.peekMeta(obj);
31032      possibleDesc = obj[keyName];
31033      desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
31034    }
31035
31036    var isUnknown, currentValue;
31037    if (desc === undefined && _emberMetalPath_cache.isPath(keyName)) {
31038      return setPath(obj, keyName, value, tolerant);
31039    }
31040
31041    _emberMetalDebug.assert('calling set on destroyed object: ' + _emberMetalUtils.toString(obj) + '.' + keyName + ' = ' + _emberMetalUtils.toString(value), !obj.isDestroyed);
31042
31043    if (desc) {
31044      desc.set(obj, keyName, value);
31045    } else {
31046      if (value !== undefined && typeof obj === 'object' && obj[keyName] === value) {
31047        return value;
31048      }
31049
31050      isUnknown = 'object' === typeof obj && !(keyName in obj);
31051
31052      // setUnknownProperty is called if `obj` is an object,
31053      // the property does not already exist, and the
31054      // `setUnknownProperty` method exists on the object
31055      if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
31056        obj.setUnknownProperty(keyName, value);
31057      } else if (meta && meta.peekWatching(keyName) > 0) {
31058        if (meta.proto !== obj) {
31059          currentValue = obj[keyName];
31060        }
31061        // only trigger a change if the value has changed
31062        if (value !== currentValue) {
31063          _emberMetalProperty_events.propertyWillChange(obj, keyName);
31064
31065          if (currentValue === undefined && !(keyName in obj) || !Object.prototype.propertyIsEnumerable.call(obj, keyName)) {
31066            _emberMetalProperties.defineProperty(obj, keyName, null, value); // setup mandatory setter
31067          } else {
31068              var descriptor = _emberMetalUtils.lookupDescriptor(obj, keyName);
31069              var isMandatorySetter = descriptor && descriptor.set && descriptor.set.isMandatorySetter;
31070              if (isMandatorySetter) {
31071                meta.writeValues(keyName, value);
31072              } else {
31073                obj[keyName] = value;
31074              }
31075            }
31076
31077          _emberMetalProperty_events.propertyDidChange(obj, keyName);
31078        }
31079      } else {
31080        obj[keyName] = value;
31081        if (obj[_emberMetalProperty_events.PROPERTY_DID_CHANGE]) {
31082          obj[_emberMetalProperty_events.PROPERTY_DID_CHANGE](keyName);
31083        }
31084      }
31085    }
31086    return value;
31087  }
31088
31089  function setPath(root, path, value, tolerant) {
31090    var keyName;
31091
31092    // get the last part of the path
31093    keyName = path.slice(path.lastIndexOf('.') + 1);
31094
31095    // get the first part of the part
31096    path = path === keyName ? keyName : path.slice(0, path.length - (keyName.length + 1));
31097
31098    // unless the path is this, look up the first part to
31099    // get the root
31100    if (path !== 'this') {
31101      root = _emberMetalProperty_get._getPath(root, path);
31102    }
31103
31104    if (!keyName || keyName.length === 0) {
31105      throw new _emberMetalError.default('Property set failed: You passed an empty path');
31106    }
31107
31108    if (!root) {
31109      if (tolerant) {
31110        return;
31111      } else {
31112        throw new _emberMetalError.default('Property set failed: object in path "' + path + '" could not be found or was destroyed.');
31113      }
31114    }
31115
31116    return set(root, keyName, value);
31117  }
31118
31119  /**
31120    Error-tolerant form of `Ember.set`. Will not blow up if any part of the
31121    chain is `undefined`, `null`, or destroyed.
31122  
31123    This is primarily used when syncing bindings, which may try to update after
31124    an object has been destroyed.
31125  
31126    @method trySet
31127    @for Ember
31128    @param {Object} root The object to modify.
31129    @param {String} path The property path to set
31130    @param {Object} value The value to set
31131    @public
31132  */
31133
31134  function trySet(root, path, value) {
31135    return set(root, path, value, true);
31136  }
31137});
31138enifed("ember-metal/replace", ["exports"], function (exports) {
31139  "use strict";
31140
31141  exports._replace = _replace;
31142  exports.default = replace;
31143  var splice = Array.prototype.splice;
31144
31145  function _replace(array, idx, amt, objects) {
31146    var args = [].concat(objects);
31147    var ret = [];
31148    // https://code.google.com/p/chromium/issues/detail?id=56588
31149    var size = 60000;
31150    var start = idx;
31151    var ends = amt;
31152    var count, chunk;
31153
31154    while (args.length) {
31155      count = ends > size ? size : ends;
31156      if (count <= 0) {
31157        count = 0;
31158      }
31159
31160      chunk = args.splice(0, size);
31161      chunk = [start, count].concat(chunk);
31162
31163      start += size;
31164      ends -= count;
31165
31166      ret = ret.concat(splice.apply(array, chunk));
31167    }
31168    return ret;
31169  }
31170
31171  /**
31172    Replaces objects in an array with the passed objects.
31173  
31174    ```javascript
31175      var array = [1,2,3];
31176      Ember.EnumerableUtils.replace(array, 1, 2, [4, 5]); // [1, 4, 5]
31177  
31178      var array = [1,2,3];
31179      Ember.EnumerableUtils.replace(array, 1, 1, [4, 5]); // [1, 4, 5, 3]
31180  
31181      var array = [1,2,3];
31182      Ember.EnumerableUtils.replace(array, 10, 1, [4, 5]); // [1, 2, 3, 4, 5]
31183    ```
31184  
31185    @method replace
31186    @deprecated
31187    @param {Array} array The array the objects should be inserted into.
31188    @param {Number} idx Starting index in the array to replace. If *idx* >=
31189    length, then append to the end of the array.
31190    @param {Number} amt Number of elements that should be removed from the array,
31191    starting at *idx*
31192    @param {Array} objects An array of zero or more objects that should be
31193    inserted into the array at *idx*
31194  
31195    @return {Array} The modified array.
31196    @public
31197  */
31198
31199  function replace(array, idx, amt, objects) {
31200    if (array.replace) {
31201      return array.replace(idx, amt, objects);
31202    } else {
31203      return _replace(array, idx, amt, objects);
31204    }
31205  }
31206});
31207enifed('ember-metal/run_loop', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/property_events', 'backburner'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalUtils, _emberMetalProperty_events, _backburner) {
31208  'use strict';
31209
31210  exports.default = run;
31211
31212  function onBegin(current) {
31213    run.currentRunLoop = current;
31214  }
31215
31216  function onEnd(current, next) {
31217    run.currentRunLoop = next;
31218  }
31219
31220  // ES6TODO: should Backburner become es6?
31221  var backburner = new _backburner.default(['sync', 'actions', 'destroy'], {
31222    GUID_KEY: _emberMetalUtils.GUID_KEY,
31223    sync: {
31224      before: _emberMetalProperty_events.beginPropertyChanges,
31225      after: _emberMetalProperty_events.endPropertyChanges
31226    },
31227    defaultQueue: 'actions',
31228    onBegin: onBegin,
31229    onEnd: onEnd,
31230    onErrorTarget: _emberMetalCore.default,
31231    onErrorMethod: 'onerror'
31232  });
31233
31234  // ..........................................................
31235  // run - this is ideally the only public API the dev sees
31236  //
31237
31238  /**
31239    Runs the passed target and method inside of a RunLoop, ensuring any
31240    deferred actions including bindings and views updates are flushed at the
31241    end.
31242  
31243    Normally you should not need to invoke this method yourself. However if
31244    you are implementing raw event handlers when interfacing with other
31245    libraries or plugins, you should probably wrap all of your code inside this
31246    call.
31247  
31248    ```javascript
31249    run(function() {
31250      // code to be executed within a RunLoop
31251    });
31252    ```
31253  
31254    @class run
31255    @namespace Ember
31256    @static
31257    @constructor
31258    @param {Object} [target] target of method to call
31259    @param {Function|String} method Method to invoke.
31260      May be a function or a string. If you pass a string
31261      then it will be looked up on the passed target.
31262    @param {Object} [args*] Any additional arguments you wish to pass to the method.
31263    @return {Object} return value from invoking the passed function.
31264    @public
31265  */
31266
31267  function run() {
31268    return backburner.run.apply(backburner, arguments);
31269  }
31270
31271  /**
31272    If no run-loop is present, it creates a new one. If a run loop is
31273    present it will queue itself to run on the existing run-loops action
31274    queue.
31275  
31276    Please note: This is not for normal usage, and should be used sparingly.
31277  
31278    If invoked when not within a run loop:
31279  
31280    ```javascript
31281    run.join(function() {
31282      // creates a new run-loop
31283    });
31284    ```
31285  
31286    Alternatively, if called within an existing run loop:
31287  
31288    ```javascript
31289    run(function() {
31290      // creates a new run-loop
31291      run.join(function() {
31292        // joins with the existing run-loop, and queues for invocation on
31293        // the existing run-loops action queue.
31294      });
31295    });
31296    ```
31297  
31298    @method join
31299    @namespace Ember
31300    @param {Object} [target] target of method to call
31301    @param {Function|String} method Method to invoke.
31302      May be a function or a string. If you pass a string
31303      then it will be looked up on the passed target.
31304    @param {Object} [args*] Any additional arguments you wish to pass to the method.
31305    @return {Object} Return value from invoking the passed function. Please note,
31306    when called within an existing loop, no return value is possible.
31307    @public
31308  */
31309  run.join = function () {
31310    return backburner.join.apply(backburner, arguments);
31311  };
31312
31313  /**
31314    Allows you to specify which context to call the specified function in while
31315    adding the execution of that function to the Ember run loop. This ability
31316    makes this method a great way to asynchronously integrate third-party libraries
31317    into your Ember application.
31318  
31319    `run.bind` takes two main arguments, the desired context and the function to
31320    invoke in that context. Any additional arguments will be supplied as arguments
31321    to the function that is passed in.
31322  
31323    Let's use the creation of a TinyMCE component as an example. Currently,
31324    TinyMCE provides a setup configuration option we can use to do some processing
31325    after the TinyMCE instance is initialized but before it is actually rendered.
31326    We can use that setup option to do some additional setup for our component.
31327    The component itself could look something like the following:
31328  
31329    ```javascript
31330    App.RichTextEditorComponent = Ember.Component.extend({
31331      initializeTinyMCE: Ember.on('didInsertElement', function() {
31332        tinymce.init({
31333          selector: '#' + this.$().prop('id'),
31334          setup: Ember.run.bind(this, this.setupEditor)
31335        });
31336      }),
31337  
31338      setupEditor: function(editor) {
31339        this.set('editor', editor);
31340  
31341        editor.on('change', function() {
31342          console.log('content changed!');
31343        });
31344      }
31345    });
31346    ```
31347  
31348    In this example, we use Ember.run.bind to bind the setupEditor method to the
31349    context of the App.RichTextEditorComponent and to have the invocation of that
31350    method be safely handled and executed by the Ember run loop.
31351  
31352    @method bind
31353    @namespace Ember
31354    @param {Object} [target] target of method to call
31355    @param {Function|String} method Method to invoke.
31356      May be a function or a string. If you pass a string
31357      then it will be looked up on the passed target.
31358    @param {Object} [args*] Any additional arguments you wish to pass to the method.
31359    @return {Function} returns a new function that will always have a particular context
31360    @since 1.4.0
31361    @public
31362  */
31363  run.bind = function () {
31364    for (var _len = arguments.length, curried = Array(_len), _key = 0; _key < _len; _key++) {
31365      curried[_key] = arguments[_key];
31366    }
31367
31368    return function () {
31369      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
31370        args[_key2] = arguments[_key2];
31371      }
31372
31373      return run.join.apply(run, curried.concat(args));
31374    };
31375  };
31376
31377  run.backburner = backburner;
31378  run.currentRunLoop = null;
31379  run.queues = backburner.queueNames;
31380
31381  /**
31382    Begins a new RunLoop. Any deferred actions invoked after the begin will
31383    be buffered until you invoke a matching call to `run.end()`. This is
31384    a lower-level way to use a RunLoop instead of using `run()`.
31385  
31386    ```javascript
31387    run.begin();
31388    // code to be executed within a RunLoop
31389    run.end();
31390    ```
31391  
31392    @method begin
31393    @return {void}
31394    @public
31395  */
31396  run.begin = function () {
31397    backburner.begin();
31398  };
31399
31400  /**
31401    Ends a RunLoop. This must be called sometime after you call
31402    `run.begin()` to flush any deferred actions. This is a lower-level way
31403    to use a RunLoop instead of using `run()`.
31404  
31405    ```javascript
31406    run.begin();
31407    // code to be executed within a RunLoop
31408    run.end();
31409    ```
31410  
31411    @method end
31412    @return {void}
31413    @public
31414  */
31415  run.end = function () {
31416    backburner.end();
31417  };
31418
31419  /**
31420    Array of named queues. This array determines the order in which queues
31421    are flushed at the end of the RunLoop. You can define your own queues by
31422    simply adding the queue name to this array. Normally you should not need
31423    to inspect or modify this property.
31424  
31425    @property queues
31426    @type Array
31427    @default ['sync', 'actions', 'destroy']
31428    @private
31429  */
31430
31431  /**
31432    Adds the passed target/method and any optional arguments to the named
31433    queue to be executed at the end of the RunLoop. If you have not already
31434    started a RunLoop when calling this method one will be started for you
31435    automatically.
31436  
31437    At the end of a RunLoop, any methods scheduled in this way will be invoked.
31438    Methods will be invoked in an order matching the named queues defined in
31439    the `run.queues` property.
31440  
31441    ```javascript
31442    run.schedule('sync', this, function() {
31443      // this will be executed in the first RunLoop queue, when bindings are synced
31444      console.log('scheduled on sync queue');
31445    });
31446  
31447    run.schedule('actions', this, function() {
31448      // this will be executed in the 'actions' queue, after bindings have synced.
31449      console.log('scheduled on actions queue');
31450    });
31451  
31452    // Note the functions will be run in order based on the run queues order.
31453    // Output would be:
31454    //   scheduled on sync queue
31455    //   scheduled on actions queue
31456    ```
31457  
31458    @method schedule
31459    @param {String} queue The name of the queue to schedule against.
31460      Default queues are 'sync' and 'actions'
31461    @param {Object} [target] target object to use as the context when invoking a method.
31462    @param {String|Function} method The method to invoke. If you pass a string it
31463      will be resolved on the target object at the time the scheduled item is
31464      invoked allowing you to change the target function.
31465    @param {Object} [arguments*] Optional arguments to be passed to the queued method.
31466    @return {void}
31467    @public
31468  */
31469  run.schedule = function () /* queue, target, method */{
31470    checkAutoRun();
31471    backburner.schedule.apply(backburner, arguments);
31472  };
31473
31474  // Used by global test teardown
31475  run.hasScheduledTimers = function () {
31476    return backburner.hasTimers();
31477  };
31478
31479  // Used by global test teardown
31480  run.cancelTimers = function () {
31481    backburner.cancelTimers();
31482  };
31483
31484  /**
31485    Immediately flushes any events scheduled in the 'sync' queue. Bindings
31486    use this queue so this method is a useful way to immediately force all
31487    bindings in the application to sync.
31488  
31489    You should call this method anytime you need any changed state to propagate
31490    throughout the app immediately without repainting the UI (which happens
31491    in the later 'render' queue added by the `ember-views` package).
31492  
31493    ```javascript
31494    run.sync();
31495    ```
31496  
31497    @method sync
31498    @return {void}
31499    @private
31500  */
31501  run.sync = function () {
31502    if (backburner.currentInstance) {
31503      backburner.currentInstance.queues.sync.flush();
31504    }
31505  };
31506
31507  /**
31508    Invokes the passed target/method and optional arguments after a specified
31509    period of time. The last parameter of this method must always be a number
31510    of milliseconds.
31511  
31512    You should use this method whenever you need to run some action after a
31513    period of time instead of using `setTimeout()`. This method will ensure that
31514    items that expire during the same script execution cycle all execute
31515    together, which is often more efficient than using a real setTimeout.
31516  
31517    ```javascript
31518    run.later(myContext, function() {
31519      // code here will execute within a RunLoop in about 500ms with this == myContext
31520    }, 500);
31521    ```
31522  
31523    @method later
31524    @param {Object} [target] target of method to invoke
31525    @param {Function|String} method The method to invoke.
31526      If you pass a string it will be resolved on the
31527      target at the time the method is invoked.
31528    @param {Object} [args*] Optional arguments to pass to the timeout.
31529    @param {Number} wait Number of milliseconds to wait.
31530    @return {*} Timer information for use in cancelling, see `run.cancel`.
31531    @public
31532  */
31533  run.later = function () /*target, method*/{
31534    return backburner.later.apply(backburner, arguments);
31535  };
31536
31537  /**
31538    Schedule a function to run one time during the current RunLoop. This is equivalent
31539    to calling `scheduleOnce` with the "actions" queue.
31540  
31541    @method once
31542    @param {Object} [target] The target of the method to invoke.
31543    @param {Function|String} method The method to invoke.
31544      If you pass a string it will be resolved on the
31545      target at the time the method is invoked.
31546    @param {Object} [args*] Optional arguments to pass to the timeout.
31547    @return {Object} Timer information for use in cancelling, see `run.cancel`.
31548    @public
31549  */
31550  run.once = function () {
31551    checkAutoRun();
31552
31553    for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
31554      args[_key3] = arguments[_key3];
31555    }
31556
31557    args.unshift('actions');
31558    return backburner.scheduleOnce.apply(backburner, args);
31559  };
31560
31561  /**
31562    Schedules a function to run one time in a given queue of the current RunLoop.
31563    Calling this method with the same queue/target/method combination will have
31564    no effect (past the initial call).
31565  
31566    Note that although you can pass optional arguments these will not be
31567    considered when looking for duplicates. New arguments will replace previous
31568    calls.
31569  
31570    ```javascript
31571    function sayHi() {
31572      console.log('hi');
31573    }
31574  
31575    run(function() {
31576      run.scheduleOnce('afterRender', myContext, sayHi);
31577      run.scheduleOnce('afterRender', myContext, sayHi);
31578      // sayHi will only be executed once, in the afterRender queue of the RunLoop
31579    });
31580    ```
31581  
31582    Also note that passing an anonymous function to `run.scheduleOnce` will
31583    not prevent additional calls with an identical anonymous function from
31584    scheduling the items multiple times, e.g.:
31585  
31586    ```javascript
31587    function scheduleIt() {
31588      run.scheduleOnce('actions', myContext, function() {
31589        console.log('Closure');
31590      });
31591    }
31592  
31593    scheduleIt();
31594    scheduleIt();
31595  
31596    // "Closure" will print twice, even though we're using `run.scheduleOnce`,
31597    // because the function we pass to it is anonymous and won't match the
31598    // previously scheduled operation.
31599    ```
31600  
31601    Available queues, and their order, can be found at `run.queues`
31602  
31603    @method scheduleOnce
31604    @param {String} [queue] The name of the queue to schedule against. Default queues are 'sync' and 'actions'.
31605    @param {Object} [target] The target of the method to invoke.
31606    @param {Function|String} method The method to invoke.
31607      If you pass a string it will be resolved on the
31608      target at the time the method is invoked.
31609    @param {Object} [args*] Optional arguments to pass to the timeout.
31610    @return {Object} Timer information for use in cancelling, see `run.cancel`.
31611    @public
31612  */
31613  run.scheduleOnce = function () /*queue, target, method*/{
31614    checkAutoRun();
31615    return backburner.scheduleOnce.apply(backburner, arguments);
31616  };
31617
31618  /**
31619    Schedules an item to run from within a separate run loop, after
31620    control has been returned to the system. This is equivalent to calling
31621    `run.later` with a wait time of 1ms.
31622  
31623    ```javascript
31624    run.next(myContext, function() {
31625      // code to be executed in the next run loop,
31626      // which will be scheduled after the current one
31627    });
31628    ```
31629  
31630    Multiple operations scheduled with `run.next` will coalesce
31631    into the same later run loop, along with any other operations
31632    scheduled by `run.later` that expire right around the same
31633    time that `run.next` operations will fire.
31634  
31635    Note that there are often alternatives to using `run.next`.
31636    For instance, if you'd like to schedule an operation to happen
31637    after all DOM element operations have completed within the current
31638    run loop, you can make use of the `afterRender` run loop queue (added
31639    by the `ember-views` package, along with the preceding `render` queue
31640    where all the DOM element operations happen). Example:
31641  
31642    ```javascript
31643    App.MyCollectionView = Ember.CollectionView.extend({
31644      didInsertElement: function() {
31645        run.scheduleOnce('afterRender', this, 'processChildElements');
31646      },
31647      processChildElements: function() {
31648        // ... do something with collectionView's child view
31649        // elements after they've finished rendering, which
31650        // can't be done within the CollectionView's
31651        // `didInsertElement` hook because that gets run
31652        // before the child elements have been added to the DOM.
31653      }
31654    });
31655    ```
31656  
31657    One benefit of the above approach compared to using `run.next` is
31658    that you will be able to perform DOM/CSS operations before unprocessed
31659    elements are rendered to the screen, which may prevent flickering or
31660    other artifacts caused by delaying processing until after rendering.
31661  
31662    The other major benefit to the above approach is that `run.next`
31663    introduces an element of non-determinism, which can make things much
31664    harder to test, due to its reliance on `setTimeout`; it's much harder
31665    to guarantee the order of scheduled operations when they are scheduled
31666    outside of the current run loop, i.e. with `run.next`.
31667  
31668    @method next
31669    @param {Object} [target] target of method to invoke
31670    @param {Function|String} method The method to invoke.
31671      If you pass a string it will be resolved on the
31672      target at the time the method is invoked.
31673    @param {Object} [args*] Optional arguments to pass to the timeout.
31674    @return {Object} Timer information for use in cancelling, see `run.cancel`.
31675    @public
31676  */
31677  run.next = function () {
31678    for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
31679      args[_key4] = arguments[_key4];
31680    }
31681
31682    args.push(1);
31683    return backburner.later.apply(backburner, args);
31684  };
31685
31686  /**
31687    Cancels a scheduled item. Must be a value returned by `run.later()`,
31688    `run.once()`, `run.scheduleOnce()`, `run.next()`, `run.debounce()`, or
31689    `run.throttle()`.
31690  
31691    ```javascript
31692    var runNext = run.next(myContext, function() {
31693      // will not be executed
31694    });
31695  
31696    run.cancel(runNext);
31697  
31698    var runLater = run.later(myContext, function() {
31699      // will not be executed
31700    }, 500);
31701  
31702    run.cancel(runLater);
31703  
31704    var runScheduleOnce = run.scheduleOnce('afterRender', myContext, function() {
31705      // will not be executed
31706    });
31707  
31708    run.cancel(runScheduleOnce);
31709  
31710    var runOnce = run.once(myContext, function() {
31711      // will not be executed
31712    });
31713  
31714    run.cancel(runOnce);
31715  
31716    var throttle = run.throttle(myContext, function() {
31717      // will not be executed
31718    }, 1, false);
31719  
31720    run.cancel(throttle);
31721  
31722    var debounce = run.debounce(myContext, function() {
31723      // will not be executed
31724    }, 1);
31725  
31726    run.cancel(debounce);
31727  
31728    var debounceImmediate = run.debounce(myContext, function() {
31729      // will be executed since we passed in true (immediate)
31730    }, 100, true);
31731  
31732    // the 100ms delay until this method can be called again will be cancelled
31733    run.cancel(debounceImmediate);
31734    ```
31735  
31736    @method cancel
31737    @param {Object} timer Timer object to cancel
31738    @return {Boolean} true if cancelled or false/undefined if it wasn't found
31739    @public
31740  */
31741  run.cancel = function (timer) {
31742    return backburner.cancel(timer);
31743  };
31744
31745  /**
31746    Delay calling the target method until the debounce period has elapsed
31747    with no additional debounce calls. If `debounce` is called again before
31748    the specified time has elapsed, the timer is reset and the entire period
31749    must pass again before the target method is called.
31750  
31751    This method should be used when an event may be called multiple times
31752    but the action should only be called once when the event is done firing.
31753    A common example is for scroll events where you only want updates to
31754    happen once scrolling has ceased.
31755  
31756    ```javascript
31757    function whoRan() {
31758      console.log(this.name + ' ran.');
31759    }
31760  
31761    var myContext = { name: 'debounce' };
31762  
31763    run.debounce(myContext, whoRan, 150);
31764  
31765    // less than 150ms passes
31766    run.debounce(myContext, whoRan, 150);
31767  
31768    // 150ms passes
31769    // whoRan is invoked with context myContext
31770    // console logs 'debounce ran.' one time.
31771    ```
31772  
31773    Immediate allows you to run the function immediately, but debounce
31774    other calls for this function until the wait time has elapsed. If
31775    `debounce` is called again before the specified time has elapsed,
31776    the timer is reset and the entire period must pass again before
31777    the method can be called again.
31778  
31779    ```javascript
31780    function whoRan() {
31781      console.log(this.name + ' ran.');
31782    }
31783  
31784    var myContext = { name: 'debounce' };
31785  
31786    run.debounce(myContext, whoRan, 150, true);
31787  
31788    // console logs 'debounce ran.' one time immediately.
31789    // 100ms passes
31790    run.debounce(myContext, whoRan, 150, true);
31791  
31792    // 150ms passes and nothing else is logged to the console and
31793    // the debouncee is no longer being watched
31794    run.debounce(myContext, whoRan, 150, true);
31795  
31796    // console logs 'debounce ran.' one time immediately.
31797    // 150ms passes and nothing else is logged to the console and
31798    // the debouncee is no longer being watched
31799  
31800    ```
31801  
31802    @method debounce
31803    @param {Object} [target] target of method to invoke
31804    @param {Function|String} method The method to invoke.
31805      May be a function or a string. If you pass a string
31806      then it will be looked up on the passed target.
31807    @param {Object} [args*] Optional arguments to pass to the timeout.
31808    @param {Number} wait Number of milliseconds to wait.
31809    @param {Boolean} immediate Trigger the function on the leading instead
31810      of the trailing edge of the wait interval. Defaults to false.
31811    @return {Array} Timer information for use in cancelling, see `run.cancel`.
31812    @public
31813  */
31814  run.debounce = function () {
31815    return backburner.debounce.apply(backburner, arguments);
31816  };
31817
31818  /**
31819    Ensure that the target method is never called more frequently than
31820    the specified spacing period. The target method is called immediately.
31821  
31822    ```javascript
31823    function whoRan() {
31824      console.log(this.name + ' ran.');
31825    }
31826  
31827    var myContext = { name: 'throttle' };
31828  
31829    run.throttle(myContext, whoRan, 150);
31830    // whoRan is invoked with context myContext
31831    // console logs 'throttle ran.'
31832  
31833    // 50ms passes
31834    run.throttle(myContext, whoRan, 150);
31835  
31836    // 50ms passes
31837    run.throttle(myContext, whoRan, 150);
31838  
31839    // 150ms passes
31840    run.throttle(myContext, whoRan, 150);
31841    // whoRan is invoked with context myContext
31842    // console logs 'throttle ran.'
31843    ```
31844  
31845    @method throttle
31846    @param {Object} [target] target of method to invoke
31847    @param {Function|String} method The method to invoke.
31848      May be a function or a string. If you pass a string
31849      then it will be looked up on the passed target.
31850    @param {Object} [args*] Optional arguments to pass to the timeout.
31851    @param {Number} spacing Number of milliseconds to space out requests.
31852    @param {Boolean} immediate Trigger the function on the leading instead
31853      of the trailing edge of the wait interval. Defaults to true.
31854    @return {Array} Timer information for use in cancelling, see `run.cancel`.
31855    @public
31856  */
31857  run.throttle = function () {
31858    return backburner.throttle.apply(backburner, arguments);
31859  };
31860
31861  // Make sure it's not an autorun during testing
31862  function checkAutoRun() {
31863    if (!run.currentRunLoop) {
31864      _emberMetalDebug.assert('You have turned on testing mode, which disabled the run-loop\'s autorun. ' + 'You will need to wrap any code with asynchronous side-effects in a run', !_emberMetalCore.default.testing);
31865    }
31866  }
31867
31868  /**
31869    Add a new named queue after the specified queue.
31870  
31871    The queue to add will only be added once.
31872  
31873    @method _addQueue
31874    @param {String} name the name of the queue to add.
31875    @param {String} after the name of the queue to add after.
31876    @private
31877  */
31878  run._addQueue = function (name, after) {
31879    if (run.queues.indexOf(name) === -1) {
31880      run.queues.splice(run.queues.indexOf(after) + 1, 0, name);
31881    }
31882  };
31883});
31884enifed('ember-metal/set_properties', ['exports', 'ember-metal/property_events', 'ember-metal/property_set'], function (exports, _emberMetalProperty_events, _emberMetalProperty_set) {
31885  'use strict';
31886
31887  exports.default = setProperties;
31888
31889  /**
31890    Set a list of properties on an object. These properties are set inside
31891    a single `beginPropertyChanges` and `endPropertyChanges` batch, so
31892    observers will be buffered.
31893  
31894    ```javascript
31895    var anObject = Ember.Object.create();
31896  
31897    anObject.setProperties({
31898      firstName: 'Stanley',
31899      lastName: 'Stuart',
31900      age: 21
31901    });
31902    ```
31903  
31904    @method setProperties
31905    @param obj
31906    @param {Object} properties
31907    @return properties
31908    @public
31909  */
31910
31911  function setProperties(obj, properties) {
31912    if (!properties || typeof properties !== 'object') {
31913      return properties;
31914    }
31915    _emberMetalProperty_events.changeProperties(function () {
31916      var props = Object.keys(properties);
31917      var propertyName;
31918
31919      for (var i = 0, l = props.length; i < l; i++) {
31920        propertyName = props[i];
31921
31922        _emberMetalProperty_set.set(obj, propertyName, properties[propertyName]);
31923      }
31924    });
31925    return properties;
31926  }
31927});
31928enifed('ember-metal/streams/dependency', ['exports', 'ember-metal/debug', 'ember-metal/assign', 'ember-metal/streams/utils'], function (exports, _emberMetalDebug, _emberMetalAssign, _emberMetalStreamsUtils) {
31929  'use strict';
31930
31931  /**
31932    @module ember-metal
31933  */
31934
31935  /**
31936    @private
31937    @class Dependency
31938    @namespace Ember.streams
31939    @constructor
31940  */
31941  function Dependency(depender, dependee) {
31942    _emberMetalDebug.assert('Dependency error: Depender must be a stream', _emberMetalStreamsUtils.isStream(depender));
31943
31944    this.next = null;
31945    this.prev = null;
31946    this.depender = depender;
31947    this.dependee = dependee;
31948    this.unsubscription = null;
31949  }
31950
31951  _emberMetalAssign.default(Dependency.prototype, {
31952    subscribe: function () {
31953      _emberMetalDebug.assert('Dependency error: Dependency tried to subscribe while already subscribed', !this.unsubscription);
31954
31955      this.unsubscription = _emberMetalStreamsUtils.subscribe(this.dependee, this.depender.notify, this.depender);
31956    },
31957
31958    unsubscribe: function () {
31959      if (this.unsubscription) {
31960        this.unsubscription();
31961        this.unsubscription = null;
31962      }
31963    },
31964
31965    replace: function (dependee) {
31966      if (this.dependee !== dependee) {
31967        this.dependee = dependee;
31968
31969        if (this.unsubscription) {
31970          this.unsubscribe();
31971          this.subscribe();
31972        }
31973        return true;
31974      }
31975      return false;
31976    },
31977
31978    getValue: function () {
31979      return _emberMetalStreamsUtils.read(this.dependee);
31980    },
31981
31982    setValue: function (value) {
31983      return _emberMetalStreamsUtils.setValue(this.dependee, value);
31984    }
31985
31986    // destroy() {
31987    //   var next = this.next;
31988    //   var prev = this.prev;
31989
31990    //   if (prev) {
31991    //     prev.next = next;
31992    //   } else {
31993    //     this.depender.dependencyHead = next;
31994    //   }
31995
31996    //   if (next) {
31997    //     next.prev = prev;
31998    //   } else {
31999    //     this.depender.dependencyTail = prev;
32000    //   }
32001
32002    //   this.unsubscribe();
32003    // }
32004  });
32005
32006  exports.default = Dependency;
32007});
32008enifed('ember-metal/streams/key-stream', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/observer', 'ember-metal/streams/stream', 'ember-metal/streams/utils'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalObserver, _emberMetalStreamsStream, _emberMetalStreamsUtils) {
32009  'use strict';
32010
32011  function labelFor(source, key) {
32012    return source.label ? source.label + '.' + key : key;
32013  }
32014
32015  exports.default = _emberMetalStreamsStream.default.extend({
32016    init: function (source, key) {
32017      _emberMetalDebug.assert('KeyStream error: source must be a stream', _emberMetalStreamsUtils.isStream(source)); // TODO: This isn't necessary.
32018      _emberMetalDebug.assert('KeyStream error: key must be a non-empty string', typeof key === 'string' && key.length > 0);
32019      _emberMetalDebug.assert('KeyStream error: key must not have a \'.\'', key.indexOf('.') === -1);
32020
32021      var label = labelFor(source, key);
32022
32023      this.path = label;
32024      this.observedObject = null;
32025      this.key = key;
32026      this.sourceDep = this.addMutableDependency(source);
32027      this.label = label;
32028    },
32029
32030    compute: function () {
32031      var object = this.sourceDep.getValue();
32032      var type = typeof object;
32033
32034      if (!object || type === 'boolean') {
32035        return;
32036      }
32037
32038      if (type === 'object') {
32039        return _emberMetalProperty_get.get(object, this.key);
32040      }
32041
32042      return object[this.key];
32043    },
32044
32045    setValue: function (value) {
32046      var object = this.sourceDep.getValue();
32047      if (object) {
32048        _emberMetalProperty_set.set(object, this.key, value);
32049      }
32050    },
32051
32052    setSource: function (source) {
32053      this.sourceDep.replace(source);
32054      this.notify();
32055    },
32056
32057    _super$revalidate: _emberMetalStreamsStream.default.prototype.revalidate,
32058
32059    revalidate: function (value) {
32060      this._super$revalidate(value);
32061
32062      var object = this.sourceDep.getValue();
32063      if (object !== this.observedObject) {
32064        this._clearObservedObject();
32065
32066        if (object && typeof object === 'object') {
32067          _emberMetalObserver.addObserver(object, this.key, this, this.notify);
32068          this.observedObject = object;
32069        }
32070      }
32071    },
32072
32073    _super$deactivate: _emberMetalStreamsStream.default.prototype.deactivate,
32074
32075    _clearObservedObject: function () {
32076      if (this.observedObject) {
32077        _emberMetalObserver.removeObserver(this.observedObject, this.key, this, this.notify);
32078        this.observedObject = null;
32079      }
32080    },
32081
32082    deactivate: function () {
32083      this._super$deactivate();
32084      this._clearObservedObject();
32085    }
32086  });
32087});
32088enifed('ember-metal/streams/proxy-stream', ['exports', 'ember-runtime/system/object', 'ember-metal/streams/stream'], function (exports, _emberRuntimeSystemObject, _emberMetalStreamsStream) {
32089  'use strict';
32090
32091  var ProxyStream = _emberMetalStreamsStream.default.extend({
32092    init: function (source, label) {
32093      this.label = label;
32094      this.sourceDep = this.addMutableDependency(source);
32095    },
32096
32097    compute: function () {
32098      return this.sourceDep.getValue();
32099    },
32100
32101    setValue: function (value) {
32102      this.sourceDep.setValue(value);
32103    },
32104
32105    setSource: function (source) {
32106      var didChange = this.sourceDep.replace(source);
32107      if (didChange || !(source instanceof _emberRuntimeSystemObject.default)) {
32108        // If the source changed, we must notify. If the source is not
32109        // an Ember.Object, we must also notify, because it could have
32110        // interior mutability that is otherwise not being observed.
32111        this.notify();
32112      }
32113    }
32114  });
32115
32116  ProxyStream.extend = _emberMetalStreamsStream.default.extend;
32117
32118  exports.default = ProxyStream;
32119});
32120enifed('ember-metal/streams/stream', ['exports', 'ember-metal/assign', 'ember-metal/debug', 'ember-metal/path_cache', 'ember-metal/observer', 'ember-metal/streams/utils', 'ember-metal/empty_object', 'ember-metal/streams/subscriber', 'ember-metal/streams/dependency', 'ember-metal/utils', 'require', 'ember-metal/symbol'], function (exports, _emberMetalAssign, _emberMetalDebug, _emberMetalPath_cache, _emberMetalObserver, _emberMetalStreamsUtils, _emberMetalEmpty_object, _emberMetalStreamsSubscriber, _emberMetalStreamsDependency, _emberMetalUtils, _require, _emberMetalSymbol) {
32121  'use strict';
32122
32123  exports.wrap = wrap;
32124  var IS_STREAM = _emberMetalSymbol.default('IS_STREAM');
32125
32126  exports.IS_STREAM = IS_STREAM;
32127  /**
32128    @module ember-metal
32129  */
32130
32131  /**
32132    @private
32133    @class Stream
32134    @namespace Ember.stream
32135    @constructor
32136  */
32137  function BasicStream(label) {
32138    this._init(label);
32139  }
32140
32141  var KeyStream;
32142  var ProxyMixin;
32143
32144  BasicStream.prototype = {
32145    _init: function (label) {
32146      this[IS_STREAM] = true;
32147      this.label = makeLabel(label);
32148      this.isActive = false;
32149      this.isDirty = true;
32150      this.isDestroyed = false;
32151      this.cache = undefined;
32152      this.children = undefined;
32153      this.subscriberHead = null;
32154      this.subscriberTail = null;
32155      this.dependencyHead = null;
32156      this.dependencyTail = null;
32157      this.observedProxy = null;
32158      this.__ember_meta__ = null;
32159      this[_emberMetalUtils.GUID_KEY] = null;
32160    },
32161
32162    _makeChildStream: function (key) {
32163      KeyStream = KeyStream || _require.default('ember-metal/streams/key-stream').default;
32164      return new KeyStream(this, key);
32165    },
32166
32167    removeChild: function (key) {
32168      delete this.children[key];
32169    },
32170
32171    getKey: function (key) {
32172      if (this.children === undefined) {
32173        this.children = new _emberMetalEmpty_object.default();
32174      }
32175
32176      var keyStream = this.children[key];
32177
32178      if (keyStream === undefined) {
32179        keyStream = this._makeChildStream(key);
32180        this.children[key] = keyStream;
32181      }
32182
32183      return keyStream;
32184    },
32185
32186    get: function (path) {
32187      var firstKey = _emberMetalPath_cache.getFirstKey(path);
32188      var tailPath = _emberMetalPath_cache.getTailPath(path);
32189
32190      if (this.children === undefined) {
32191        this.children = new _emberMetalEmpty_object.default();
32192      }
32193
32194      var keyStream = this.children[firstKey];
32195
32196      if (keyStream === undefined) {
32197        keyStream = this._makeChildStream(firstKey, path);
32198        this.children[firstKey] = keyStream;
32199      }
32200
32201      if (tailPath === undefined) {
32202        return keyStream;
32203      } else {
32204        return keyStream.get(tailPath);
32205      }
32206    },
32207
32208    value: function () {
32209      // TODO: Ensure value is never called on a destroyed stream
32210      // so that we can uncomment this assertion.
32211      //
32212      // assert("Stream error: value was called after the stream was destroyed", !this.isDestroyed);
32213
32214      // TODO: Remove this block. This will require ensuring we are
32215      // not treating streams as "volatile" anywhere.
32216      if (!this.isActive) {
32217        this.isDirty = true;
32218      }
32219
32220      var willRevalidate = false;
32221
32222      if (!this.isActive && this.subscriberHead) {
32223        this.activate();
32224        willRevalidate = true;
32225      }
32226
32227      if (this.isDirty) {
32228        if (this.isActive) {
32229          willRevalidate = true;
32230        }
32231
32232        this.cache = this.compute();
32233        this.isDirty = false;
32234      }
32235
32236      if (willRevalidate) {
32237        this.revalidate(this.cache);
32238      }
32239
32240      return this.cache;
32241    },
32242
32243    addMutableDependency: function (object) {
32244      var dependency = new _emberMetalStreamsDependency.default(this, object);
32245
32246      if (this.isActive) {
32247        dependency.subscribe();
32248      }
32249
32250      if (this.dependencyHead === null) {
32251        this.dependencyHead = this.dependencyTail = dependency;
32252      } else {
32253        var tail = this.dependencyTail;
32254        tail.next = dependency;
32255        dependency.prev = tail;
32256        this.dependencyTail = dependency;
32257      }
32258
32259      return dependency;
32260    },
32261
32262    addDependency: function (object) {
32263      if (_emberMetalStreamsUtils.isStream(object)) {
32264        this.addMutableDependency(object);
32265      }
32266    },
32267
32268    subscribeDependencies: function () {
32269      var dependency = this.dependencyHead;
32270      while (dependency) {
32271        var next = dependency.next;
32272        dependency.subscribe();
32273        dependency = next;
32274      }
32275    },
32276
32277    unsubscribeDependencies: function () {
32278      var dependency = this.dependencyHead;
32279      while (dependency) {
32280        var next = dependency.next;
32281        dependency.unsubscribe();
32282        dependency = next;
32283      }
32284    },
32285
32286    maybeDeactivate: function () {
32287      if (!this.subscriberHead && this.isActive) {
32288        this.isActive = false;
32289        this.unsubscribeDependencies();
32290        this.deactivate();
32291      }
32292    },
32293
32294    activate: function () {
32295      this.isActive = true;
32296      this.subscribeDependencies();
32297    },
32298
32299    revalidate: function (value) {
32300      if (value !== this.observedProxy) {
32301        this._clearObservedProxy();
32302
32303        ProxyMixin = ProxyMixin || _require.default('ember-runtime/mixins/-proxy').default;
32304
32305        if (ProxyMixin.detect(value)) {
32306          _emberMetalObserver.addObserver(value, 'content', this, this.notify);
32307          this.observedProxy = value;
32308        }
32309      }
32310    },
32311
32312    _clearObservedProxy: function () {
32313      if (this.observedProxy) {
32314        _emberMetalObserver.removeObserver(this.observedProxy, 'content', this, this.notify);
32315        this.observedProxy = null;
32316      }
32317    },
32318
32319    deactivate: function () {
32320      this._clearObservedProxy();
32321    },
32322
32323    compute: function () {
32324      throw new Error('Stream error: compute not implemented');
32325    },
32326
32327    setValue: function () {
32328      throw new Error('Stream error: setValue not implemented');
32329    },
32330
32331    notify: function () {
32332      this.notifyExcept();
32333    },
32334
32335    notifyExcept: function (callbackToSkip, contextToSkip) {
32336      if (!this.isDirty) {
32337        this.isDirty = true;
32338        this.notifySubscribers(callbackToSkip, contextToSkip);
32339      }
32340    },
32341
32342    subscribe: function (callback, context) {
32343      _emberMetalDebug.assert('You tried to subscribe to a stream but the callback provided was not a function.', typeof callback === 'function');
32344
32345      var subscriber = new _emberMetalStreamsSubscriber.default(callback, context, this);
32346      if (this.subscriberHead === null) {
32347        this.subscriberHead = this.subscriberTail = subscriber;
32348      } else {
32349        var tail = this.subscriberTail;
32350        tail.next = subscriber;
32351        subscriber.prev = tail;
32352        this.subscriberTail = subscriber;
32353      }
32354
32355      var stream = this;
32356      return function (prune) {
32357        subscriber.removeFrom(stream);
32358        if (prune) {
32359          stream.prune();
32360        }
32361      };
32362    },
32363
32364    prune: function () {
32365      if (this.subscriberHead === null) {
32366        this.destroy(true);
32367      }
32368    },
32369
32370    unsubscribe: function (callback, context) {
32371      var subscriber = this.subscriberHead;
32372
32373      while (subscriber) {
32374        var next = subscriber.next;
32375        if (subscriber.callback === callback && subscriber.context === context) {
32376          subscriber.removeFrom(this);
32377        }
32378        subscriber = next;
32379      }
32380    },
32381
32382    notifySubscribers: function (callbackToSkip, contextToSkip) {
32383      var subscriber = this.subscriberHead;
32384
32385      while (subscriber) {
32386        var next = subscriber.next;
32387
32388        var callback = subscriber.callback;
32389        var context = subscriber.context;
32390
32391        subscriber = next;
32392
32393        if (callback === callbackToSkip && context === contextToSkip) {
32394          continue;
32395        }
32396
32397        if (context === undefined) {
32398          callback(this);
32399        } else {
32400          callback.call(context, this);
32401        }
32402      }
32403    },
32404
32405    destroy: function (prune) {
32406      if (!this.isDestroyed) {
32407        this.isDestroyed = true;
32408
32409        this.subscriberHead = this.subscriberTail = null;
32410        this.maybeDeactivate();
32411
32412        var dependencies = this.dependencies;
32413
32414        if (dependencies) {
32415          for (var i = 0, l = dependencies.length; i < l; i++) {
32416            dependencies[i](prune);
32417          }
32418        }
32419
32420        return true;
32421      }
32422    }
32423  };
32424
32425  BasicStream.extend = function (object) {
32426    var Child = function () {
32427      this._init();
32428      this.init.apply(this, arguments);
32429
32430      _emberMetalDebug.debugSeal(this);
32431    };
32432
32433    Child.prototype = Object.create(this.prototype);
32434
32435    _emberMetalAssign.default(Child.prototype, object);
32436    Child.extend = BasicStream.extend;
32437    return Child;
32438  };
32439
32440  var Stream = BasicStream.extend({
32441    init: function (fn, label) {
32442      this._compute = fn;
32443      this.label = label;
32444    },
32445
32446    compute: function () {
32447      return this._compute();
32448    }
32449  });
32450
32451  function wrap(value, Kind, param) {
32452    if (_emberMetalStreamsUtils.isStream(value)) {
32453      return value;
32454    } else {
32455      return new Kind(value, param);
32456    }
32457  }
32458
32459  function makeLabel(label) {
32460    if (label === undefined) {
32461      return '(no label)';
32462    } else {
32463      return label;
32464    }
32465  }
32466
32467  exports.default = BasicStream;
32468  exports.Stream = Stream;
32469});
32470enifed('ember-metal/streams/subscriber', ['exports', 'ember-metal/assign'], function (exports, _emberMetalAssign) {
32471  'use strict';
32472
32473  /**
32474    @module ember-metal
32475  */
32476
32477  /**
32478    @private
32479    @class Subscriber
32480    @namespace Ember.streams
32481    @constructor
32482  */
32483  function Subscriber(callback, context) {
32484    this.next = null;
32485    this.prev = null;
32486    this.callback = callback;
32487    this.context = context;
32488  }
32489
32490  _emberMetalAssign.default(Subscriber.prototype, {
32491    removeFrom: function (stream) {
32492      var next = this.next;
32493      var prev = this.prev;
32494
32495      if (prev) {
32496        prev.next = next;
32497      } else {
32498        stream.subscriberHead = next;
32499      }
32500
32501      if (next) {
32502        next.prev = prev;
32503      } else {
32504        stream.subscriberTail = prev;
32505      }
32506
32507      stream.maybeDeactivate();
32508    }
32509  });
32510
32511  exports.default = Subscriber;
32512});
32513enifed('ember-metal/streams/utils', ['exports', 'ember-metal/debug', 'ember-metal/streams/stream'], function (exports, _emberMetalDebug, _emberMetalStreamsStream) {
32514  'use strict';
32515
32516  exports.isStream = isStream;
32517  exports.subscribe = subscribe;
32518  exports.unsubscribe = unsubscribe;
32519  exports.read = read;
32520  exports.readArray = readArray;
32521  exports.readHash = readHash;
32522  exports.scanArray = scanArray;
32523  exports.scanHash = scanHash;
32524  exports.concat = concat;
32525  exports.labelsFor = labelsFor;
32526  exports.labelsForObject = labelsForObject;
32527  exports.labelFor = labelFor;
32528  exports.or = or;
32529  exports.addDependency = addDependency;
32530  exports.zip = zip;
32531  exports.zipHash = zipHash;
32532  exports.chain = chain;
32533  exports.setValue = setValue;
32534
32535  /*
32536   Check whether an object is a stream or not.
32537  
32538   @private
32539   @for Ember.stream
32540   @function isStream
32541   @param {Object|Stream} object Object to check whether it is a stream.
32542   @return {Boolean} `true` if the object is a stream, `false` otherwise.
32543  */
32544
32545  function isStream(object) {
32546    return object && object[_emberMetalStreamsStream.IS_STREAM];
32547  }
32548
32549  /*
32550   A method of subscribing to a stream which is safe for use with a non-stream
32551   object. If a non-stream object is passed, the function does nothing.
32552  
32553   @public
32554   @for Ember.stream
32555   @function subscribe
32556   @param {Object|Stream} object Object or stream to potentially subscribe to.
32557   @param {Function} callback Function to run when stream value changes.
32558   @param {Object} [context] the callback will be executed with this context if it
32559                             is provided.
32560   */
32561
32562  function subscribe(object, callback, context) {
32563    if (object && object[_emberMetalStreamsStream.IS_STREAM]) {
32564      return object.subscribe(callback, context);
32565    }
32566  }
32567
32568  /*
32569   A method of unsubscribing from a stream which is safe for use with a non-stream
32570   object. If a non-stream object is passed, the function does nothing.
32571  
32572   @private
32573   @for Ember.stream
32574   @function unsubscribe
32575   @param {Object|Stream} object Object or stream to potentially unsubscribe from.
32576   @param {Function} callback Function originally passed to `subscribe()`.
32577   @param {Object} [context] Object originally passed to `subscribe()`.
32578   */
32579
32580  function unsubscribe(object, callback, context) {
32581    if (object && object[_emberMetalStreamsStream.IS_STREAM]) {
32582      object.unsubscribe(callback, context);
32583    }
32584  }
32585
32586  /*
32587   Retrieve the value of a stream, or in the case where a non-stream object is passed,
32588   return the object itself.
32589  
32590   @private
32591   @for Ember.stream
32592   @function read
32593   @param {Object|Stream} object Object to return the value of.
32594   @return The stream's current value, or the non-stream object itself.
32595   */
32596
32597  function read(object) {
32598    if (object && object[_emberMetalStreamsStream.IS_STREAM]) {
32599      return object.value();
32600    } else {
32601      return object;
32602    }
32603  }
32604
32605  /*
32606   Map an array, replacing any streams with their values.
32607  
32608   @private
32609   @for Ember.stream
32610   @function readArray
32611   @param {Array} array The array to read values from
32612   @return {Array} A new array of the same length with the values of non-stream
32613                   objects mapped from their original positions untouched, and
32614                   the values of stream objects retaining their original position
32615                   and replaced with the stream's current value.
32616   */
32617
32618  function readArray(array) {
32619    var length = array.length;
32620    var ret = new Array(length);
32621    for (var i = 0; i < length; i++) {
32622      ret[i] = read(array[i]);
32623    }
32624    return ret;
32625  }
32626
32627  /*
32628   Map a hash, replacing any stream property values with the current value of that
32629   stream.
32630  
32631   @private
32632   @for Ember.stream
32633   @function readHash
32634   @param {Object} object The hash to read keys and values from.
32635   @return {Object} A new object with the same keys as the passed object. The
32636                    property values in the new object are the original values in
32637                    the case of non-stream objects, and the streams' current
32638                    values in the case of stream objects.
32639   */
32640
32641  function readHash(object) {
32642    var ret = {};
32643    for (var key in object) {
32644      ret[key] = read(object[key]);
32645    }
32646    return ret;
32647  }
32648
32649  /*
32650   Check whether an array contains any stream values.
32651  
32652   @private
32653   @for Ember.stream
32654   @function scanArray
32655   @param {Array} array Array given to a handlebars helper.
32656   @return {Boolean} `true` if the array contains a stream/bound value, `false`
32657                     otherwise.
32658  */
32659
32660  function scanArray(array) {
32661    var length = array.length;
32662    var containsStream = false;
32663
32664    for (var i = 0; i < length; i++) {
32665      if (isStream(array[i])) {
32666        containsStream = true;
32667        break;
32668      }
32669    }
32670
32671    return containsStream;
32672  }
32673
32674  /*
32675   Check whether a hash has any stream property values.
32676  
32677   @private
32678   @for Ember.stream
32679   @function scanHash
32680   @param {Object} hash "hash" argument given to a handlebars helper.
32681   @return {Boolean} `true` if the object contains a stream/bound value, `false`
32682                     otherwise.
32683   */
32684
32685  function scanHash(hash) {
32686    var containsStream = false;
32687
32688    for (var prop in hash) {
32689      if (isStream(hash[prop])) {
32690        containsStream = true;
32691        break;
32692      }
32693    }
32694
32695    return containsStream;
32696  }
32697
32698  var ConcatStream = _emberMetalStreamsStream.default.extend({
32699    init: function (array, separator) {
32700      this.array = array;
32701      this.separator = separator;
32702
32703      // Used by angle bracket components to detect an attribute was provided
32704      // as a string literal.
32705      this.isConcat = true;
32706    },
32707
32708    label: function () {
32709      var labels = labelsFor(this.array);
32710      return 'concat([' + labels.join(', ') + ']; separator=' + inspect(this.separator) + ')';
32711    },
32712
32713    compute: function () {
32714      return concat(readArray(this.array), this.separator);
32715    }
32716  });
32717
32718  /*
32719   Join an array, with any streams replaced by their current values.
32720  
32721   @private
32722   @for Ember.stream
32723   @function concat
32724   @param {Array} array An array containing zero or more stream objects and
32725                        zero or more non-stream objects.
32726   @param {String} separator String to be used to join array elements.
32727   @return {String} String with array elements concatenated and joined by the
32728                    provided separator, and any stream array members having been
32729                    replaced by the current value of the stream.
32730   */
32731
32732  function concat(array, separator) {
32733    // TODO: Create subclass ConcatStream < Stream. Defer
32734    // subscribing to streams until the value() is called.
32735    var hasStream = scanArray(array);
32736    if (hasStream) {
32737      var stream = new ConcatStream(array, separator);
32738
32739      for (var i = 0, l = array.length; i < l; i++) {
32740        addDependency(stream, array[i]);
32741      }
32742
32743      return stream;
32744    } else {
32745      return array.join(separator);
32746    }
32747  }
32748
32749  function labelsFor(streams) {
32750    var labels = [];
32751
32752    for (var i = 0, l = streams.length; i < l; i++) {
32753      var stream = streams[i];
32754      labels.push(labelFor(stream));
32755    }
32756
32757    return labels;
32758  }
32759
32760  function labelsForObject(streams) {
32761    var labels = [];
32762
32763    for (var prop in streams) {
32764      labels.push(prop + ': ' + inspect(streams[prop]));
32765    }
32766
32767    return labels.length ? '{ ' + labels.join(', ') + ' }' : '{}';
32768  }
32769
32770  function labelFor(maybeStream) {
32771    if (isStream(maybeStream)) {
32772      var stream = maybeStream;
32773      return typeof stream.label === 'function' ? stream.label() : stream.label;
32774    } else {
32775      return inspect(maybeStream);
32776    }
32777  }
32778
32779  function inspect(value) {
32780    switch (typeof value) {
32781      case 'string':
32782        return '"' + value + '"';
32783      case 'object':
32784        return '{ ... }';
32785      case 'function':
32786        return 'function() { ... }';
32787      default:
32788        return String(value);
32789    }
32790  }
32791
32792  function or(first, second) {
32793    var stream = new _emberMetalStreamsStream.Stream(function () {
32794      return first.value() || second.value();
32795    }, function () {
32796      return labelFor(first) + ' || ' + labelFor(second);
32797    });
32798
32799    stream.addDependency(first);
32800    stream.addDependency(second);
32801
32802    return stream;
32803  }
32804
32805  function addDependency(stream, dependency) {
32806    _emberMetalDebug.assert('Cannot add a stream as a dependency to a non-stream', isStream(stream) || !isStream(dependency));
32807    if (isStream(stream)) {
32808      stream.addDependency(dependency);
32809    }
32810  }
32811
32812  function zip(streams, callback, label) {
32813    _emberMetalDebug.assert('Must call zip with a label', !!label);
32814
32815    var stream = new _emberMetalStreamsStream.Stream(function () {
32816      var array = readArray(streams);
32817      return callback ? callback(array) : array;
32818    }, function () {
32819      return label + '(' + labelsFor(streams) + ')';
32820    });
32821
32822    for (var i = 0, l = streams.length; i < l; i++) {
32823      stream.addDependency(streams[i]);
32824    }
32825
32826    return stream;
32827  }
32828
32829  function zipHash(object, callback, label) {
32830    _emberMetalDebug.assert('Must call zipHash with a label', !!label);
32831
32832    var stream = new _emberMetalStreamsStream.Stream(function () {
32833      var hash = readHash(object);
32834      return callback ? callback(hash) : hash;
32835    }, function () {
32836      return label + '(' + labelsForObject(object) + ')';
32837    });
32838
32839    for (var prop in object) {
32840      stream.addDependency(object[prop]);
32841    }
32842
32843    return stream;
32844  }
32845
32846  /**
32847   Generate a new stream by providing a source stream and a function that can
32848   be used to transform the stream's value. In the case of a non-stream object,
32849   returns the result of the function.
32850  
32851   The value to transform would typically be available to the function you pass
32852   to `chain()` via scope. For example:
32853  
32854   ```javascript
32855       var source = ...;  // stream returning a number
32856                              // or a numeric (non-stream) object
32857       var result = chain(source, function() {
32858         var currentValue = read(source);
32859         return currentValue + 1;
32860       });
32861   ```
32862  
32863   In the example, result is a stream if source is a stream, or a number of
32864   source was numeric.
32865  
32866   @private
32867   @for Ember.stream
32868   @function chain
32869   @param {Object|Stream} value A stream or non-stream object.
32870   @param {Function} fn Function to be run when the stream value changes, or to
32871                        be run once in the case of a non-stream object.
32872   @return {Object|Stream} In the case of a stream `value` parameter, a new
32873                           stream that will be updated with the return value of
32874                           the provided function `fn`. In the case of a
32875                           non-stream object, the return value of the provided
32876                           function `fn`.
32877   */
32878
32879  function chain(value, fn, label) {
32880    _emberMetalDebug.assert('Must call chain with a label', !!label);
32881    if (isStream(value)) {
32882      var stream = new _emberMetalStreamsStream.Stream(fn, function () {
32883        return label + '(' + labelFor(value) + ')';
32884      });
32885      stream.addDependency(value);
32886      return stream;
32887    } else {
32888      return fn();
32889    }
32890  }
32891
32892  function setValue(object, value) {
32893    if (object && object[_emberMetalStreamsStream.IS_STREAM]) {
32894      object.setValue(value);
32895    }
32896  }
32897});
32898enifed('ember-metal/symbol', ['exports', 'ember-metal/utils'], function (exports, _emberMetalUtils) {
32899  'use strict';
32900
32901  exports.default = symbol;
32902
32903  function symbol(debugName) {
32904    // TODO: Investigate using platform symbols, but we do not
32905    // want to require non-enumerability for this API, which
32906    // would introduce a large cost.
32907
32908    return _emberMetalUtils.intern(debugName + ' [id=' + _emberMetalUtils.GUID_KEY + Math.floor(Math.random() * new Date()) + ']');
32909  }
32910});
32911enifed('ember-metal/utils', ['exports'], function (exports) {
32912  'no use strict';
32913  // Remove "use strict"; from transpiled module until
32914  // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
32915
32916  /**
32917  @module ember-metal
32918  */
32919
32920  /**
32921    Previously we used `Ember.$.uuid`, however `$.uuid` has been removed from
32922    jQuery master. We'll just bootstrap our own uuid now.
32923  
32924    @private
32925    @return {Number} the uuid
32926  */
32927  exports.uuid = uuid;
32928  exports.intern = intern;
32929  exports.generateGuid = generateGuid;
32930  exports.guidFor = guidFor;
32931  exports.wrap = wrap;
32932  exports.tryInvoke = tryInvoke;
32933  exports.makeArray = makeArray;
32934  exports.inspect = inspect;
32935  exports.apply = apply;
32936  exports.applyStr = applyStr;
32937  exports.lookupDescriptor = lookupDescriptor;
32938  exports.toString = toString;
32939  var _uuid = 0;
32940
32941  /**
32942    Generates a universally unique identifier. This method
32943    is used internally by Ember for assisting with
32944    the generation of GUID's and other unique identifiers.
32945  
32946    @public
32947    @return {Number} [description]
32948   */
32949
32950  function uuid() {
32951    return ++_uuid;
32952  }
32953
32954  /**
32955    Prefix used for guids through out Ember.
32956    @private
32957    @property GUID_PREFIX
32958    @for Ember
32959    @type String
32960    @final
32961  */
32962  var GUID_PREFIX = 'ember';
32963
32964  // Used for guid generation...
32965  var numberCache = [];
32966  var stringCache = {};
32967
32968  /**
32969    Strongly hint runtimes to intern the provided string.
32970  
32971    When do I need to use this function?
32972  
32973    For the most part, never. Pre-mature optimization is bad, and often the
32974    runtime does exactly what you need it to, and more often the trade-off isn't
32975    worth it.
32976  
32977    Why?
32978  
32979    Runtimes store strings in at least 2 different representations:
32980    Ropes and Symbols (interned strings). The Rope provides a memory efficient
32981    data-structure for strings created from concatenation or some other string
32982    manipulation like splitting.
32983  
32984    Unfortunately checking equality of different ropes can be quite costly as
32985    runtimes must resort to clever string comparison algorithms. These
32986    algorithms typically cost in proportion to the length of the string.
32987    Luckily, this is where the Symbols (interned strings) shine. As Symbols are
32988    unique by their string content, equality checks can be done by pointer
32989    comparison.
32990  
32991    How do I know if my string is a rope or symbol?
32992  
32993    Typically (warning general sweeping statement, but truthy in runtimes at
32994    present) static strings created as part of the JS source are interned.
32995    Strings often used for comparisons can be interned at runtime if some
32996    criteria are met.  One of these criteria can be the size of the entire rope.
32997    For example, in chrome 38 a rope longer then 12 characters will not
32998    intern, nor will segments of that rope.
32999  
33000    Some numbers: http://jsperf.com/eval-vs-keys/8
33001  
33002    Known Trick™
33003  
33004    @private
33005    @return {String} interned version of the provided string
33006  */
33007
33008  function intern(str) {
33009    var obj = {};
33010    obj[str] = 1;
33011    for (var key in obj) {
33012      if (key === str) {
33013        return key;
33014      }
33015    }
33016    return str;
33017  }
33018
33019  /**
33020    A unique key used to assign guids and other private metadata to objects.
33021    If you inspect an object in your browser debugger you will often see these.
33022    They can be safely ignored.
33023  
33024    On browsers that support it, these properties are added with enumeration
33025    disabled so they won't show up when you iterate over your properties.
33026  
33027    @private
33028    @property GUID_KEY
33029    @for Ember
33030    @type String
33031    @final
33032  */
33033  var GUID_KEY = intern('__ember' + +new Date());
33034
33035  var GUID_DESC = {
33036    writable: true,
33037    configurable: true,
33038    enumerable: false,
33039    value: null
33040  };
33041
33042  exports.GUID_DESC = GUID_DESC;
33043  var nullDescriptor = {
33044    configurable: true,
33045    writable: true,
33046    enumerable: false,
33047    value: null
33048  };
33049
33050  var GUID_KEY_PROPERTY = {
33051    name: GUID_KEY,
33052    descriptor: nullDescriptor
33053  };
33054
33055  exports.GUID_KEY_PROPERTY = GUID_KEY_PROPERTY;
33056  /**
33057    Generates a new guid, optionally saving the guid to the object that you
33058    pass in. You will rarely need to use this method. Instead you should
33059    call `Ember.guidFor(obj)`, which return an existing guid if available.
33060  
33061    @private
33062    @method generateGuid
33063    @for Ember
33064    @param {Object} [obj] Object the guid will be used for. If passed in, the guid will
33065      be saved on the object and reused whenever you pass the same object
33066      again.
33067  
33068      If no object is passed, just generate a new guid.
33069    @param {String} [prefix] Prefix to place in front of the guid. Useful when you want to
33070      separate the guid into separate namespaces.
33071    @return {String} the guid
33072  */
33073
33074  function generateGuid(obj, prefix) {
33075    if (!prefix) {
33076      prefix = GUID_PREFIX;
33077    }
33078
33079    var ret = prefix + uuid();
33080    if (obj) {
33081      if (obj[GUID_KEY] === null) {
33082        obj[GUID_KEY] = ret;
33083      } else {
33084        GUID_DESC.value = ret;
33085        if (obj.__defineNonEnumerable) {
33086          obj.__defineNonEnumerable(GUID_KEY_PROPERTY);
33087        } else {
33088          Object.defineProperty(obj, GUID_KEY, GUID_DESC);
33089        }
33090      }
33091    }
33092    return ret;
33093  }
33094
33095  /**
33096    Returns a unique id for the object. If the object does not yet have a guid,
33097    one will be assigned to it. You can call this on any object,
33098    `Ember.Object`-based or not, but be aware that it will add a `_guid`
33099    property.
33100  
33101    You can also use this method on DOM Element objects.
33102  
33103    @public
33104    @method guidFor
33105    @for Ember
33106    @param {Object} obj any object, string, number, Element, or primitive
33107    @return {String} the unique guid for this instance.
33108  */
33109
33110  function guidFor(obj) {
33111    if (obj && obj[GUID_KEY]) {
33112      return obj[GUID_KEY];
33113    }
33114
33115    // special cases where we don't want to add a key to object
33116    if (obj === undefined) {
33117      return '(undefined)';
33118    }
33119
33120    if (obj === null) {
33121      return '(null)';
33122    }
33123
33124    var ret;
33125    var type = typeof obj;
33126
33127    // Don't allow prototype changes to String etc. to change the guidFor
33128    switch (type) {
33129      case 'number':
33130        ret = numberCache[obj];
33131
33132        if (!ret) {
33133          ret = numberCache[obj] = 'nu' + obj;
33134        }
33135
33136        return ret;
33137
33138      case 'string':
33139        ret = stringCache[obj];
33140
33141        if (!ret) {
33142          ret = stringCache[obj] = 'st' + uuid();
33143        }
33144
33145        return ret;
33146
33147      case 'boolean':
33148        return obj ? '(true)' : '(false)';
33149
33150      default:
33151        if (obj === Object) {
33152          return '(Object)';
33153        }
33154
33155        if (obj === Array) {
33156          return '(Array)';
33157        }
33158
33159        ret = GUID_PREFIX + uuid();
33160
33161        if (obj[GUID_KEY] === null) {
33162          obj[GUID_KEY] = ret;
33163        } else {
33164          GUID_DESC.value = ret;
33165
33166          if (obj.__defineNonEnumerable) {
33167            obj.__defineNonEnumerable(GUID_KEY_PROPERTY);
33168          } else {
33169            Object.defineProperty(obj, GUID_KEY, GUID_DESC);
33170          }
33171        }
33172        return ret;
33173    }
33174  }
33175
33176  var HAS_SUPER_PATTERN = /\.(_super|call\(this|apply\(this)/;
33177
33178  var checkHasSuper = (function () {
33179    var sourceAvailable = (function () {
33180      return this;
33181    }).toString().indexOf('return this') > -1;
33182
33183    if (sourceAvailable) {
33184      return function checkHasSuper(func) {
33185        return HAS_SUPER_PATTERN.test(func.toString());
33186      };
33187    }
33188
33189    return function checkHasSuper() {
33190      return true;
33191    };
33192  })();
33193
33194  exports.checkHasSuper = checkHasSuper;
33195  function ROOT() {}
33196  ROOT.__hasSuper = false;
33197
33198  function hasSuper(func) {
33199    if (func.__hasSuper === undefined) {
33200      func.__hasSuper = checkHasSuper(func);
33201    }
33202    return func.__hasSuper;
33203  }
33204
33205  /**
33206    Wraps the passed function so that `this._super` will point to the superFunc
33207    when the function is invoked. This is the primitive we use to implement
33208    calls to super.
33209  
33210    @private
33211    @method wrap
33212    @for Ember
33213    @param {Function} func The function to call
33214    @param {Function} superFunc The super function.
33215    @return {Function} wrapped function.
33216  */
33217
33218  function wrap(func, superFunc) {
33219    if (!hasSuper(func)) {
33220      return func;
33221    }
33222    // ensure an unwrapped super that calls _super is wrapped with a terminal _super
33223    if (!superFunc.wrappedFunction && hasSuper(superFunc)) {
33224      return _wrap(func, _wrap(superFunc, ROOT));
33225    }
33226    return _wrap(func, superFunc);
33227  }
33228
33229  function _wrap(func, superFunc) {
33230    function superWrapper() {
33231      var orig = this._super;
33232      var length = arguments.length;
33233      var ret = undefined;
33234      this._super = superFunc;
33235      switch (length) {
33236        case 0:
33237          ret = func.call(this);break;
33238        case 1:
33239          ret = func.call(this, arguments[0]);break;
33240        case 2:
33241          ret = func.call(this, arguments[0], arguments[1]);break;
33242        case 3:
33243          ret = func.call(this, arguments[0], arguments[1], arguments[2]);break;
33244        case 4:
33245          ret = func.call(this, arguments[0], arguments[1], arguments[2], arguments[3]);break;
33246        case 5:
33247          ret = func.call(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);break;
33248        default:
33249          // v8 bug potentially incorrectly deopts this function: https://code.google.com/p/v8/issues/detail?id=3709
33250          // we may want to keep this around till this ages out on mobile
33251          var args = new Array(length);
33252          for (var x = 0; x < length; x++) {
33253            args[x] = arguments[x];
33254          }
33255          ret = func.apply(this, args);
33256          break;
33257      }
33258      this._super = orig;
33259      return ret;
33260    }
33261
33262    superWrapper.wrappedFunction = func;
33263    superWrapper.__ember_observes__ = func.__ember_observes__;
33264    superWrapper.__ember_observesBefore__ = func.__ember_observesBefore__;
33265    superWrapper.__ember_listens__ = func.__ember_listens__;
33266
33267    return superWrapper;
33268  }
33269
33270  /**
33271    Checks to see if the `methodName` exists on the `obj`.
33272  
33273    ```javascript
33274    var foo = { bar: function() { return 'bar'; }, baz: null };
33275  
33276    Ember.canInvoke(foo, 'bar'); // true
33277    Ember.canInvoke(foo, 'baz'); // false
33278    Ember.canInvoke(foo, 'bat'); // false
33279    ```
33280  
33281    @method canInvoke
33282    @for Ember
33283    @param {Object} obj The object to check for the method
33284    @param {String} methodName The method name to check for
33285    @return {Boolean}
33286    @private
33287  */
33288  function canInvoke(obj, methodName) {
33289    return !!(obj && typeof obj[methodName] === 'function');
33290  }
33291
33292  /**
33293    Checks to see if the `methodName` exists on the `obj`,
33294    and if it does, invokes it with the arguments passed.
33295  
33296    ```javascript
33297    var d = new Date('03/15/2013');
33298  
33299    Ember.tryInvoke(d, 'getTime');              // 1363320000000
33300    Ember.tryInvoke(d, 'setFullYear', [2014]);  // 1394856000000
33301    Ember.tryInvoke(d, 'noSuchMethod', [2014]); // undefined
33302    ```
33303  
33304    @method tryInvoke
33305    @for Ember
33306    @param {Object} obj The object to check for the method
33307    @param {String} methodName The method name to check for
33308    @param {Array} [args] The arguments to pass to the method
33309    @return {*} the return value of the invoked method or undefined if it cannot be invoked
33310    @public
33311  */
33312
33313  function tryInvoke(obj, methodName, args) {
33314    if (canInvoke(obj, methodName)) {
33315      return args ? applyStr(obj, methodName, args) : applyStr(obj, methodName);
33316    }
33317  }
33318
33319  // ........................................
33320  // TYPING & ARRAY MESSAGING
33321  //
33322
33323  var objectToString = Object.prototype.toString;
33324
33325  /**
33326    Forces the passed object to be part of an array. If the object is already
33327    an array, it will return the object. Otherwise, it will add the object to
33328    an array. If obj is `null` or `undefined`, it will return an empty array.
33329  
33330    ```javascript
33331    Ember.makeArray();            // []
33332    Ember.makeArray(null);        // []
33333    Ember.makeArray(undefined);   // []
33334    Ember.makeArray('lindsay');   // ['lindsay']
33335    Ember.makeArray([1, 2, 42]);  // [1, 2, 42]
33336  
33337    var controller = Ember.ArrayProxy.create({ content: [] });
33338  
33339    Ember.makeArray(controller) === controller;  // true
33340    ```
33341  
33342    @method makeArray
33343    @for Ember
33344    @param {Object} obj the object
33345    @return {Array}
33346    @private
33347  */
33348
33349  function makeArray(obj) {
33350    if (obj === null || obj === undefined) {
33351      return [];
33352    }
33353    return Array.isArray(obj) ? obj : [obj];
33354  }
33355
33356  /**
33357    Convenience method to inspect an object. This method will attempt to
33358    convert the object into a useful string description.
33359  
33360    It is a pretty simple implementation. If you want something more robust,
33361    use something like JSDump: https://github.com/NV/jsDump
33362  
33363    @method inspect
33364    @for Ember
33365    @param {Object} obj The object you want to inspect.
33366    @return {String} A description of the object
33367    @since 1.4.0
33368    @private
33369  */
33370
33371  function inspect(obj) {
33372    if (obj === null) {
33373      return 'null';
33374    }
33375    if (obj === undefined) {
33376      return 'undefined';
33377    }
33378    if (Array.isArray(obj)) {
33379      return '[' + obj + ']';
33380    }
33381    // for non objects
33382    var type = typeof obj;
33383    if (type !== 'object' && type !== 'symbol') {
33384      return '' + obj;
33385    }
33386    // overridden toString
33387    if (typeof obj.toString === 'function' && obj.toString !== objectToString) {
33388      return obj.toString();
33389    }
33390
33391    // Object.prototype.toString === {}.toString
33392    var v;
33393    var ret = [];
33394    for (var key in obj) {
33395      if (obj.hasOwnProperty(key)) {
33396        v = obj[key];
33397        if (v === 'toString') {
33398          continue;
33399        } // ignore useless items
33400        if (typeof v === 'function') {
33401          v = 'function() { ... }';
33402        }
33403
33404        if (v && typeof v.toString !== 'function') {
33405          ret.push(key + ': ' + objectToString.call(v));
33406        } else {
33407          ret.push(key + ': ' + v);
33408        }
33409      }
33410    }
33411    return '{' + ret.join(', ') + '}';
33412  }
33413
33414  // The following functions are intentionally minified to keep the functions
33415  // below Chrome's function body size inlining limit of 600 chars.
33416  /**
33417    @param {Object} t target
33418    @param {Function} m method
33419    @param {Array} a args
33420    @private
33421  */
33422
33423  function apply(t, m, a) {
33424    var l = a && a.length;
33425    if (!a || !l) {
33426      return m.call(t);
33427    }
33428    switch (l) {
33429      case 1:
33430        return m.call(t, a[0]);
33431      case 2:
33432        return m.call(t, a[0], a[1]);
33433      case 3:
33434        return m.call(t, a[0], a[1], a[2]);
33435      case 4:
33436        return m.call(t, a[0], a[1], a[2], a[3]);
33437      case 5:
33438        return m.call(t, a[0], a[1], a[2], a[3], a[4]);
33439      default:
33440        return m.apply(t, a);
33441    }
33442  }
33443
33444  /**
33445    @param {Object} t target
33446    @param {String} m method
33447    @param {Array} a args
33448    @private
33449  */
33450
33451  function applyStr(t, m, a) {
33452    var l = a && a.length;
33453    if (!a || !l) {
33454      return t[m]();
33455    }
33456    switch (l) {
33457      case 1:
33458        return t[m](a[0]);
33459      case 2:
33460        return t[m](a[0], a[1]);
33461      case 3:
33462        return t[m](a[0], a[1], a[2]);
33463      case 4:
33464        return t[m](a[0], a[1], a[2], a[3]);
33465      case 5:
33466        return t[m](a[0], a[1], a[2], a[3], a[4]);
33467      default:
33468        return t[m].apply(t, a);
33469    }
33470  }
33471
33472  function lookupDescriptor(obj, keyName) {
33473    var current = obj;
33474    while (current) {
33475      var descriptor = Object.getOwnPropertyDescriptor(current, keyName);
33476
33477      if (descriptor) {
33478        return descriptor;
33479      }
33480
33481      current = Object.getPrototypeOf(current);
33482    }
33483
33484    return null;
33485  }
33486
33487  // A `toString` util function that supports objects without a `toString`
33488  // method, e.g. an object created with `Object.create(null)`.
33489
33490  function toString(obj) {
33491    if (obj && obj.toString) {
33492      return obj.toString();
33493    } else {
33494      return objectToString.call(obj);
33495    }
33496  }
33497
33498  exports.GUID_KEY = GUID_KEY;
33499  exports.makeArray = makeArray;
33500  exports.canInvoke = canInvoke;
33501});
33502enifed('ember-metal/watch_key', ['exports', 'ember-metal/features', 'ember-metal/meta', 'ember-metal/properties', 'ember-metal/utils'], function (exports, _emberMetalFeatures, _emberMetalMeta, _emberMetalProperties, _emberMetalUtils) {
33503  'use strict';
33504
33505  exports.watchKey = watchKey;
33506  exports.unwatchKey = unwatchKey;
33507
33508  var handleMandatorySetter = undefined;
33509
33510  function watchKey(obj, keyName, meta) {
33511    // can't watch length on Array - it is special...
33512    if (keyName === 'length' && Array.isArray(obj)) {
33513      return;
33514    }
33515
33516    var m = meta || _emberMetalMeta.meta(obj);
33517
33518    // activate watching first time
33519    if (!m.peekWatching(keyName)) {
33520      m.writeWatching(keyName, 1);
33521
33522      var possibleDesc = obj[keyName];
33523      var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
33524      if (desc && desc.willWatch) {
33525        desc.willWatch(obj, keyName);
33526      }
33527
33528      if ('function' === typeof obj.willWatchProperty) {
33529        obj.willWatchProperty(keyName);
33530      }
33531
33532      // NOTE: this is dropped for prod + minified builds
33533      handleMandatorySetter(m, obj, keyName);
33534    } else {
33535      m.writeWatching(keyName, (m.peekWatching(keyName) || 0) + 1);
33536    }
33537  }
33538
33539  // Future traveler, although this code looks scary. It merely exists in
33540  // development to aid in development asertions. Production builds of
33541  // ember strip this entire block out
33542  handleMandatorySetter = function handleMandatorySetter(m, obj, keyName) {
33543    var descriptor = _emberMetalUtils.lookupDescriptor(obj, keyName);
33544    var configurable = descriptor ? descriptor.configurable : true;
33545    var isWritable = descriptor ? descriptor.writable : true;
33546    var hasValue = descriptor ? 'value' in descriptor : true;
33547    var possibleDesc = descriptor && descriptor.value;
33548    var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor;
33549
33550    if (isDescriptor) {
33551      return;
33552    }
33553
33554    // this x in Y deopts, so keeping it in this function is better;
33555    if (configurable && isWritable && hasValue && keyName in obj) {
33556      var desc = {
33557        configurable: true,
33558        enumerable: Object.prototype.propertyIsEnumerable.call(obj, keyName),
33559        set: _emberMetalProperties.MANDATORY_SETTER_FUNCTION(keyName),
33560        get: undefined
33561      };
33562
33563      if (Object.prototype.hasOwnProperty.call(obj, keyName)) {
33564        m.writeValues(keyName, obj[keyName]);
33565        desc.get = _emberMetalProperties.DEFAULT_GETTER_FUNCTION(keyName);
33566      } else {
33567        desc.get = _emberMetalProperties.INHERITING_GETTER_FUNCTION(keyName);
33568      }
33569
33570      Object.defineProperty(obj, keyName, desc);
33571    }
33572  };
33573
33574  function unwatchKey(obj, keyName, meta) {
33575    var m = meta || _emberMetalMeta.meta(obj);
33576    var count = m.peekWatching(keyName);
33577    if (count === 1) {
33578      m.writeWatching(keyName, 0);
33579
33580      var possibleDesc = obj[keyName];
33581      var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
33582
33583      if (desc && desc.didUnwatch) {
33584        desc.didUnwatch(obj, keyName);
33585      }
33586
33587      if ('function' === typeof obj.didUnwatchProperty) {
33588        obj.didUnwatchProperty(keyName);
33589      }
33590
33591      // It is true, the following code looks quite WAT. But have no fear, It
33592      // exists purely to improve development ergonomics and is removed from
33593      // ember.min.js and ember.prod.js builds.
33594      //
33595      // Some further context: Once a property is watched by ember, bypassing `set`
33596      // for mutation, will bypass observation. This code exists to assert when
33597      // that occurs, and attempt to provide more helpful feedback. The alternative
33598      // is tricky to debug partially observable properties.
33599      if (!desc && keyName in obj) {
33600        var maybeMandatoryDescriptor = _emberMetalUtils.lookupDescriptor(obj, keyName);
33601
33602        if (maybeMandatoryDescriptor.set && maybeMandatoryDescriptor.set.isMandatorySetter) {
33603          if (maybeMandatoryDescriptor.get && maybeMandatoryDescriptor.get.isInheritingGetter) {
33604            delete obj[keyName];
33605          } else {
33606            Object.defineProperty(obj, keyName, {
33607              configurable: true,
33608              enumerable: Object.prototype.propertyIsEnumerable.call(obj, keyName),
33609              writable: true,
33610              value: m.peekValues(keyName)
33611            });
33612            m.deleteFromValues(keyName);
33613          }
33614        }
33615      }
33616    } else if (count > 1) {
33617      m.writeWatching(keyName, count - 1);
33618    }
33619  }
33620});
33621enifed('ember-metal/watch_path', ['exports', 'ember-metal/meta', 'ember-metal/chains'], function (exports, _emberMetalMeta, _emberMetalChains) {
33622  'use strict';
33623
33624  exports.watchPath = watchPath;
33625  exports.unwatchPath = unwatchPath;
33626
33627  // get the chains for the current object. If the current object has
33628  // chains inherited from the proto they will be cloned and reconfigured for
33629  // the current object.
33630  function chainsFor(obj, meta) {
33631    return (meta || _emberMetalMeta.meta(obj)).writableChains(makeChainNode);
33632  }
33633
33634  function makeChainNode(obj) {
33635    return new _emberMetalChains.ChainNode(null, null, obj);
33636  }
33637
33638  function watchPath(obj, keyPath, meta) {
33639    // can't watch length on Array - it is special...
33640    if (keyPath === 'length' && Array.isArray(obj)) {
33641      return;
33642    }
33643
33644    var m = meta || _emberMetalMeta.meta(obj);
33645    var counter = m.peekWatching(keyPath) || 0;
33646    if (!counter) {
33647      // activate watching first time
33648      m.writeWatching(keyPath, 1);
33649      chainsFor(obj, m).add(keyPath);
33650    } else {
33651      m.writeWatching(keyPath, counter + 1);
33652    }
33653  }
33654
33655  function unwatchPath(obj, keyPath, meta) {
33656    var m = meta || _emberMetalMeta.meta(obj);
33657    var counter = m.peekWatching(keyPath) || 0;
33658
33659    if (counter === 1) {
33660      m.writeWatching(keyPath, 0);
33661      chainsFor(obj, m).remove(keyPath);
33662    } else if (counter > 1) {
33663      m.writeWatching(keyPath, counter - 1);
33664    }
33665  }
33666});
33667enifed('ember-metal/watching', ['exports', 'ember-metal/chains', 'ember-metal/watch_key', 'ember-metal/watch_path', 'ember-metal/path_cache', 'ember-metal/meta'], function (exports, _emberMetalChains, _emberMetalWatch_key, _emberMetalWatch_path, _emberMetalPath_cache, _emberMetalMeta) {
33668  /**
33669  @module ember-metal
33670  */
33671
33672  'use strict';
33673
33674  exports.isWatching = isWatching;
33675  exports.watcherCount = watcherCount;
33676  exports.unwatch = unwatch;
33677  exports.destroy = destroy;
33678
33679  /**
33680    Starts watching a property on an object. Whenever the property changes,
33681    invokes `Ember.propertyWillChange` and `Ember.propertyDidChange`. This is the
33682    primitive used by observers and dependent keys; usually you will never call
33683    this method directly but instead use higher level methods like
33684    `Ember.addObserver()`
33685  
33686    @private
33687    @method watch
33688    @for Ember
33689    @param obj
33690    @param {String} _keyPath
33691  */
33692  function watch(obj, _keyPath, m) {
33693    // can't watch length on Array - it is special...
33694    if (_keyPath === 'length' && Array.isArray(obj)) {
33695      return;
33696    }
33697
33698    if (!_emberMetalPath_cache.isPath(_keyPath)) {
33699      _emberMetalWatch_key.watchKey(obj, _keyPath, m);
33700    } else {
33701      _emberMetalWatch_path.watchPath(obj, _keyPath, m);
33702    }
33703  }
33704
33705  exports.watch = watch;
33706
33707  function isWatching(obj, key) {
33708    var meta = _emberMetalMeta.peekMeta(obj);
33709    return (meta && meta.peekWatching(key)) > 0;
33710  }
33711
33712  function watcherCount(obj, key) {
33713    var meta = _emberMetalMeta.peekMeta(obj);
33714    return meta && meta.peekWatching(key) || 0;
33715  }
33716
33717  function unwatch(obj, _keyPath, m) {
33718    // can't watch length on Array - it is special...
33719    if (_keyPath === 'length' && Array.isArray(obj)) {
33720      return;
33721    }
33722
33723    if (!_emberMetalPath_cache.isPath(_keyPath)) {
33724      _emberMetalWatch_key.unwatchKey(obj, _keyPath, m);
33725    } else {
33726      _emberMetalWatch_path.unwatchPath(obj, _keyPath, m);
33727    }
33728  }
33729
33730  var NODE_STACK = [];
33731
33732  /**
33733    Tears down the meta on an object so that it can be garbage collected.
33734    Multiple calls will have no effect.
33735  
33736    @method destroy
33737    @for Ember
33738    @param {Object} obj  the object to destroy
33739    @return {void}
33740    @private
33741  */
33742
33743  function destroy(obj) {
33744    var meta = _emberMetalMeta.peekMeta(obj);
33745    var node, nodes, key, nodeObject;
33746
33747    if (meta) {
33748      _emberMetalMeta.deleteMeta(obj);
33749      // remove chainWatchers to remove circular references that would prevent GC
33750      node = meta.readableChains();
33751      if (node) {
33752        NODE_STACK.push(node);
33753        // process tree
33754        while (NODE_STACK.length > 0) {
33755          node = NODE_STACK.pop();
33756          // push children
33757          nodes = node._chains;
33758          if (nodes) {
33759            for (key in nodes) {
33760              if (nodes[key] !== undefined) {
33761                NODE_STACK.push(nodes[key]);
33762              }
33763            }
33764          }
33765          // remove chainWatcher in node object
33766          if (node._watching) {
33767            nodeObject = node._object;
33768            if (nodeObject) {
33769              _emberMetalChains.removeChainWatcher(nodeObject, node._key, node);
33770            }
33771          }
33772        }
33773      }
33774    }
33775  }
33776});
33777enifed('ember-metal/weak_map', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/meta'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberMetalMeta) {
33778  'use strict';
33779
33780  exports.default = WeakMap;
33781
33782  var id = 0;
33783  function UNDEFINED() {}
33784
33785  /*
33786   * @private
33787   * @class Ember.WeakMap
33788   *
33789   * A partial polyfill for [WeakMap](http://www.ecma-international.org/ecma-262/6.0/#sec-weakmap-objects).
33790   *
33791   * There is a small but important caveat. This implementation assumes that the
33792   * weak map will live longer (in the sense of garbage collection) than all of its
33793   * keys, otherwise it is possible to leak the values stored in the weak map. In
33794   * practice, most use cases satisfy this limitation which is why it is included
33795   * in ember-metal.
33796   */
33797
33798  function WeakMap() {
33799    _emberMetalDebug.assert('Invoking the WeakMap constructor with arguments is not supported at this time', arguments.length === 0);
33800
33801    this._id = _emberMetalUtils.GUID_KEY + id++;
33802  }
33803
33804  /*
33805   * @method get
33806   * @param key {Object | Function}
33807   * @return {Any} stored value
33808   */
33809  WeakMap.prototype.get = function (obj) {
33810    var meta = _emberMetalMeta.peekMeta(obj);
33811    if (meta) {
33812      var map = meta.readableWeak();
33813      if (map) {
33814        if (map[this._id] === UNDEFINED) {
33815          return undefined;
33816        }
33817
33818        return map[this._id];
33819      }
33820    }
33821  };
33822
33823  /*
33824   * @method set
33825   * @param key {Object | Function}
33826   * @param value {Any}
33827   * @return {WeakMap} the weak map
33828   */
33829  WeakMap.prototype.set = function (obj, value) {
33830    _emberMetalDebug.assert('Uncaught TypeError: Invalid value used as weak map key', obj && (typeof obj === 'object' || typeof obj === 'function'));
33831
33832    if (value === undefined) {
33833      value = UNDEFINED;
33834    }
33835
33836    _emberMetalMeta.meta(obj).writableWeak()[this._id] = value;
33837
33838    return this;
33839  };
33840
33841  /*
33842   * @method has
33843   * @param key {Object | Function}
33844   * @return {boolean} if the key exists
33845   */
33846  WeakMap.prototype.has = function (obj) {
33847    var meta = _emberMetalMeta.peekMeta(obj);
33848    if (meta) {
33849      var map = meta.readableWeak();
33850      if (map) {
33851        return map[this._id] !== undefined;
33852      }
33853    }
33854
33855    return false;
33856  };
33857
33858  /*
33859   * @method delete
33860   * @param key {Object | Function}
33861   * @return {boolean} if the key was deleted
33862   */
33863  WeakMap.prototype.delete = function (obj) {
33864    if (this.has(obj)) {
33865      delete _emberMetalMeta.meta(obj).writableWeak()[this._id];
33866      return true;
33867    } else {
33868      return false;
33869    }
33870  };
33871});
33872enifed('ember-metal-views/htmlbars-renderer', ['exports', 'ember-metal/run_loop', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/assign', 'ember-metal/set_properties', 'ember-views/system/build-component-template', 'ember-metal/environment', 'htmlbars-runtime'], function (exports, _emberMetalRun_loop, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalAssign, _emberMetalSet_properties, _emberViewsSystemBuildComponentTemplate, _emberMetalEnvironment, _htmlbarsRuntime) {
33873  'use strict';
33874
33875  exports.Renderer = Renderer;
33876  exports.MorphSet = MorphSet;
33877
33878  function Renderer(domHelper) {
33879    var _ref = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
33880
33881    var destinedForDOM = _ref.destinedForDOM;
33882
33883    this._dom = domHelper;
33884
33885    // This flag indicates whether the resulting rendered element will be
33886    // inserted into the DOM. This should be set to `false` if the rendered
33887    // element is going to be serialized to HTML without being inserted into
33888    // the DOM (e.g., in FastBoot mode). By default, this flag is the same
33889    // as whether we are running in an environment with DOM, but may be
33890    // overridden.
33891    this._destinedForDOM = destinedForDOM === undefined ? _emberMetalEnvironment.default.hasDOM : destinedForDOM;
33892  }
33893
33894  Renderer.prototype.prerenderTopLevelView = function Renderer_prerenderTopLevelView(view, renderNode) {
33895    if (view._state === 'inDOM') {
33896      throw new Error('You cannot insert a View that has already been rendered');
33897    }
33898    view.ownerView = renderNode.emberView = view;
33899    view._renderNode = renderNode;
33900
33901    var layout = _emberMetalProperty_get.get(view, 'layout');
33902    var template = _emberMetalProperty_get.get(view, 'template');
33903
33904    var componentInfo = { component: view, layout: layout };
33905
33906    var block = _emberViewsSystemBuildComponentTemplate.default(componentInfo, {}, {
33907      self: view,
33908      templates: template ? { default: template.raw } : undefined
33909    }).block;
33910
33911    view.renderBlock(block, renderNode);
33912    view.lastResult = renderNode.lastResult;
33913    this.clearRenderedViews(view.env);
33914  };
33915
33916  Renderer.prototype.renderTopLevelView = function Renderer_renderTopLevelView(view, renderNode) {
33917    // Check to see if insertion has been canceled.
33918    if (view._willInsert) {
33919      view._willInsert = false;
33920      this.prerenderTopLevelView(view, renderNode);
33921      this.dispatchLifecycleHooks(view.env);
33922    }
33923  };
33924
33925  Renderer.prototype.revalidateTopLevelView = function Renderer_revalidateTopLevelView(view) {
33926    // This guard prevents revalidation on an already-destroyed view.
33927    if (view._renderNode.lastResult) {
33928      view._renderNode.lastResult.revalidate(view.env);
33929      // supports createElement, which operates without moving the view into
33930      // the inDOM state.
33931      if (view._state === 'inDOM') {
33932        this.dispatchLifecycleHooks(view.env);
33933      }
33934      this.clearRenderedViews(view.env);
33935    }
33936  };
33937
33938  Renderer.prototype.dispatchLifecycleHooks = function Renderer_dispatchLifecycleHooks(env) {
33939    var ownerView = env.view;
33940
33941    var lifecycleHooks = env.lifecycleHooks;
33942    var i, hook;
33943
33944    for (i = 0; i < lifecycleHooks.length; i++) {
33945      hook = lifecycleHooks[i];
33946      ownerView._dispatching = hook.type;
33947
33948      switch (hook.type) {
33949        case 'didInsertElement':
33950          this.didInsertElement(hook.view);break;
33951        case 'didUpdate':
33952          this.didUpdate(hook.view);break;
33953      }
33954
33955      this.didRender(hook.view);
33956    }
33957
33958    ownerView._dispatching = null;
33959    env.lifecycleHooks.length = 0;
33960  };
33961
33962  Renderer.prototype.ensureViewNotRendering = function Renderer_ensureViewNotRendering(view) {
33963    var env = view.ownerView.env;
33964    if (env && env.renderedViews.indexOf(view.elementId) !== -1) {
33965      throw new Error('Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.');
33966    }
33967  };
33968
33969  function MorphSet() {
33970    this.morphs = [];
33971  }
33972
33973  MorphSet.prototype.add = function (morph) {
33974    this.morphs.push(morph);
33975    morph.seen = true;
33976  };
33977
33978  MorphSet.prototype.has = function (morph) {
33979    return morph.seen;
33980  };
33981
33982  MorphSet.prototype.clear = function () {
33983    var morphs = this.morphs;
33984    for (var i = 0, l = morphs.length; i < l; i++) {
33985      morphs[i].seen = false;
33986    }
33987
33988    this.morphs = [];
33989  };
33990
33991  Renderer.prototype.clearRenderedViews = function Renderer_clearRenderedViews(env) {
33992    env.renderedNodes.clear();
33993    env.renderedViews.length = 0;
33994  };
33995
33996  // This entry point is called from top-level `view.appendTo`.
33997  Renderer.prototype.appendTo = function Renderer_appendTo(view, target) {
33998    var morph = this._dom.appendMorph(target);
33999    morph.ownerNode = morph;
34000    view._willInsert = true;
34001    _emberMetalRun_loop.default.schedule('render', this, this.renderTopLevelView, view, morph);
34002  };
34003
34004  Renderer.prototype.replaceIn = function Renderer_replaceIn(view, target) {
34005    var morph = this._dom.replaceContentWithMorph(target);
34006    morph.ownerNode = morph;
34007    view._willInsert = true;
34008    _emberMetalRun_loop.default.scheduleOnce('render', this, this.renderTopLevelView, view, morph);
34009  };
34010
34011  Renderer.prototype.createElement = function Renderer_createElement(view) {
34012    var morph = this._dom.createFragmentMorph();
34013    morph.ownerNode = morph;
34014    this.prerenderTopLevelView(view, morph);
34015  };
34016
34017  Renderer.prototype.didCreateElement = function (view, element) {
34018    if (element) {
34019      view.element = element;
34020    }
34021
34022    if (view._transitionTo) {
34023      view._transitionTo('hasElement');
34024    }
34025  }; // hasElement
34026
34027  Renderer.prototype.willInsertElement = function (view) {
34028    if (view.trigger) {
34029      view.trigger('willInsertElement');
34030    }
34031  }; // Will place into DOM.
34032
34033  Renderer.prototype.setAttrs = function (view, attrs) {
34034    _emberMetalProperty_set.set(view, 'attrs', attrs);
34035  }; // Set attrs the first time.
34036
34037  Renderer.prototype.componentInitAttrs = function (component, attrs) {
34038    component.trigger('didInitAttrs', { attrs: attrs });
34039    component.trigger('didReceiveAttrs', { newAttrs: attrs });
34040  }; // Set attrs the first time.
34041
34042  Renderer.prototype.didInsertElement = function (view) {
34043    if (view._transitionTo) {
34044      view._transitionTo('inDOM');
34045    }
34046
34047    if (view.trigger) {
34048      view.trigger('didInsertElement');
34049    }
34050  }; // inDOM // Placed into DOM.
34051
34052  Renderer.prototype.didUpdate = function (view) {
34053    if (view.trigger) {
34054      view.trigger('didUpdate');
34055    }
34056  };
34057
34058  Renderer.prototype.didRender = function (view) {
34059    if (view.trigger) {
34060      view.trigger('didRender');
34061    }
34062  };
34063
34064  Renderer.prototype.updateAttrs = function (view, attrs) {
34065    this.setAttrs(view, attrs);
34066  }; // Setting new attrs.
34067
34068  Renderer.prototype.componentUpdateAttrs = function (component, newAttrs) {
34069    var oldAttrs = null;
34070
34071    if (component.attrs) {
34072      oldAttrs = _emberMetalAssign.default({}, component.attrs);
34073      _emberMetalSet_properties.default(component.attrs, newAttrs);
34074    } else {
34075      _emberMetalProperty_set.set(component, 'attrs', newAttrs);
34076    }
34077
34078    component.trigger('didUpdateAttrs', { oldAttrs: oldAttrs, newAttrs: newAttrs });
34079    component.trigger('didReceiveAttrs', { oldAttrs: oldAttrs, newAttrs: newAttrs });
34080  };
34081
34082  Renderer.prototype.willUpdate = function (view, attrs) {
34083    if (view._willUpdate) {
34084      view._willUpdate(attrs);
34085    }
34086  };
34087
34088  Renderer.prototype.componentWillUpdate = function (component) {
34089    component.trigger('willUpdate');
34090  };
34091
34092  Renderer.prototype.willRender = function (view) {
34093    if (view._willRender) {
34094      view._willRender();
34095    }
34096  };
34097
34098  Renderer.prototype.componentWillRender = function (component) {
34099    component.trigger('willRender');
34100  };
34101
34102  Renderer.prototype.rerender = function (view) {
34103    var renderNode = view._renderNode;
34104
34105    renderNode.isDirty = true;
34106    _htmlbarsRuntime.internal.visitChildren(renderNode.childNodes, function (node) {
34107      if (node.getState().manager) {
34108        node.shouldReceiveAttrs = true;
34109      }
34110      node.isDirty = true;
34111    });
34112
34113    renderNode.ownerNode.emberView.scheduleRevalidate(renderNode, view.toString(), 'rerendering');
34114  };
34115
34116  Renderer.prototype.remove = function (view, shouldDestroy) {
34117    this.willDestroyElement(view);
34118
34119    view._willRemoveElement = true;
34120    _emberMetalRun_loop.default.schedule('render', this, this.renderElementRemoval, view);
34121  };
34122
34123  Renderer.prototype.renderElementRemoval = function Renderer_renderElementRemoval(view) {
34124    // Use the _willRemoveElement flag to avoid mulitple removal attempts in
34125    // case many have been scheduled. This should be more performant than using
34126    // `scheduleOnce`.
34127    if (view._willRemoveElement) {
34128      view._willRemoveElement = false;
34129
34130      if (view._renderNode && view.element && view.element.parentNode) {
34131        view._renderNode.clear();
34132      }
34133      this.didDestroyElement(view);
34134    }
34135  };
34136
34137  Renderer.prototype.willRemoveElement = function () /*view*/{};
34138
34139  Renderer.prototype.willDestroyElement = function (view) {
34140    if (view._willDestroyElement) {
34141      view._willDestroyElement();
34142    }
34143    if (view.trigger) {
34144      view.trigger('willDestroyElement');
34145      view.trigger('willClearRender');
34146    }
34147
34148    if (view._transitionTo) {
34149      view._transitionTo('destroying');
34150    }
34151  };
34152
34153  Renderer.prototype.didDestroyElement = function (view) {
34154    view.element = null;
34155
34156    // Views that are being destroyed should never go back to the preRender state.
34157    // However if we're just destroying an element on a view (as is the case when
34158    // using View#remove) then the view should go to a preRender state so that
34159    // it can be rendered again later.
34160    if (view._state !== 'destroying' && view._transitionTo) {
34161      view._transitionTo('preRender');
34162    }
34163
34164    if (view.trigger) {
34165      view.trigger('didDestroyElement');
34166    }
34167  }; // Element destroyed so view.destroy shouldn't try to remove it removedFromDOM
34168
34169  exports.default = Renderer;
34170});
34171enifed('ember-metal-views/index', ['exports', 'ember-metal-views/htmlbars-renderer'], function (exports, _emberMetalViewsHtmlbarsRenderer) {
34172  'use strict';
34173
34174  function _interopExportWildcard(obj, defaults) { var newObj = defaults({}, obj); delete newObj['default']; return newObj; }
34175
34176  function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
34177
34178  _defaults(exports, _interopExportWildcard(_emberMetalViewsHtmlbarsRenderer, _defaults));
34179});
34180enifed('ember-routing/ext/controller', ['exports', 'ember-metal/property_get', 'ember-runtime/mixins/controller'], function (exports, _emberMetalProperty_get, _emberRuntimeMixinsController) {
34181  'use strict';
34182
34183  /**
34184  @module ember
34185  @submodule ember-routing
34186  */
34187
34188  _emberRuntimeMixinsController.default.reopen({
34189    concatenatedProperties: ['queryParams'],
34190
34191    /**
34192      Defines which query parameters the controller accepts.
34193      If you give the names `['category','page']` it will bind
34194      the values of these query parameters to the variables
34195      `this.category` and `this.page`
34196       @property queryParams
34197      @public
34198    */
34199    queryParams: null,
34200
34201    /**
34202      @property _qpDelegate
34203      @private
34204    */
34205    _qpDelegate: null, // set by route
34206
34207    /**
34208      @method _qpChanged
34209      @private
34210    */
34211    _qpChanged: function (controller, _prop) {
34212      var prop = _prop.substr(0, _prop.length - 3);
34213
34214      var delegate = controller._qpDelegate;
34215      var value = _emberMetalProperty_get.get(controller, prop);
34216      delegate(prop, value);
34217    },
34218
34219    /**
34220      Transition the application into another route. The route may
34221      be either a single route or route path:
34222       ```javascript
34223      aController.transitionToRoute('blogPosts');
34224      aController.transitionToRoute('blogPosts.recentEntries');
34225      ```
34226       Optionally supply a model for the route in question. The model
34227      will be serialized into the URL using the `serialize` hook of
34228      the route:
34229       ```javascript
34230      aController.transitionToRoute('blogPost', aPost);
34231      ```
34232       If a literal is passed (such as a number or a string), it will
34233      be treated as an identifier instead. In this case, the `model`
34234      hook of the route will be triggered:
34235       ```javascript
34236      aController.transitionToRoute('blogPost', 1);
34237      ```
34238       Multiple models will be applied last to first recursively up the
34239      route tree.
34240       ```javascript
34241      App.Router.map(function() {
34242        this.route('blogPost', { path: ':blogPostId' }, function() {
34243          this.route('blogComment', { path: ':blogCommentId', resetNamespace: true });
34244        });
34245      });
34246       aController.transitionToRoute('blogComment', aPost, aComment);
34247      aController.transitionToRoute('blogComment', 1, 13);
34248      ```
34249       It is also possible to pass a URL (a string that starts with a
34250      `/`). This is intended for testing and debugging purposes and
34251      should rarely be used in production code.
34252       ```javascript
34253      aController.transitionToRoute('/');
34254      aController.transitionToRoute('/blog/post/1/comment/13');
34255      aController.transitionToRoute('/blog/posts?sort=title');
34256      ```
34257       An options hash with a `queryParams` property may be provided as
34258      the final argument to add query parameters to the destination URL.
34259       ```javascript
34260      aController.transitionToRoute('blogPost', 1, {
34261        queryParams: {showComments: 'true'}
34262      });
34263       // if you just want to transition the query parameters without changing the route
34264      aController.transitionToRoute({queryParams: {sort: 'date'}});
34265      ```
34266       See also [replaceRoute](/api/classes/Ember.ControllerMixin.html#method_replaceRoute).
34267       @param {String} name the name of the route or a URL
34268      @param {...Object} models the model(s) or identifier(s) to be used
34269        while transitioning to the route.
34270      @param {Object} [options] optional hash with a queryParams property
34271        containing a mapping of query parameters
34272      @for Ember.ControllerMixin
34273      @method transitionToRoute
34274      @public
34275    */
34276    transitionToRoute: function () {
34277      // target may be either another controller or a router
34278      var target = _emberMetalProperty_get.get(this, 'target');
34279      var method = target.transitionToRoute || target.transitionTo;
34280      return method.apply(target, arguments);
34281    },
34282
34283    /**
34284      Transition into another route while replacing the current URL, if possible.
34285      This will replace the current history entry instead of adding a new one.
34286      Beside that, it is identical to `transitionToRoute` in all other respects.
34287       ```javascript
34288      aController.replaceRoute('blogPosts');
34289      aController.replaceRoute('blogPosts.recentEntries');
34290      ```
34291       Optionally supply a model for the route in question. The model
34292      will be serialized into the URL using the `serialize` hook of
34293      the route:
34294       ```javascript
34295      aController.replaceRoute('blogPost', aPost);
34296      ```
34297       If a literal is passed (such as a number or a string), it will
34298      be treated as an identifier instead. In this case, the `model`
34299      hook of the route will be triggered:
34300       ```javascript
34301      aController.replaceRoute('blogPost', 1);
34302      ```
34303       Multiple models will be applied last to first recursively up the
34304      route tree.
34305       ```javascript
34306      App.Router.map(function() {
34307        this.route('blogPost', { path: ':blogPostId' }, function() {
34308          this.route('blogComment', { path: ':blogCommentId', resetNamespace: true });
34309        });
34310      });
34311       aController.replaceRoute('blogComment', aPost, aComment);
34312      aController.replaceRoute('blogComment', 1, 13);
34313      ```
34314       It is also possible to pass a URL (a string that starts with a
34315      `/`). This is intended for testing and debugging purposes and
34316      should rarely be used in production code.
34317       ```javascript
34318      aController.replaceRoute('/');
34319      aController.replaceRoute('/blog/post/1/comment/13');
34320      ```
34321       @param {String} name the name of the route or a URL
34322      @param {...Object} models the model(s) or identifier(s) to be used
34323      while transitioning to the route.
34324      @for Ember.ControllerMixin
34325      @method replaceRoute
34326      @private
34327    */
34328    replaceRoute: function () {
34329      // target may be either another controller or a router
34330      var target = _emberMetalProperty_get.get(this, 'target');
34331      var method = target.replaceRoute || target.replaceWith;
34332      return method.apply(target, arguments);
34333    }
34334  });
34335
34336  exports.default = _emberRuntimeMixinsController.default;
34337});
34338enifed('ember-routing/ext/run_loop', ['exports', 'ember-metal/run_loop'], function (exports, _emberMetalRun_loop) {
34339  'use strict';
34340
34341  /**
34342  @module ember
34343  @submodule ember-views
34344  */
34345
34346  // Add a new named queue after the 'actions' queue (where RSVP promises
34347  // resolve), which is used in router transitions to prevent unnecessary
34348  // loading state entry if all context promises resolve on the
34349  // 'actions' queue first.
34350  _emberMetalRun_loop.default._addQueue('routerTransitions', 'actions');
34351});
34352enifed('ember-routing/index', ['exports', 'ember-metal/core', 'ember-routing/ext/run_loop', 'ember-routing/ext/controller', 'ember-routing/location/api', 'ember-routing/location/none_location', 'ember-routing/location/hash_location', 'ember-routing/location/history_location', 'ember-routing/location/auto_location', 'ember-routing/system/generate_controller', 'ember-routing/system/controller_for', 'ember-routing/system/dsl', 'ember-routing/system/router', 'ember-routing/system/route'], function (exports, _emberMetalCore, _emberRoutingExtRun_loop, _emberRoutingExtController, _emberRoutingLocationApi, _emberRoutingLocationNone_location, _emberRoutingLocationHash_location, _emberRoutingLocationHistory_location, _emberRoutingLocationAuto_location, _emberRoutingSystemGenerate_controller, _emberRoutingSystemController_for, _emberRoutingSystemDsl, _emberRoutingSystemRouter, _emberRoutingSystemRoute) {
34353  /**
34354  @module ember
34355  @submodule ember-routing
34356  */
34357
34358  'use strict';
34359
34360  _emberMetalCore.default.Location = _emberRoutingLocationApi.default;
34361  _emberMetalCore.default.AutoLocation = _emberRoutingLocationAuto_location.default;
34362  _emberMetalCore.default.HashLocation = _emberRoutingLocationHash_location.default;
34363  _emberMetalCore.default.HistoryLocation = _emberRoutingLocationHistory_location.default;
34364  _emberMetalCore.default.NoneLocation = _emberRoutingLocationNone_location.default;
34365
34366  _emberMetalCore.default.controllerFor = _emberRoutingSystemController_for.default;
34367  _emberMetalCore.default.generateControllerFactory = _emberRoutingSystemGenerate_controller.generateControllerFactory;
34368  _emberMetalCore.default.generateController = _emberRoutingSystemGenerate_controller.default;
34369  _emberMetalCore.default.RouterDSL = _emberRoutingSystemDsl.default;
34370  _emberMetalCore.default.Router = _emberRoutingSystemRouter.default;
34371  _emberMetalCore.default.Route = _emberRoutingSystemRoute.default;
34372
34373  exports.default = _emberMetalCore.default;
34374});
34375
34376// ES6TODO: Cleanup modules with side-effects below
34377enifed('ember-routing/location/api', ['exports', 'ember-metal/debug', 'ember-metal/environment', 'ember-routing/location/util'], function (exports, _emberMetalDebug, _emberMetalEnvironment, _emberRoutingLocationUtil) {
34378  'use strict';
34379
34380  /**
34381  @module ember
34382  @submodule ember-routing
34383  */
34384
34385  /**
34386    Ember.Location returns an instance of the correct implementation of
34387    the `location` API.
34388  
34389    ## Implementations
34390  
34391    You can pass an implementation name (`hash`, `history`, `none`) to force a
34392    particular implementation to be used in your application.
34393  
34394    ### HashLocation
34395  
34396    Using `HashLocation` results in URLs with a `#` (hash sign) separating the
34397    server side URL portion of the URL from the portion that is used by Ember.
34398    This relies upon the `hashchange` event existing in the browser.
34399  
34400    Example:
34401  
34402    ```javascript
34403    App.Router.map(function() {
34404      this.route('posts', function() {
34405        this.route('new');
34406      });
34407    });
34408  
34409    App.Router.reopen({
34410      location: 'hash'
34411    });
34412    ```
34413  
34414    This will result in a posts.new url of `/#/posts/new`.
34415  
34416    ### HistoryLocation
34417  
34418    Using `HistoryLocation` results in URLs that are indistinguishable from a
34419    standard URL. This relies upon the browser's `history` API.
34420  
34421    Example:
34422  
34423    ```javascript
34424    App.Router.map(function() {
34425      this.route('posts', function() {
34426        this.route('new');
34427      });
34428    });
34429  
34430    App.Router.reopen({
34431      location: 'history'
34432    });
34433    ```
34434  
34435    This will result in a posts.new url of `/posts/new`.
34436  
34437    Keep in mind that your server must serve the Ember app at all the routes you
34438    define.
34439  
34440    ### AutoLocation
34441  
34442    Using `AutoLocation`, the router will use the best Location class supported by
34443    the browser it is running in.
34444  
34445    Browsers that support the `history` API will use `HistoryLocation`, those that
34446    do not, but still support the `hashchange` event will use `HashLocation`, and
34447    in the rare case neither is supported will use `NoneLocation`.
34448  
34449    Example:
34450  
34451    ```javascript
34452    App.Router.map(function() {
34453      this.route('posts', function() {
34454        this.route('new');
34455      });
34456    });
34457  
34458    App.Router.reopen({
34459      location: 'auto'
34460    });
34461    ```
34462  
34463    This will result in a posts.new url of `/posts/new` for modern browsers that
34464    support the `history` api or `/#/posts/new` for older ones, like Internet
34465    Explorer 9 and below.
34466  
34467    When a user visits a link to your application, they will be automatically
34468    upgraded or downgraded to the appropriate `Location` class, with the URL
34469    transformed accordingly, if needed.
34470  
34471    Keep in mind that since some of your users will use `HistoryLocation`, your
34472    server must serve the Ember app at all the routes you define.
34473  
34474    ### NoneLocation
34475  
34476    Using `NoneLocation` causes Ember to not store the applications URL state
34477    in the actual URL. This is generally used for testing purposes, and is one
34478    of the changes made when calling `App.setupForTesting()`.
34479  
34480    ## Location API
34481  
34482    Each location implementation must provide the following methods:
34483  
34484    * implementation: returns the string name used to reference the implementation.
34485    * getURL: returns the current URL.
34486    * setURL(path): sets the current URL.
34487    * replaceURL(path): replace the current URL (optional).
34488    * onUpdateURL(callback): triggers the callback when the URL changes.
34489    * formatURL(url): formats `url` to be placed into `href` attribute.
34490    * detect() (optional): instructs the location to do any feature detection
34491        necessary. If the location needs to redirect to a different URL, it
34492        can cancel routing by setting the `cancelRouterSetup` property on itself
34493        to `false`.
34494  
34495    Calling setURL or replaceURL will not trigger onUpdateURL callbacks.
34496  
34497    @class Location
34498    @namespace Ember
34499    @static
34500    @private
34501  */
34502  exports.default = {
34503    /**
34504     This is deprecated in favor of using the container to lookup the location
34505     implementation as desired.
34506      For example:
34507      ```javascript
34508     // Given a location registered as follows:
34509     container.register('location:history-test', HistoryTestLocation);
34510      // You could create a new instance via:
34511     container.lookup('location:history-test');
34512     ```
34513       @method create
34514      @param {Object} options
34515      @return {Object} an instance of an implementation of the `location` API
34516      @deprecated Use the container to lookup the location implementation that you
34517      need.
34518      @private
34519    */
34520    create: function (options) {
34521      var implementation = options && options.implementation;
34522      _emberMetalDebug.assert('Ember.Location.create: you must specify a \'implementation\' option', !!implementation);
34523
34524      var implementationClass = this.implementations[implementation];
34525      _emberMetalDebug.assert('Ember.Location.create: ' + implementation + ' is not a valid implementation', !!implementationClass);
34526
34527      return implementationClass.create.apply(implementationClass, arguments);
34528    },
34529
34530    implementations: {},
34531    _location: _emberMetalEnvironment.default.location,
34532
34533    /**
34534      Returns the current `location.hash` by parsing location.href since browsers
34535      inconsistently URL-decode `location.hash`.
34536       https://bugzilla.mozilla.org/show_bug.cgi?id=483304
34537       @private
34538      @method getHash
34539      @since 1.4.0
34540    */
34541    _getHash: function () {
34542      return _emberRoutingLocationUtil.getHash(this.location);
34543    }
34544  };
34545});
34546enifed('ember-routing/location/auto_location', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'container/owner', 'ember-runtime/system/object', 'ember-metal/environment', 'ember-routing/location/util'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalUtils, _containerOwner, _emberRuntimeSystemObject, _emberMetalEnvironment, _emberRoutingLocationUtil) {
34547  'use strict';
34548
34549  exports.getHistoryPath = getHistoryPath;
34550  exports.getHashPath = getHashPath;
34551
34552  /**
34553  @module ember
34554  @submodule ember-routing
34555  */
34556
34557  /**
34558    Ember.AutoLocation will select the best location option based off browser
34559    support with the priority order: history, hash, none.
34560  
34561    Clean pushState paths accessed by hashchange-only browsers will be redirected
34562    to the hash-equivalent and vice versa so future transitions are consistent.
34563  
34564    Keep in mind that since some of your users will use `HistoryLocation`, your
34565    server must serve the Ember app at all the routes you define.
34566  
34567    @class AutoLocation
34568    @namespace Ember
34569    @static
34570    @private
34571  */
34572  exports.default = _emberRuntimeSystemObject.default.extend({
34573    /**
34574      @private
34575       The browser's `location` object. This is typically equivalent to
34576      `window.location`, but may be overridden for testing.
34577       @property location
34578      @default environment.location
34579    */
34580    location: _emberMetalEnvironment.default.location,
34581
34582    /**
34583      @private
34584       The browser's `history` object. This is typically equivalent to
34585      `window.history`, but may be overridden for testing.
34586       @since 1.5.1
34587      @property history
34588      @default environment.history
34589    */
34590    history: _emberMetalEnvironment.default.history,
34591
34592    /**
34593     @private
34594      The user agent's global variable. In browsers, this will be `window`.
34595      @since 1.11
34596     @property global
34597     @default environment.global
34598    */
34599    global: _emberMetalEnvironment.default.global,
34600
34601    /**
34602      @private
34603       The browser's `userAgent`. This is typically equivalent to
34604      `navigator.userAgent`, but may be overridden for testing.
34605       @since 1.5.1
34606      @property userAgent
34607      @default environment.history
34608    */
34609    userAgent: _emberMetalEnvironment.default.userAgent,
34610
34611    /**
34612      @private
34613       This property is used by the router to know whether to cancel the routing
34614      setup process, which is needed while we redirect the browser.
34615       @since 1.5.1
34616      @property cancelRouterSetup
34617      @default false
34618    */
34619    cancelRouterSetup: false,
34620
34621    /**
34622      @private
34623       Will be pre-pended to path upon state change.
34624       @since 1.5.1
34625      @property rootURL
34626      @default '/'
34627    */
34628    rootURL: '/',
34629
34630    /**
34631     Called by the router to instruct the location to do any feature detection
34632     necessary. In the case of AutoLocation, we detect whether to use history
34633     or hash concrete implementations.
34634      @private
34635    */
34636    detect: function () {
34637      var rootURL = this.rootURL;
34638
34639      _emberMetalDebug.assert('rootURL must end with a trailing forward slash e.g. "/app/"', rootURL.charAt(rootURL.length - 1) === '/');
34640
34641      var implementation = detectImplementation({
34642        location: this.location,
34643        history: this.history,
34644        userAgent: this.userAgent,
34645        rootURL: rootURL,
34646        documentMode: this.documentMode,
34647        global: this.global
34648      });
34649
34650      if (implementation === false) {
34651        _emberMetalProperty_set.set(this, 'cancelRouterSetup', true);
34652        implementation = 'none';
34653      }
34654
34655      var concrete = _containerOwner.getOwner(this).lookup('location:' + implementation);
34656      _emberMetalProperty_set.set(concrete, 'rootURL', rootURL);
34657
34658      _emberMetalDebug.assert('Could not find location \'' + implementation + '\'.', !!concrete);
34659
34660      _emberMetalProperty_set.set(this, 'concreteImplementation', concrete);
34661    },
34662
34663    initState: delegateToConcreteImplementation('initState'),
34664    getURL: delegateToConcreteImplementation('getURL'),
34665    setURL: delegateToConcreteImplementation('setURL'),
34666    replaceURL: delegateToConcreteImplementation('replaceURL'),
34667    onUpdateURL: delegateToConcreteImplementation('onUpdateURL'),
34668    formatURL: delegateToConcreteImplementation('formatURL'),
34669
34670    willDestroy: function () {
34671      var concreteImplementation = _emberMetalProperty_get.get(this, 'concreteImplementation');
34672
34673      if (concreteImplementation) {
34674        concreteImplementation.destroy();
34675      }
34676    }
34677  });
34678
34679  function delegateToConcreteImplementation(methodName) {
34680    return function () {
34681      var concreteImplementation = _emberMetalProperty_get.get(this, 'concreteImplementation');
34682      _emberMetalDebug.assert('AutoLocation\'s detect() method should be called before calling any other hooks.', !!concreteImplementation);
34683
34684      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
34685        args[_key] = arguments[_key];
34686      }
34687
34688      return _emberMetalUtils.tryInvoke(concreteImplementation, methodName, args);
34689    };
34690  }
34691
34692  /*
34693    Given the browser's `location`, `history` and `userAgent`, and a configured
34694    root URL, this function detects whether the browser supports the [History
34695    API](https://developer.mozilla.org/en-US/docs/Web/API/History) and returns a
34696    string representing the Location object to use based on its determination.
34697  
34698    For example, if the page loads in an evergreen browser, this function would
34699    return the string "history", meaning the history API and thus HistoryLocation
34700    should be used. If the page is loaded in IE8, it will return the string
34701    "hash," indicating that the History API should be simulated by manipulating the
34702    hash portion of the location.
34703  
34704  */
34705
34706  function detectImplementation(options) {
34707    var location = options.location;
34708    var userAgent = options.userAgent;
34709    var history = options.history;
34710    var documentMode = options.documentMode;
34711    var global = options.global;
34712    var rootURL = options.rootURL;
34713
34714    var implementation = 'none';
34715    var cancelRouterSetup = false;
34716    var currentPath = _emberRoutingLocationUtil.getFullPath(location);
34717
34718    if (_emberRoutingLocationUtil.supportsHistory(userAgent, history)) {
34719      var historyPath = getHistoryPath(rootURL, location);
34720
34721      // If the browser supports history and we have a history path, we can use
34722      // the history location with no redirects.
34723      if (currentPath === historyPath) {
34724        return 'history';
34725      } else {
34726        if (currentPath.substr(0, 2) === '/#') {
34727          history.replaceState({ path: historyPath }, null, historyPath);
34728          implementation = 'history';
34729        } else {
34730          cancelRouterSetup = true;
34731          _emberRoutingLocationUtil.replacePath(location, historyPath);
34732        }
34733      }
34734    } else if (_emberRoutingLocationUtil.supportsHashChange(documentMode, global)) {
34735      var hashPath = getHashPath(rootURL, location);
34736
34737      // Be sure we're using a hashed path, otherwise let's switch over it to so
34738      // we start off clean and consistent. We'll count an index path with no
34739      // hash as "good enough" as well.
34740      if (currentPath === hashPath || currentPath === '/' && hashPath === '/#/') {
34741        implementation = 'hash';
34742      } else {
34743        // Our URL isn't in the expected hash-supported format, so we want to
34744        // cancel the router setup and replace the URL to start off clean
34745        cancelRouterSetup = true;
34746        _emberRoutingLocationUtil.replacePath(location, hashPath);
34747      }
34748    }
34749
34750    if (cancelRouterSetup) {
34751      return false;
34752    }
34753
34754    return implementation;
34755  }
34756
34757  /**
34758    @private
34759  
34760    Returns the current path as it should appear for HistoryLocation supported
34761    browsers. This may very well differ from the real current path (e.g. if it
34762    starts off as a hashed URL)
34763  */
34764
34765  function getHistoryPath(rootURL, location) {
34766    var path = _emberRoutingLocationUtil.getPath(location);
34767    var hash = _emberRoutingLocationUtil.getHash(location);
34768    var query = _emberRoutingLocationUtil.getQuery(location);
34769    var rootURLIndex = path.indexOf(rootURL);
34770    var routeHash, hashParts;
34771
34772    _emberMetalDebug.assert('Path ' + path + ' does not start with the provided rootURL ' + rootURL, rootURLIndex === 0);
34773
34774    // By convention, Ember.js routes using HashLocation are required to start
34775    // with `#/`. Anything else should NOT be considered a route and should
34776    // be passed straight through, without transformation.
34777    if (hash.substr(0, 2) === '#/') {
34778      // There could be extra hash segments after the route
34779      hashParts = hash.substr(1).split('#');
34780      // The first one is always the route url
34781      routeHash = hashParts.shift();
34782
34783      // If the path already has a trailing slash, remove the one
34784      // from the hashed route so we don't double up.
34785      if (path.slice(-1) === '/') {
34786        routeHash = routeHash.substr(1);
34787      }
34788
34789      // This is the "expected" final order
34790      path = path + routeHash + query;
34791
34792      if (hashParts.length) {
34793        path += '#' + hashParts.join('#');
34794      }
34795    } else {
34796      path = path + query + hash;
34797    }
34798
34799    return path;
34800  }
34801
34802  /**
34803    @private
34804  
34805    Returns the current path as it should appear for HashLocation supported
34806    browsers. This may very well differ from the real current path.
34807  
34808    @method _getHashPath
34809  */
34810
34811  function getHashPath(rootURL, location) {
34812    var path = rootURL;
34813    var historyPath = getHistoryPath(rootURL, location);
34814    var routePath = historyPath.substr(rootURL.length);
34815
34816    if (routePath !== '') {
34817      if (routePath.charAt(0) !== '/') {
34818        routePath = '/' + routePath;
34819      }
34820
34821      path += '#' + routePath;
34822    }
34823
34824    return path;
34825  }
34826});
34827enifed('ember-routing/location/hash_location', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/run_loop', 'ember-metal/utils', 'ember-runtime/system/object', 'ember-routing/location/api', 'ember-views/system/jquery'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalRun_loop, _emberMetalUtils, _emberRuntimeSystemObject, _emberRoutingLocationApi, _emberViewsSystemJquery) {
34828  'use strict';
34829
34830  /**
34831  @module ember
34832  @submodule ember-routing
34833  */
34834
34835  /**
34836    `Ember.HashLocation` implements the location API using the browser's
34837    hash. At present, it relies on a `hashchange` event existing in the
34838    browser.
34839  
34840    @class HashLocation
34841    @namespace Ember
34842    @extends Ember.Object
34843    @private
34844  */
34845  exports.default = _emberRuntimeSystemObject.default.extend({
34846    implementation: 'hash',
34847
34848    init: function () {
34849      _emberMetalProperty_set.set(this, 'location', _emberMetalProperty_get.get(this, '_location') || window.location);
34850    },
34851
34852    /**
34853      @private
34854       Returns normalized location.hash
34855       @since 1.5.1
34856      @method getHash
34857    */
34858    getHash: _emberRoutingLocationApi.default._getHash,
34859
34860    /**
34861      Returns the normalized URL, constructed from `location.hash`.
34862       e.g. `#/foo` => `/foo` as well as `#/foo#bar` => `/foo#bar`.
34863       By convention, hashed paths must begin with a forward slash, otherwise they
34864      are not treated as a path so we can distinguish intent.
34865       @private
34866      @method getURL
34867    */
34868    getURL: function () {
34869      var originalPath = this.getHash().substr(1);
34870      var outPath = originalPath;
34871
34872      if (outPath.charAt(0) !== '/') {
34873        outPath = '/';
34874
34875        // Only add the # if the path isn't empty.
34876        // We do NOT want `/#` since the ampersand
34877        // is only included (conventionally) when
34878        // the location.hash has a value
34879        if (originalPath) {
34880          outPath += '#' + originalPath;
34881        }
34882      }
34883
34884      return outPath;
34885    },
34886
34887    /**
34888      Set the `location.hash` and remembers what was set. This prevents
34889      `onUpdateURL` callbacks from triggering when the hash was set by
34890      `HashLocation`.
34891       @private
34892      @method setURL
34893      @param path {String}
34894    */
34895    setURL: function (path) {
34896      _emberMetalProperty_get.get(this, 'location').hash = path;
34897      _emberMetalProperty_set.set(this, 'lastSetURL', path);
34898    },
34899
34900    /**
34901      Uses location.replace to update the url without a page reload
34902      or history modification.
34903       @private
34904      @method replaceURL
34905      @param path {String}
34906    */
34907    replaceURL: function (path) {
34908      _emberMetalProperty_get.get(this, 'location').replace('#' + path);
34909      _emberMetalProperty_set.set(this, 'lastSetURL', path);
34910    },
34911
34912    /**
34913      Register a callback to be invoked when the hash changes. These
34914      callbacks will execute when the user presses the back or forward
34915      button, but not after `setURL` is invoked.
34916       @private
34917      @method onUpdateURL
34918      @param callback {Function}
34919    */
34920    onUpdateURL: function (callback) {
34921      var _this = this;
34922
34923      var guid = _emberMetalUtils.guidFor(this);
34924
34925      _emberViewsSystemJquery.default(window).on('hashchange.ember-location-' + guid, function () {
34926        _emberMetalRun_loop.default(function () {
34927          var path = _this.getURL();
34928          if (_emberMetalProperty_get.get(_this, 'lastSetURL') === path) {
34929            return;
34930          }
34931
34932          _emberMetalProperty_set.set(_this, 'lastSetURL', null);
34933
34934          callback(path);
34935        });
34936      });
34937    },
34938
34939    /**
34940      Given a URL, formats it to be placed into the page as part
34941      of an element's `href` attribute.
34942       This is used, for example, when using the {{action}} helper
34943      to generate a URL based on an event.
34944       @private
34945      @method formatURL
34946      @param url {String}
34947    */
34948    formatURL: function (url) {
34949      return '#' + url;
34950    },
34951
34952    /**
34953      Cleans up the HashLocation event listener.
34954       @private
34955      @method willDestroy
34956    */
34957    willDestroy: function () {
34958      var guid = _emberMetalUtils.guidFor(this);
34959
34960      _emberViewsSystemJquery.default(window).off('hashchange.ember-location-' + guid);
34961    }
34962  });
34963});
34964enifed('ember-routing/location/history_location', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'ember-runtime/system/object', 'ember-routing/location/api', 'ember-views/system/jquery'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalUtils, _emberRuntimeSystemObject, _emberRoutingLocationApi, _emberViewsSystemJquery) {
34965  'use strict';
34966
34967  /**
34968  @module ember
34969  @submodule ember-routing
34970  */
34971
34972  var popstateFired = false;
34973
34974  /**
34975    Ember.HistoryLocation implements the location API using the browser's
34976    history.pushState API.
34977  
34978    @class HistoryLocation
34979    @namespace Ember
34980    @extends Ember.Object
34981    @private
34982  */
34983  exports.default = _emberRuntimeSystemObject.default.extend({
34984    implementation: 'history',
34985
34986    init: function () {
34987      _emberMetalProperty_set.set(this, 'location', _emberMetalProperty_get.get(this, 'location') || window.location);
34988      _emberMetalProperty_set.set(this, 'baseURL', _emberViewsSystemJquery.default('base').attr('href') || '');
34989    },
34990
34991    /**
34992      Used to set state on first call to setURL
34993       @private
34994      @method initState
34995    */
34996    initState: function () {
34997      var history = _emberMetalProperty_get.get(this, 'history') || window.history;
34998      _emberMetalProperty_set.set(this, 'history', history);
34999
35000      if (history && 'state' in history) {
35001        this.supportsHistory = true;
35002      }
35003
35004      this.replaceState(this.formatURL(this.getURL()));
35005    },
35006
35007    /**
35008      Will be pre-pended to path upon state change
35009       @property rootURL
35010      @default '/'
35011      @private
35012    */
35013    rootURL: '/',
35014
35015    /**
35016      Returns the current `location.pathname` without `rootURL` or `baseURL`
35017       @private
35018      @method getURL
35019      @return url {String}
35020    */
35021    getURL: function () {
35022      var rootURL = _emberMetalProperty_get.get(this, 'rootURL');
35023      var location = _emberMetalProperty_get.get(this, 'location');
35024      var path = location.pathname;
35025      var baseURL = _emberMetalProperty_get.get(this, 'baseURL');
35026
35027      rootURL = rootURL.replace(/\/$/, '');
35028      baseURL = baseURL.replace(/\/$/, '');
35029
35030      var url = path.replace(baseURL, '').replace(rootURL, '');
35031      var search = location.search || '';
35032
35033      url += search;
35034      url += this.getHash();
35035
35036      return url;
35037    },
35038
35039    /**
35040      Uses `history.pushState` to update the url without a page reload.
35041       @private
35042      @method setURL
35043      @param path {String}
35044    */
35045    setURL: function (path) {
35046      var state = this.getState();
35047      path = this.formatURL(path);
35048
35049      if (!state || state.path !== path) {
35050        this.pushState(path);
35051      }
35052    },
35053
35054    /**
35055      Uses `history.replaceState` to update the url without a page reload
35056      or history modification.
35057       @private
35058      @method replaceURL
35059      @param path {String}
35060    */
35061    replaceURL: function (path) {
35062      var state = this.getState();
35063      path = this.formatURL(path);
35064
35065      if (!state || state.path !== path) {
35066        this.replaceState(path);
35067      }
35068    },
35069
35070    /**
35071      Get the current `history.state`. Checks for if a polyfill is
35072      required and if so fetches this._historyState. The state returned
35073      from getState may be null if an iframe has changed a window's
35074      history.
35075       @private
35076      @method getState
35077      @return state {Object}
35078    */
35079    getState: function () {
35080      if (this.supportsHistory) {
35081        return _emberMetalProperty_get.get(this, 'history').state;
35082      }
35083
35084      return this._historyState;
35085    },
35086
35087    /**
35088     Pushes a new state.
35089      @private
35090     @method pushState
35091     @param path {String}
35092    */
35093    pushState: function (path) {
35094      var state = { path: path };
35095
35096      _emberMetalProperty_get.get(this, 'history').pushState(state, null, path);
35097
35098      this._historyState = state;
35099
35100      // used for webkit workaround
35101      this._previousURL = this.getURL();
35102    },
35103
35104    /**
35105     Replaces the current state.
35106      @private
35107     @method replaceState
35108     @param path {String}
35109    */
35110    replaceState: function (path) {
35111      var state = { path: path };
35112      _emberMetalProperty_get.get(this, 'history').replaceState(state, null, path);
35113
35114      this._historyState = state;
35115
35116      // used for webkit workaround
35117      this._previousURL = this.getURL();
35118    },
35119
35120    /**
35121      Register a callback to be invoked whenever the browser
35122      history changes, including using forward and back buttons.
35123       @private
35124      @method onUpdateURL
35125      @param callback {Function}
35126    */
35127    onUpdateURL: function (callback) {
35128      var _this = this;
35129
35130      var guid = _emberMetalUtils.guidFor(this);
35131
35132      _emberViewsSystemJquery.default(window).on('popstate.ember-location-' + guid, function (e) {
35133        // Ignore initial page load popstate event in Chrome
35134        if (!popstateFired) {
35135          popstateFired = true;
35136          if (_this.getURL() === _this._previousURL) {
35137            return;
35138          }
35139        }
35140        callback(_this.getURL());
35141      });
35142    },
35143
35144    /**
35145      Used when using `{{action}}` helper.  The url is always appended to the rootURL.
35146       @private
35147      @method formatURL
35148      @param url {String}
35149      @return formatted url {String}
35150    */
35151    formatURL: function (url) {
35152      var rootURL = _emberMetalProperty_get.get(this, 'rootURL');
35153      var baseURL = _emberMetalProperty_get.get(this, 'baseURL');
35154
35155      if (url !== '') {
35156        rootURL = rootURL.replace(/\/$/, '');
35157        baseURL = baseURL.replace(/\/$/, '');
35158      } else if (baseURL.match(/^\//) && rootURL.match(/^\//)) {
35159        baseURL = baseURL.replace(/\/$/, '');
35160      }
35161
35162      return baseURL + rootURL + url;
35163    },
35164
35165    /**
35166      Cleans up the HistoryLocation event listener.
35167       @private
35168      @method willDestroy
35169    */
35170    willDestroy: function () {
35171      var guid = _emberMetalUtils.guidFor(this);
35172
35173      _emberViewsSystemJquery.default(window).off('popstate.ember-location-' + guid);
35174    },
35175
35176    /**
35177      @private
35178       Returns normalized location.hash
35179       @method getHash
35180    */
35181    getHash: _emberRoutingLocationApi.default._getHash
35182  });
35183});
35184enifed('ember-routing/location/none_location', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-runtime/system/object'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberRuntimeSystemObject) {
35185  'use strict';
35186
35187  /**
35188  @module ember
35189  @submodule ember-routing
35190  */
35191
35192  /**
35193    Ember.NoneLocation does not interact with the browser. It is useful for
35194    testing, or when you need to manage state with your Router, but temporarily
35195    don't want it to muck with the URL (for example when you embed your
35196    application in a larger page).
35197  
35198    @class NoneLocation
35199    @namespace Ember
35200    @extends Ember.Object
35201    @private
35202  */
35203  exports.default = _emberRuntimeSystemObject.default.extend({
35204    implementation: 'none',
35205    path: '',
35206
35207    /**
35208      Returns the current path.
35209       @private
35210      @method getURL
35211      @return {String} path
35212    */
35213    getURL: function () {
35214      return _emberMetalProperty_get.get(this, 'path');
35215    },
35216
35217    /**
35218      Set the path and remembers what was set. Using this method
35219      to change the path will not invoke the `updateURL` callback.
35220       @private
35221      @method setURL
35222      @param path {String}
35223    */
35224    setURL: function (path) {
35225      _emberMetalProperty_set.set(this, 'path', path);
35226    },
35227
35228    /**
35229      Register a callback to be invoked when the path changes. These
35230      callbacks will execute when the user presses the back or forward
35231      button, but not after `setURL` is invoked.
35232       @private
35233      @method onUpdateURL
35234      @param callback {Function}
35235    */
35236    onUpdateURL: function (callback) {
35237      this.updateCallback = callback;
35238    },
35239
35240    /**
35241      Sets the path and calls the `updateURL` callback.
35242       @private
35243      @method handleURL
35244      @param callback {Function}
35245    */
35246    handleURL: function (url) {
35247      _emberMetalProperty_set.set(this, 'path', url);
35248      this.updateCallback(url);
35249    },
35250
35251    /**
35252      Given a URL, formats it to be placed into the page as part
35253      of an element's `href` attribute.
35254       This is used, for example, when using the {{action}} helper
35255      to generate a URL based on an event.
35256       @private
35257      @method formatURL
35258      @param url {String}
35259      @return {String} url
35260    */
35261    formatURL: function (url) {
35262      // The return value is not overly meaningful, but we do not want to throw
35263      // errors when test code renders templates containing {{action href=true}}
35264      // helpers.
35265      return url;
35266    }
35267  });
35268});
35269enifed('ember-routing/location/util', ['exports'], function (exports) {
35270  /**
35271    @private
35272  
35273    Returns the current `location.pathname`, normalized for IE inconsistencies.
35274  */
35275  'use strict';
35276
35277  exports.getPath = getPath;
35278  exports.getQuery = getQuery;
35279  exports.getHash = getHash;
35280  exports.getFullPath = getFullPath;
35281  exports.getOrigin = getOrigin;
35282  exports.supportsHashChange = supportsHashChange;
35283  exports.supportsHistory = supportsHistory;
35284  exports.replacePath = replacePath;
35285
35286  function getPath(location) {
35287    var pathname = location.pathname;
35288    // Various versions of IE/Opera don't always return a leading slash
35289    if (pathname.charAt(0) !== '/') {
35290      pathname = '/' + pathname;
35291    }
35292
35293    return pathname;
35294  }
35295
35296  /**
35297    @private
35298  
35299    Returns the current `location.search`.
35300  */
35301
35302  function getQuery(location) {
35303    return location.search;
35304  }
35305
35306  /**
35307    @private
35308  
35309    Returns the current `location.hash` by parsing location.href since browsers
35310    inconsistently URL-decode `location.hash`.
35311  
35312    Should be passed the browser's `location` object as the first argument.
35313  
35314    https://bugzilla.mozilla.org/show_bug.cgi?id=483304
35315  */
35316
35317  function getHash(location) {
35318    var href = location.href;
35319    var hashIndex = href.indexOf('#');
35320
35321    if (hashIndex === -1) {
35322      return '';
35323    } else {
35324      return href.substr(hashIndex);
35325    }
35326  }
35327
35328  function getFullPath(location) {
35329    return getPath(location) + getQuery(location) + getHash(location);
35330  }
35331
35332  function getOrigin(location) {
35333    var origin = location.origin;
35334
35335    // Older browsers, especially IE, don't have origin
35336    if (!origin) {
35337      origin = location.protocol + '//' + location.hostname;
35338
35339      if (location.port) {
35340        origin += ':' + location.port;
35341      }
35342    }
35343
35344    return origin;
35345  }
35346
35347  /*
35348    `documentMode` only exist in Internet Explorer, and it's tested because IE8 running in
35349    IE7 compatibility mode claims to support `onhashchange` but actually does not.
35350  
35351    `global` is an object that may have an `onhashchange` property.
35352  
35353    @private
35354    @function supportsHashChange
35355  */
35356
35357  function supportsHashChange(documentMode, global) {
35358    return 'onhashchange' in global && (documentMode === undefined || documentMode > 7);
35359  }
35360
35361  /*
35362    `userAgent` is a user agent string. We use user agent testing here, because
35363    the stock Android browser is known to have buggy versions of the History API,
35364    in some Android versions.
35365  
35366    @private
35367    @function supportsHistory
35368  */
35369
35370  function supportsHistory(userAgent, history) {
35371    // Boosted from Modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
35372    // The stock browser on Android 2.2 & 2.3, and 4.0.x returns positive on history support
35373    // Unfortunately support is really buggy and there is no clean way to detect
35374    // these bugs, so we fall back to a user agent sniff :(
35375
35376    // We only want Android 2 and 4.0, stock browser, and not Chrome which identifies
35377    // itself as 'Mobile Safari' as well, nor Windows Phone.
35378    if ((userAgent.indexOf('Android 2.') !== -1 || userAgent.indexOf('Android 4.0') !== -1) && userAgent.indexOf('Mobile Safari') !== -1 && userAgent.indexOf('Chrome') === -1 && userAgent.indexOf('Windows Phone') === -1) {
35379      return false;
35380    }
35381
35382    return !!(history && 'pushState' in history);
35383  }
35384
35385  /**
35386    Replaces the current location, making sure we explicitly include the origin
35387    to prevent redirecting to a different origin.
35388  
35389    @private
35390  */
35391
35392  function replacePath(location, path) {
35393    location.replace(getOrigin(location) + path);
35394  }
35395});
35396enifed('ember-routing/services/routing', ['exports', 'ember-runtime/system/service', 'ember-metal/property_get', 'ember-metal/computed_macros', 'ember-routing/utils', 'ember-metal/assign'], function (exports, _emberRuntimeSystemService, _emberMetalProperty_get, _emberMetalComputed_macros, _emberRoutingUtils, _emberMetalAssign) {
35397  /**
35398  @module ember
35399  @submodule ember-routing
35400  */
35401
35402  'use strict';
35403
35404  /**
35405    The Routing service is used by LinkComponent, and provides facilities for
35406    the component/view layer to interact with the router.
35407  
35408    While still private, this service can eventually be opened up, and provides
35409    the set of API needed for components to control routing without interacting
35410    with router internals.
35411  
35412    @private
35413    @class RoutingService
35414  */
35415  exports.default = _emberRuntimeSystemService.default.extend({
35416    router: null,
35417
35418    targetState: _emberMetalComputed_macros.readOnly('router.targetState'),
35419    currentState: _emberMetalComputed_macros.readOnly('router.currentState'),
35420    currentRouteName: _emberMetalComputed_macros.readOnly('router.currentRouteName'),
35421    currentPath: _emberMetalComputed_macros.readOnly('router.currentPath'),
35422
35423    availableRoutes: function () {
35424      return Object.keys(_emberMetalProperty_get.get(this, 'router').router.recognizer.names);
35425    },
35426
35427    hasRoute: function (routeName) {
35428      return _emberMetalProperty_get.get(this, 'router').hasRoute(routeName);
35429    },
35430
35431    transitionTo: function (routeName, models, queryParams, shouldReplace) {
35432      var router = _emberMetalProperty_get.get(this, 'router');
35433
35434      var transition = router._doTransition(routeName, models, queryParams);
35435
35436      if (shouldReplace) {
35437        transition.method('replace');
35438      }
35439    },
35440
35441    normalizeQueryParams: function (routeName, models, queryParams) {
35442      var router = _emberMetalProperty_get.get(this, 'router');
35443      router._prepareQueryParams(routeName, models, queryParams);
35444    },
35445
35446    generateURL: function (routeName, models, queryParams) {
35447      var router = _emberMetalProperty_get.get(this, 'router');
35448      if (!router.router) {
35449        return;
35450      }
35451
35452      var visibleQueryParams = {};
35453      _emberMetalAssign.default(visibleQueryParams, queryParams);
35454
35455      this.normalizeQueryParams(routeName, models, visibleQueryParams);
35456
35457      var args = _emberRoutingUtils.routeArgs(routeName, models, visibleQueryParams);
35458      return router.generate.apply(router, args);
35459    },
35460
35461    isActiveForRoute: function (contexts, queryParams, routeName, routerState, isCurrentWhenSpecified) {
35462      var router = _emberMetalProperty_get.get(this, 'router');
35463
35464      var handlers = router.router.recognizer.handlersFor(routeName);
35465      var leafName = handlers[handlers.length - 1].handler;
35466      var maximumContexts = numberOfContextsAcceptedByHandler(routeName, handlers);
35467
35468      // NOTE: any ugliness in the calculation of activeness is largely
35469      // due to the fact that we support automatic normalizing of
35470      // `resource` -> `resource.index`, even though there might be
35471      // dynamic segments / query params defined on `resource.index`
35472      // which complicates (and makes somewhat ambiguous) the calculation
35473      // of activeness for links that link to `resource` instead of
35474      // directly to `resource.index`.
35475
35476      // if we don't have enough contexts revert back to full route name
35477      // this is because the leaf route will use one of the contexts
35478      if (contexts.length > maximumContexts) {
35479        routeName = leafName;
35480      }
35481
35482      return routerState.isActiveIntent(routeName, contexts, queryParams, !isCurrentWhenSpecified);
35483    }
35484  });
35485
35486  function numberOfContextsAcceptedByHandler(handler, handlerInfos) {
35487    var req = 0;
35488    for (var i = 0, l = handlerInfos.length; i < l; i++) {
35489      req = req + handlerInfos[i].names.length;
35490      if (handlerInfos[i].handler === handler) {
35491        break;
35492      }
35493    }
35494
35495    return req;
35496  }
35497});
35498enifed('ember-routing/system/cache', ['exports', 'ember-runtime/system/object'], function (exports, _emberRuntimeSystemObject) {
35499  'use strict';
35500
35501  exports.default = _emberRuntimeSystemObject.default.extend({
35502    init: function () {
35503      this.cache = {};
35504    },
35505    has: function (bucketKey) {
35506      return bucketKey in this.cache;
35507    },
35508    stash: function (bucketKey, key, value) {
35509      var bucket = this.cache[bucketKey];
35510      if (!bucket) {
35511        bucket = this.cache[bucketKey] = {};
35512      }
35513      bucket[key] = value;
35514    },
35515    lookup: function (bucketKey, prop, defaultValue) {
35516      var cache = this.cache;
35517      if (!(bucketKey in cache)) {
35518        return defaultValue;
35519      }
35520      var bucket = cache[bucketKey];
35521      if (prop in bucket) {
35522        return bucket[prop];
35523      } else {
35524        return defaultValue;
35525      }
35526    },
35527    cache: null
35528  });
35529});
35530enifed("ember-routing/system/controller_for", ["exports"], function (exports) {
35531  /**
35532  @module ember
35533  @submodule ember-routing
35534  */
35535
35536  /**
35537  
35538    Finds a controller instance.
35539  
35540    @for Ember
35541    @method controllerFor
35542    @private
35543  */
35544  "use strict";
35545
35546  exports.default = controllerFor;
35547
35548  function controllerFor(container, controllerName, lookupOptions) {
35549    return container.lookup("controller:" + controllerName, lookupOptions);
35550  }
35551});
35552enifed('ember-routing/system/dsl', ['exports', 'ember-metal/debug'], function (exports, _emberMetalDebug) {
35553  'use strict';
35554
35555  /**
35556  @module ember
35557  @submodule ember-routing
35558  */
35559
35560  function DSL(name, options) {
35561    this.parent = name;
35562    this.enableLoadingSubstates = options && options.enableLoadingSubstates;
35563    this.matches = [];
35564    this.explicitIndex = undefined;
35565    this.options = options;
35566  }
35567
35568  exports.default = DSL;
35569
35570  DSL.prototype = {
35571    route: function (name, options, callback) {
35572      var dummyErrorRoute = '/_unused_dummy_error_path_route_' + name + '/:error';
35573      if (arguments.length === 2 && typeof options === 'function') {
35574        callback = options;
35575        options = {};
35576      }
35577
35578      if (arguments.length === 1) {
35579        options = {};
35580      }
35581
35582      _emberMetalDebug.assert('\'' + name + '\' cannot be used as a route name.', (function () {
35583        if (options.overrideNameAssertion === true) {
35584          return true;
35585        }
35586
35587        return ['array', 'basic', 'object', 'application'].indexOf(name) === -1;
35588      })());
35589
35590      _emberMetalDebug.warn('Using a route named \'select\' (and defining a App.SelectView) will prevent you from using {{view \'select\'}}', name !== 'select', { id: 'ember-routing.dsl-select-route' });
35591
35592      if (this.enableLoadingSubstates) {
35593        createRoute(this, name + '_loading', { resetNamespace: options.resetNamespace });
35594        createRoute(this, name + '_error', { path: dummyErrorRoute });
35595      }
35596
35597      if (callback) {
35598        var fullName = getFullName(this, name, options.resetNamespace);
35599        var dsl = new DSL(fullName, this.options);
35600
35601        createRoute(dsl, 'loading');
35602        createRoute(dsl, 'error', { path: dummyErrorRoute });
35603
35604        callback.call(dsl);
35605
35606        createRoute(this, name, options, dsl.generate());
35607      } else {
35608        createRoute(this, name, options);
35609      }
35610    },
35611
35612    push: function (url, name, callback) {
35613      var parts = name.split('.');
35614      if (url === '' || url === '/' || parts[parts.length - 1] === 'index') {
35615        this.explicitIndex = true;
35616      }
35617
35618      this.matches.push([url, name, callback]);
35619    },
35620
35621    resource: function (name, options, callback) {
35622      if (arguments.length === 2 && typeof options === 'function') {
35623        callback = options;
35624        options = {};
35625      }
35626
35627      if (arguments.length === 1) {
35628        options = {};
35629      }
35630
35631      options.resetNamespace = true;
35632      _emberMetalDebug.deprecate('this.resource() is deprecated. Use this.route(\'name\', { resetNamespace: true }, function () {}) instead.', false, { id: 'ember-routing.router-resource', until: '3.0.0' });
35633      this.route(name, options, callback);
35634    },
35635
35636    generate: function () {
35637      var dslMatches = this.matches;
35638
35639      if (!this.explicitIndex) {
35640        this.route('index', { path: '/' });
35641      }
35642
35643      return function (match) {
35644        for (var i = 0, l = dslMatches.length; i < l; i++) {
35645          var dslMatch = dslMatches[i];
35646          match(dslMatch[0]).to(dslMatch[1], dslMatch[2]);
35647        }
35648      };
35649    }
35650  };
35651
35652  function canNest(dsl) {
35653    return dsl.parent && dsl.parent !== 'application';
35654  }
35655
35656  function getFullName(dsl, name, resetNamespace) {
35657    if (canNest(dsl) && resetNamespace !== true) {
35658      return dsl.parent + '.' + name;
35659    } else {
35660      return name;
35661    }
35662  }
35663
35664  function createRoute(dsl, name, options, callback) {
35665    options = options || {};
35666
35667    var fullName = getFullName(dsl, name, options.resetNamespace);
35668
35669    if (typeof options.path !== 'string') {
35670      options.path = '/' + name;
35671    }
35672
35673    dsl.push(options.path, fullName, callback);
35674  }
35675
35676  DSL.map = function (callback) {
35677    var dsl = new DSL();
35678    callback.call(dsl);
35679    return dsl;
35680  };
35681});
35682enifed('ember-routing/system/generate_controller', ['exports', 'ember-metal/debug', 'ember-metal/property_get'], function (exports, _emberMetalDebug, _emberMetalProperty_get) {
35683  'use strict';
35684
35685  exports.generateControllerFactory = generateControllerFactory;
35686  exports.default = generateController;
35687
35688  /**
35689  @module ember
35690  @submodule ember-routing
35691  */
35692
35693  /**
35694    Generates a controller factory
35695  
35696    @for Ember
35697    @method generateControllerFactory
35698    @private
35699  */
35700
35701  function generateControllerFactory(owner, controllerName, context) {
35702    var Factory, fullName;
35703
35704    Factory = owner._lookupFactory('controller:basic').extend({
35705      isGenerated: true,
35706      toString: function () {
35707        return '(generated ' + controllerName + ' controller)';
35708      }
35709    });
35710
35711    fullName = 'controller:' + controllerName;
35712
35713    owner.register(fullName, Factory);
35714
35715    return Factory;
35716  }
35717
35718  /**
35719    Generates and instantiates a controller.
35720  
35721    The type of the generated controller factory is derived
35722    from the context. If the context is an array an array controller
35723    is generated, if an object, an object controller otherwise, a basic
35724    controller is generated.
35725  
35726    @for Ember
35727    @method generateController
35728    @private
35729    @since 1.3.0
35730  */
35731
35732  function generateController(owner, controllerName, context) {
35733    generateControllerFactory(owner, controllerName, context);
35734
35735    var fullName = 'controller:' + controllerName;
35736    var instance = owner.lookup(fullName);
35737
35738    if (_emberMetalProperty_get.get(instance, 'namespace.LOG_ACTIVE_GENERATION')) {
35739      _emberMetalDebug.info('generated -> ' + fullName, { fullName: fullName });
35740    }
35741
35742    return instance;
35743  }
35744});
35745enifed('ember-routing/system/query_params', ['exports', 'ember-runtime/system/object'], function (exports, _emberRuntimeSystemObject) {
35746  'use strict';
35747
35748  exports.default = _emberRuntimeSystemObject.default.extend({
35749    isQueryParams: true,
35750    values: null
35751  });
35752});
35753enifed('ember-routing/system/route', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/error', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/get_properties', 'ember-metal/is_none', 'ember-metal/computed', 'ember-metal/assign', 'ember-runtime/utils', 'ember-metal/run_loop', 'ember-runtime/copy', 'ember-runtime/system/string', 'ember-runtime/system/object', 'ember-runtime/system/native_array', 'ember-runtime/mixins/evented', 'ember-runtime/mixins/action_handler', 'ember-routing/system/generate_controller', 'ember-routing/utils', 'container/owner', 'ember-metal/is_empty'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalFeatures, _emberMetalError, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalGet_properties, _emberMetalIs_none, _emberMetalComputed, _emberMetalAssign, _emberRuntimeUtils, _emberMetalRun_loop, _emberRuntimeCopy, _emberRuntimeSystemString, _emberRuntimeSystemObject, _emberRuntimeSystemNative_array, _emberRuntimeMixinsEvented, _emberRuntimeMixinsAction_handler, _emberRoutingSystemGenerate_controller, _emberRoutingUtils, _containerOwner, _emberMetalIs_empty) {
35754  'use strict';
35755
35756  var slice = Array.prototype.slice;
35757
35758  function K() {
35759    return this;
35760  }
35761
35762  /**
35763  @module ember
35764  @submodule ember-routing
35765  */
35766
35767  /**
35768    The `Ember.Route` class is used to define individual routes. Refer to
35769    the [routing guide](http://emberjs.com/guides/routing/) for documentation.
35770  
35771    @class Route
35772    @namespace Ember
35773    @extends Ember.Object
35774    @uses Ember.ActionHandler
35775    @uses Ember.Evented
35776    @public
35777  */
35778  var Route = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsAction_handler.default, _emberRuntimeMixinsEvented.default, {
35779    /**
35780      Configuration hash for this route's queryParams. The possible
35781      configuration options and their defaults are as follows
35782      (assuming a query param whose controller property is `page`):
35783       ```javascript
35784      queryParams: {
35785        page: {
35786          // By default, controller query param properties don't
35787          // cause a full transition when they are changed, but
35788          // rather only cause the URL to update. Setting
35789          // `refreshModel` to true will cause an "in-place"
35790          // transition to occur, whereby the model hooks for
35791          // this route (and any child routes) will re-fire, allowing
35792          // you to reload models (e.g., from the server) using the
35793          // updated query param values.
35794          refreshModel: false,
35795           // By default, changes to controller query param properties
35796          // cause the URL to update via `pushState`, which means an
35797          // item will be added to the browser's history, allowing
35798          // you to use the back button to restore the app to the
35799          // previous state before the query param property was changed.
35800          // Setting `replace` to true will use `replaceState` (or its
35801          // hash location equivalent), which causes no browser history
35802          // item to be added. This options name and default value are
35803          // the same as the `link-to` helper's `replace` option.
35804          replace: false,
35805           // By default, the query param URL key is the same name as
35806          // the controller property name. Use `as` to specify a
35807          // different URL key.
35808          as: 'page'
35809        }
35810      }
35811      ```
35812       @property queryParams
35813      @for Ember.Route
35814      @type Object
35815      @public
35816    */
35817    queryParams: {},
35818
35819    /**
35820      The name of the route, dot-delimited.
35821       For example, a route found at `app/routes/posts/post.js` or
35822      `app/posts/post/route.js` (with pods) will have a `routeName` of
35823      `posts.post`.
35824       @property routeName
35825      @for Ember.Route
35826      @type String
35827      @public
35828    */
35829
35830    /**
35831      @private
35832       @property _qp
35833    */
35834    _qp: _emberMetalComputed.computed(function () {
35835      var _this = this;
35836
35837      var controllerProto, combinedQueryParameterConfiguration;
35838
35839      var controllerName = this.controllerName || this.routeName;
35840      var definedControllerClass = _containerOwner.getOwner(this)._lookupFactory('controller:' + controllerName);
35841      var queryParameterConfiguraton = _emberMetalProperty_get.get(this, 'queryParams');
35842      var hasRouterDefinedQueryParams = !!Object.keys(queryParameterConfiguraton).length;
35843
35844      if (definedControllerClass) {
35845        // the developer has authored a controller class in their application for this route
35846        // access the prototype, find its query params and normalize their object shape
35847        // them merge in the query params for the route. As a mergedProperty, Route#queryParams is always
35848        // at least `{}`
35849        controllerProto = definedControllerClass.proto();
35850
35851        var controllerDefinedQueryParameterConfiguration = _emberMetalProperty_get.get(controllerProto, 'queryParams');
35852        var normalizedControllerQueryParameterConfiguration = _emberRoutingUtils.normalizeControllerQueryParams(controllerDefinedQueryParameterConfiguration);
35853        combinedQueryParameterConfiguration = mergeEachQueryParams(normalizedControllerQueryParameterConfiguration, queryParameterConfiguraton);
35854      } else if (hasRouterDefinedQueryParams) {
35855        // the developer has not defined a controller but *has* supplied route query params.
35856        // Generate a class for them so we can later insert default values
35857        var generatedControllerClass = _emberRoutingSystemGenerate_controller.generateControllerFactory(_containerOwner.getOwner(this), controllerName);
35858        controllerProto = generatedControllerClass.proto();
35859        combinedQueryParameterConfiguration = queryParameterConfiguraton;
35860      }
35861
35862      var qps = [];
35863      var map = {};
35864      var propertyNames = [];
35865
35866      for (var propName in combinedQueryParameterConfiguration) {
35867        if (!combinedQueryParameterConfiguration.hasOwnProperty(propName)) {
35868          continue;
35869        }
35870
35871        // to support the dubious feature of using unknownProperty
35872        // on queryParams configuration
35873        if (propName === 'unknownProperty' || propName === '_super') {
35874          // possible todo: issue deprecation warning?
35875          continue;
35876        }
35877
35878        var desc = combinedQueryParameterConfiguration[propName];
35879
35880        var scope = desc.scope || 'model';
35881        var parts;
35882
35883        if (scope === 'controller') {
35884          parts = [];
35885        }
35886
35887        var urlKey = desc.as || this.serializeQueryParamKey(propName);
35888        var defaultValue = _emberMetalProperty_get.get(controllerProto, propName);
35889
35890        if (Array.isArray(defaultValue)) {
35891          defaultValue = _emberRuntimeSystemNative_array.A(defaultValue.slice());
35892        }
35893
35894        var type = desc.type || _emberRuntimeUtils.typeOf(defaultValue);
35895
35896        var defaultValueSerialized = this.serializeQueryParam(defaultValue, urlKey, type);
35897        var scopedPropertyName = controllerName + ':' + propName;
35898        var qp = {
35899          undecoratedDefaultValue: _emberMetalProperty_get.get(controllerProto, propName),
35900          defaultValue: defaultValue,
35901          serializedDefaultValue: defaultValueSerialized,
35902          serializedValue: defaultValueSerialized,
35903
35904          type: type,
35905          urlKey: urlKey,
35906          prop: propName,
35907          scopedPropertyName: scopedPropertyName,
35908          ctrl: controllerName,
35909          route: this,
35910          parts: parts, // provided later when stashNames is called if 'model' scope
35911          values: null, // provided later when setup is called. no idea why.
35912          scope: scope,
35913          prefix: ''
35914        };
35915
35916        map[propName] = map[urlKey] = map[scopedPropertyName] = qp;
35917        qps.push(qp);
35918        propertyNames.push(propName);
35919      }
35920
35921      return {
35922        qps: qps,
35923        map: map,
35924        propertyNames: propertyNames,
35925        states: {
35926          /*
35927            Called when a query parameter changes in the URL, this route cares
35928            about that query parameter, but the route is not currently
35929            in the active route hierarchy.
35930          */
35931          inactive: function (prop, value) {
35932            var qp = map[prop];
35933            _this._qpChanged(prop, value, qp);
35934          },
35935          /*
35936            Called when a query parameter changes in the URL, this route cares
35937            about that query parameter, and the route is currently
35938            in the active route hierarchy.
35939          */
35940          active: function (prop, value) {
35941            var qp = map[prop];
35942            _this._qpChanged(prop, value, qp);
35943            return _this._activeQPChanged(map[prop], value);
35944          },
35945          /*
35946            Called when a value of a query parameter this route handles changes in a controller
35947            and the route is currently in the active route hierarchy.
35948          */
35949          allowOverrides: function (prop, value) {
35950            var qp = map[prop];
35951            _this._qpChanged(prop, value, qp);
35952            return _this._updatingQPChanged(map[prop]);
35953          }
35954        }
35955      };
35956    }),
35957
35958    /**
35959      @private
35960       @property _names
35961    */
35962    _names: null,
35963
35964    /**
35965      @private
35966       @method _stashNames
35967    */
35968    _stashNames: function (_handlerInfo, dynamicParent) {
35969      var handlerInfo = _handlerInfo;
35970      if (this._names) {
35971        return;
35972      }
35973      var names = this._names = handlerInfo._names;
35974
35975      if (!names.length) {
35976        handlerInfo = dynamicParent;
35977        names = handlerInfo && handlerInfo._names || [];
35978      }
35979
35980      var qps = _emberMetalProperty_get.get(this, '_qp.qps');
35981      var len = qps.length;
35982
35983      var namePaths = new Array(names.length);
35984      for (var a = 0, nlen = names.length; a < nlen; ++a) {
35985        namePaths[a] = handlerInfo.name + '.' + names[a];
35986      }
35987
35988      for (var i = 0; i < len; ++i) {
35989        var qp = qps[i];
35990        if (qp.scope === 'model') {
35991          qp.parts = namePaths;
35992        }
35993        qp.prefix = qp.ctrl;
35994      }
35995    },
35996
35997    /**
35998      @private
35999       @property _activeQPChanged
36000    */
36001    _activeQPChanged: function (qp, value) {
36002      var router = this.router;
36003      router._activeQPChanged(qp.scopedPropertyName, value);
36004    },
36005
36006    /**
36007      @private
36008      @method _updatingQPChanged
36009    */
36010    _updatingQPChanged: function (qp) {
36011      var router = this.router;
36012      router._updatingQPChanged(qp.urlKey);
36013    },
36014
36015    mergedProperties: ['queryParams'],
36016
36017    /**
36018      Retrieves parameters, for current route using the state.params
36019      variable and getQueryParamsFor, using the supplied routeName.
36020       @method paramsFor
36021      @param {String} name
36022      @public
36023    */
36024    paramsFor: function (name) {
36025      var route = _containerOwner.getOwner(this).lookup('route:' + name);
36026
36027      if (!route) {
36028        return {};
36029      }
36030
36031      var transition = this.router.router.activeTransition;
36032      var state = transition ? transition.state : this.router.router.state;
36033
36034      var params = {};
36035      _emberMetalAssign.default(params, state.params[name]);
36036      _emberMetalAssign.default(params, getQueryParamsFor(route, state));
36037
36038      return params;
36039    },
36040
36041    /**
36042      Serializes the query parameter key
36043       @method serializeQueryParamKey
36044      @param {String} controllerPropertyName
36045      @private
36046    */
36047    serializeQueryParamKey: function (controllerPropertyName) {
36048      return controllerPropertyName;
36049    },
36050
36051    /**
36052      Serializes value of the query parameter based on defaultValueType
36053       @method serializeQueryParam
36054      @param {Object} value
36055      @param {String} urlKey
36056      @param {String} defaultValueType
36057      @private
36058    */
36059    serializeQueryParam: function (value, urlKey, defaultValueType) {
36060      // urlKey isn't used here, but anyone overriding
36061      // can use it to provide serialization specific
36062      // to a certain query param.
36063      if (defaultValueType === 'array') {
36064        return JSON.stringify(value);
36065      }
36066      return '' + value;
36067    },
36068
36069    /**
36070      Deserializes value of the query parameter based on defaultValueType
36071       @method deserializeQueryParam
36072      @param {Object} value
36073      @param {String} urlKey
36074      @param {String} defaultValueType
36075      @private
36076    */
36077    deserializeQueryParam: function (value, urlKey, defaultValueType) {
36078      // urlKey isn't used here, but anyone overriding
36079      // can use it to provide deserialization specific
36080      // to a certain query param.
36081
36082      // Use the defaultValueType of the default value (the initial value assigned to a
36083      // controller query param property), to intelligently deserialize and cast.
36084      if (defaultValueType === 'boolean') {
36085        return value === 'true' ? true : false;
36086      } else if (defaultValueType === 'number') {
36087        return Number(value).valueOf();
36088      } else if (defaultValueType === 'array') {
36089        return _emberRuntimeSystemNative_array.A(JSON.parse(value));
36090      }
36091      return value;
36092    },
36093
36094    /**
36095      @private
36096       @property _optionsForQueryParam
36097    */
36098    _optionsForQueryParam: function (qp) {
36099      return _emberMetalProperty_get.get(this, 'queryParams.' + qp.urlKey) || _emberMetalProperty_get.get(this, 'queryParams.' + qp.prop) || {};
36100    },
36101
36102    /**
36103      A hook you can use to reset controller values either when the model
36104      changes or the route is exiting.
36105       ```javascript
36106      App.ArticlesRoute = Ember.Route.extend({
36107        // ...
36108         resetController: function(controller, isExiting, transition) {
36109          if (isExiting) {
36110            controller.set('page', 1);
36111          }
36112        }
36113      });
36114      ```
36115       @method resetController
36116      @param {Controller} controller instance
36117      @param {Boolean} isExiting
36118      @param {Object} transition
36119      @since 1.7.0
36120      @public
36121    */
36122    resetController: K,
36123
36124    /**
36125      @private
36126       @method exit
36127    */
36128    exit: function () {
36129      this.deactivate();
36130      this.trigger('deactivate');
36131      this.teardownViews();
36132    },
36133
36134    /**
36135      @private
36136       @method _reset
36137      @since 1.7.0
36138    */
36139    _reset: function (isExiting, transition) {
36140      var controller = this.controller;
36141      controller._qpDelegate = _emberMetalProperty_get.get(this, '_qp.states.inactive');
36142
36143      this.resetController(controller, isExiting, transition);
36144    },
36145
36146    /**
36147      @private
36148       @method enter
36149    */
36150    enter: function () {
36151      this.connections = [];
36152      this.activate();
36153      this.trigger('activate');
36154    },
36155
36156    /**
36157      The name of the view to use by default when rendering this routes template.
36158       When rendering a template, the route will, by default, determine the
36159      template and view to use from the name of the route itself. If you need to
36160      define a specific view, set this property.
36161       This is useful when multiple routes would benefit from using the same view
36162      because it doesn't require a custom `renderTemplate` method. For example,
36163      the following routes will all render using the `App.PostsListView` view:
36164       ```javascript
36165      var PostsList = Ember.Route.extend({
36166        viewName: 'postsList'
36167      });
36168       App.PostsIndexRoute = PostsList.extend();
36169      App.PostsArchivedRoute = PostsList.extend();
36170      ```
36171       @property viewName
36172      @type String
36173      @default null
36174      @since 1.4.0
36175      @public
36176    */
36177    viewName: null,
36178
36179    /**
36180      The name of the template to use by default when rendering this routes
36181      template.
36182       This is similar with `viewName`, but is useful when you just want a custom
36183      template without a view.
36184       ```javascript
36185      var PostsList = Ember.Route.extend({
36186        templateName: 'posts/list'
36187      });
36188       App.PostsIndexRoute = PostsList.extend();
36189      App.PostsArchivedRoute = PostsList.extend();
36190      ```
36191       @property templateName
36192      @type String
36193      @default null
36194      @since 1.4.0
36195      @public
36196    */
36197    templateName: null,
36198
36199    /**
36200      The name of the controller to associate with this route.
36201       By default, Ember will lookup a route's controller that matches the name
36202      of the route (i.e. `App.PostController` for `App.PostRoute`). However,
36203      if you would like to define a specific controller to use, you can do so
36204      using this property.
36205       This is useful in many ways, as the controller specified will be:
36206       * passed to the `setupController` method.
36207      * used as the controller for the view being rendered by the route.
36208      * returned from a call to `controllerFor` for the route.
36209       @property controllerName
36210      @type String
36211      @default null
36212      @since 1.4.0
36213      @public
36214    */
36215    controllerName: null,
36216
36217    /**
36218      The `willTransition` action is fired at the beginning of any
36219      attempted transition with a `Transition` object as the sole
36220      argument. This action can be used for aborting, redirecting,
36221      or decorating the transition from the currently active routes.
36222       A good example is preventing navigation when a form is
36223      half-filled out:
36224       ```javascript
36225      App.ContactFormRoute = Ember.Route.extend({
36226        actions: {
36227          willTransition: function(transition) {
36228            if (this.controller.get('userHasEnteredData')) {
36229              this.controller.displayNavigationConfirm();
36230              transition.abort();
36231            }
36232          }
36233        }
36234      });
36235      ```
36236       You can also redirect elsewhere by calling
36237      `this.transitionTo('elsewhere')` from within `willTransition`.
36238      Note that `willTransition` will not be fired for the
36239      redirecting `transitionTo`, since `willTransition` doesn't
36240      fire when there is already a transition underway. If you want
36241      subsequent `willTransition` actions to fire for the redirecting
36242      transition, you must first explicitly call
36243      `transition.abort()`.
36244       To allow the `willTransition` event to continue bubbling to the parent
36245      route, use `return true;`. When the `willTransition` method has a
36246      return value of `true` then the parent route's `willTransition` method
36247      will be fired, enabling "bubbling" behavior for the event.
36248       @event willTransition
36249      @param {Transition} transition
36250      @public
36251    */
36252
36253    /**
36254      The `didTransition` action is fired after a transition has
36255      successfully been completed. This occurs after the normal model
36256      hooks (`beforeModel`, `model`, `afterModel`, `setupController`)
36257      have resolved. The `didTransition` action has no arguments,
36258      however, it can be useful for tracking page views or resetting
36259      state on the controller.
36260       ```javascript
36261      App.LoginRoute = Ember.Route.extend({
36262        actions: {
36263          didTransition: function() {
36264            this.controller.get('errors.base').clear();
36265            return true; // Bubble the didTransition event
36266          }
36267        }
36268      });
36269      ```
36270       @event didTransition
36271      @since 1.2.0
36272      @public
36273    */
36274
36275    /**
36276      The `loading` action is fired on the route when a route's `model`
36277      hook returns a promise that is not already resolved. The current
36278      `Transition` object is the first parameter and the route that
36279      triggered the loading event is the second parameter.
36280       ```javascript
36281      App.ApplicationRoute = Ember.Route.extend({
36282        actions: {
36283          loading: function(transition, route) {
36284            var view = Ember.View.create({
36285              classNames: ['app-loading']
36286            })
36287            .append();
36288             this.router.one('didTransition', function() {
36289              view.destroy();
36290            });
36291             return true; // Bubble the loading event
36292          }
36293        }
36294      });
36295      ```
36296       @event loading
36297      @param {Transition} transition
36298      @param {Ember.Route} route The route that triggered the loading event
36299      @since 1.2.0
36300      @public
36301    */
36302
36303    /**
36304      When attempting to transition into a route, any of the hooks
36305      may return a promise that rejects, at which point an `error`
36306      action will be fired on the partially-entered routes, allowing
36307      for per-route error handling logic, or shared error handling
36308      logic defined on a parent route.
36309       Here is an example of an error handler that will be invoked
36310      for rejected promises from the various hooks on the route,
36311      as well as any unhandled errors from child routes:
36312       ```javascript
36313      App.AdminRoute = Ember.Route.extend({
36314        beforeModel: function() {
36315          return Ember.RSVP.reject('bad things!');
36316        },
36317         actions: {
36318          error: function(error, transition) {
36319            // Assuming we got here due to the error in `beforeModel`,
36320            // we can expect that error === "bad things!",
36321            // but a promise model rejecting would also
36322            // call this hook, as would any errors encountered
36323            // in `afterModel`.
36324             // The `error` hook is also provided the failed
36325            // `transition`, which can be stored and later
36326            // `.retry()`d if desired.
36327             this.transitionTo('login');
36328          }
36329        }
36330      });
36331      ```
36332       `error` actions that bubble up all the way to `ApplicationRoute`
36333      will fire a default error handler that logs the error. You can
36334      specify your own global default error handler by overriding the
36335      `error` handler on `ApplicationRoute`:
36336       ```javascript
36337      App.ApplicationRoute = Ember.Route.extend({
36338        actions: {
36339          error: function(error, transition) {
36340            this.controllerFor('banner').displayError(error.message);
36341          }
36342        }
36343      });
36344      ```
36345      @event error
36346      @param {Error} error
36347      @param {Transition} transition
36348      @public
36349    */
36350
36351    /**
36352      This event is triggered when the router enters the route. It is
36353      not executed when the model for the route changes.
36354       ```javascript
36355      App.ApplicationRoute = Ember.Route.extend({
36356        collectAnalytics: function(){
36357          collectAnalytics();
36358        }.on('activate')
36359      });
36360      ```
36361       @event activate
36362      @since 1.9.0
36363      @public
36364    */
36365
36366    /**
36367      This event is triggered when the router completely exits this
36368      route. It is not executed when the model for the route changes.
36369       ```javascript
36370      App.IndexRoute = Ember.Route.extend({
36371        trackPageLeaveAnalytics: function(){
36372          trackPageLeaveAnalytics();
36373        }.on('deactivate')
36374      });
36375      ```
36376       @event deactivate
36377      @since 1.9.0
36378      @public
36379    */
36380
36381    /**
36382      The controller associated with this route.
36383       Example
36384       ```javascript
36385      App.FormRoute = Ember.Route.extend({
36386        actions: {
36387          willTransition: function(transition) {
36388            if (this.controller.get('userHasEnteredData') &&
36389                !confirm('Are you sure you want to abandon progress?')) {
36390              transition.abort();
36391            } else {
36392              // Bubble the `willTransition` action so that
36393              // parent routes can decide whether or not to abort.
36394              return true;
36395            }
36396          }
36397        }
36398      });
36399      ```
36400       @property controller
36401      @type Ember.Controller
36402      @since 1.6.0
36403      @public
36404    */
36405
36406    actions: {
36407
36408      queryParamsDidChange: function (changed, totalPresent, removed) {
36409        var qpMap = _emberMetalProperty_get.get(this, '_qp').map;
36410
36411        var totalChanged = Object.keys(changed).concat(Object.keys(removed));
36412        for (var i = 0, len = totalChanged.length; i < len; ++i) {
36413          var qp = qpMap[totalChanged[i]];
36414          if (qp && _emberMetalProperty_get.get(this._optionsForQueryParam(qp), 'refreshModel') && this.router.currentState) {
36415            this.refresh();
36416          }
36417        }
36418
36419        return true;
36420      },
36421
36422      finalizeQueryParamChange: function (params, finalParams, transition) {
36423        if (this.routeName !== 'application') {
36424          return true;
36425        }
36426
36427        // Transition object is absent for intermediate transitions.
36428        if (!transition) {
36429          return;
36430        }
36431
36432        var handlerInfos = transition.state.handlerInfos;
36433        var router = this.router;
36434        var qpMeta = router._queryParamsFor(handlerInfos[handlerInfos.length - 1].name);
36435        var changes = router._qpUpdates;
36436        var replaceUrl;
36437
36438        _emberRoutingUtils.stashParamNames(router, handlerInfos);
36439
36440        for (var i = 0, len = qpMeta.qps.length; i < len; ++i) {
36441          var qp = qpMeta.qps[i];
36442          var route = qp.route;
36443          var controller = route.controller;
36444          var presentKey = qp.urlKey in params && qp.urlKey;
36445
36446          // Do a reverse lookup to see if the changed query
36447          // param URL key corresponds to a QP property on
36448          // this controller.
36449          var value, svalue;
36450          if (changes && qp.urlKey in changes) {
36451            // Value updated in/before setupController
36452            value = _emberMetalProperty_get.get(controller, qp.prop);
36453            svalue = route.serializeQueryParam(value, qp.urlKey, qp.type);
36454          } else {
36455            if (presentKey) {
36456              svalue = params[presentKey];
36457              value = route.deserializeQueryParam(svalue, qp.urlKey, qp.type);
36458            } else {
36459              // No QP provided; use default value.
36460              svalue = qp.serializedDefaultValue;
36461              value = copyDefaultValue(qp.defaultValue);
36462            }
36463          }
36464
36465          controller._qpDelegate = _emberMetalProperty_get.get(route, '_qp.states.inactive');
36466
36467          var thisQueryParamChanged = svalue !== qp.serializedValue;
36468          if (thisQueryParamChanged) {
36469            if (transition.queryParamsOnly && replaceUrl !== false) {
36470              var options = route._optionsForQueryParam(qp);
36471              var replaceConfigValue = _emberMetalProperty_get.get(options, 'replace');
36472              if (replaceConfigValue) {
36473                replaceUrl = true;
36474              } else if (replaceConfigValue === false) {
36475                // Explicit pushState wins over any other replaceStates.
36476                replaceUrl = false;
36477              }
36478            }
36479
36480            _emberMetalProperty_set.set(controller, qp.prop, value);
36481          }
36482
36483          // Stash current serialized value of controller.
36484          qp.serializedValue = svalue;
36485
36486          var thisQueryParamHasDefaultValue = qp.serializedDefaultValue === svalue;
36487          if (!thisQueryParamHasDefaultValue) {
36488            finalParams.push({
36489              value: svalue,
36490              visible: true,
36491              key: presentKey || qp.urlKey
36492            });
36493          }
36494        }
36495
36496        if (replaceUrl) {
36497          transition.method('replace');
36498        }
36499
36500        qpMeta.qps.forEach(function (qp) {
36501          var routeQpMeta = _emberMetalProperty_get.get(qp.route, '_qp');
36502          var finalizedController = qp.route.controller;
36503          finalizedController._qpDelegate = _emberMetalProperty_get.get(routeQpMeta, 'states.active');
36504        });
36505
36506        router._qpUpdates = null;
36507      }
36508    },
36509
36510    /**
36511      This hook is executed when the router completely exits this route. It is
36512      not executed when the model for the route changes.
36513       @method deactivate
36514      @public
36515    */
36516    deactivate: K,
36517
36518    /**
36519      This hook is executed when the router enters the route. It is not executed
36520      when the model for the route changes.
36521       @method activate
36522      @public
36523    */
36524    activate: K,
36525
36526    /**
36527      Transition the application into another route. The route may
36528      be either a single route or route path:
36529       ```javascript
36530      this.transitionTo('blogPosts');
36531      this.transitionTo('blogPosts.recentEntries');
36532      ```
36533       Optionally supply a model for the route in question. The model
36534      will be serialized into the URL using the `serialize` hook of
36535      the route:
36536       ```javascript
36537      this.transitionTo('blogPost', aPost);
36538      ```
36539       If a literal is passed (such as a number or a string), it will
36540      be treated as an identifier instead. In this case, the `model`
36541      hook of the route will be triggered:
36542       ```javascript
36543      this.transitionTo('blogPost', 1);
36544      ```
36545       Multiple models will be applied last to first recursively up the
36546      route tree.
36547       ```javascript
36548      App.Router.map(function() {
36549        this.route('blogPost', { path:':blogPostId' }, function() {
36550          this.route('blogComment', { path: ':blogCommentId', resetNamespace: true });
36551        });
36552      });
36553       this.transitionTo('blogComment', aPost, aComment);
36554      this.transitionTo('blogComment', 1, 13);
36555      ```
36556       It is also possible to pass a URL (a string that starts with a
36557      `/`). This is intended for testing and debugging purposes and
36558      should rarely be used in production code.
36559       ```javascript
36560      this.transitionTo('/');
36561      this.transitionTo('/blog/post/1/comment/13');
36562      this.transitionTo('/blog/posts?sort=title');
36563      ```
36564       An options hash with a `queryParams` property may be provided as
36565      the final argument to add query parameters to the destination URL.
36566       ```javascript
36567      this.transitionTo('blogPost', 1, {
36568        queryParams: {showComments: 'true'}
36569      });
36570       // if you just want to transition the query parameters without changing the route
36571      this.transitionTo({queryParams: {sort: 'date'}});
36572      ```
36573       See also [replaceWith](#method_replaceWith).
36574       Simple Transition Example
36575       ```javascript
36576      App.Router.map(function() {
36577        this.route('index');
36578        this.route('secret');
36579        this.route('fourOhFour', { path: '*:' });
36580      });
36581       App.IndexRoute = Ember.Route.extend({
36582        actions: {
36583          moveToSecret: function(context) {
36584            if (authorized()) {
36585              this.transitionTo('secret', context);
36586            } else {
36587              this.transitionTo('fourOhFour');
36588            }
36589          }
36590        }
36591      });
36592      ```
36593       Transition to a nested route
36594       ```javascript
36595      App.Router.map(function() {
36596        this.route('articles', { path: '/articles' }, function() {
36597          this.route('new');
36598        });
36599      });
36600       App.IndexRoute = Ember.Route.extend({
36601        actions: {
36602          transitionToNewArticle: function() {
36603            this.transitionTo('articles.new');
36604          }
36605        }
36606      });
36607      ```
36608       Multiple Models Example
36609       ```javascript
36610      App.Router.map(function() {
36611        this.route('index');
36612         this.route('breakfast', { path: ':breakfastId' }, function() {
36613          this.route('cereal', { path: ':cerealId', resetNamespace: true });
36614        });
36615      });
36616       App.IndexRoute = Ember.Route.extend({
36617        actions: {
36618          moveToChocolateCereal: function() {
36619            var cereal = { cerealId: 'ChocolateYumminess' };
36620            var breakfast = { breakfastId: 'CerealAndMilk' };
36621             this.transitionTo('cereal', breakfast, cereal);
36622          }
36623        }
36624      });
36625      ```
36626       Nested Route with Query String Example
36627       ```javascript
36628      App.Router.map(function() {
36629        this.route('fruits', function() {
36630          this.route('apples');
36631        });
36632      });
36633       App.IndexRoute = Ember.Route.extend({
36634        actions: {
36635          transitionToApples: function() {
36636            this.transitionTo('fruits.apples', {queryParams: {color: 'red'}});
36637          }
36638        }
36639      });
36640      ```
36641       @method transitionTo
36642      @param {String} name the name of the route or a URL
36643      @param {...Object} models the model(s) or identifier(s) to be used while
36644        transitioning to the route.
36645      @param {Object} [options] optional hash with a queryParams property
36646        containing a mapping of query parameters
36647      @return {Transition} the transition object associated with this
36648        attempted transition
36649      @public
36650    */
36651    transitionTo: function (name, context) {
36652      var router = this.router;
36653      return router.transitionTo.apply(router, arguments);
36654    },
36655
36656    /**
36657      Perform a synchronous transition into another route without attempting
36658      to resolve promises, update the URL, or abort any currently active
36659      asynchronous transitions (i.e. regular transitions caused by
36660      `transitionTo` or URL changes).
36661       This method is handy for performing intermediate transitions on the
36662      way to a final destination route, and is called internally by the
36663      default implementations of the `error` and `loading` handlers.
36664       @method intermediateTransitionTo
36665      @param {String} name the name of the route
36666      @param {...Object} models the model(s) to be used while transitioning
36667      to the route.
36668      @since 1.2.0
36669      @public
36670     */
36671    intermediateTransitionTo: function () {
36672      var router = this.router;
36673      router.intermediateTransitionTo.apply(router, arguments);
36674    },
36675
36676    /**
36677      Refresh the model on this route and any child routes, firing the
36678      `beforeModel`, `model`, and `afterModel` hooks in a similar fashion
36679      to how routes are entered when transitioning in from other route.
36680      The current route params (e.g. `article_id`) will be passed in
36681      to the respective model hooks, and if a different model is returned,
36682      `setupController` and associated route hooks will re-fire as well.
36683       An example usage of this method is re-querying the server for the
36684      latest information using the same parameters as when the route
36685      was first entered.
36686       Note that this will cause `model` hooks to fire even on routes
36687      that were provided a model object when the route was initially
36688      entered.
36689       @method refresh
36690      @return {Transition} the transition object associated with this
36691        attempted transition
36692      @since 1.4.0
36693      @public
36694     */
36695    refresh: function () {
36696      return this.router.router.refresh(this);
36697    },
36698
36699    /**
36700      Transition into another route while replacing the current URL, if possible.
36701      This will replace the current history entry instead of adding a new one.
36702      Beside that, it is identical to `transitionTo` in all other respects. See
36703      'transitionTo' for additional information regarding multiple models.
36704       Example
36705       ```javascript
36706      App.Router.map(function() {
36707        this.route('index');
36708        this.route('secret');
36709      });
36710       App.SecretRoute = Ember.Route.extend({
36711        afterModel: function() {
36712          if (!authorized()){
36713            this.replaceWith('index');
36714          }
36715        }
36716      });
36717      ```
36718       @method replaceWith
36719      @param {String} name the name of the route or a URL
36720      @param {...Object} models the model(s) or identifier(s) to be used while
36721        transitioning to the route.
36722      @return {Transition} the transition object associated with this
36723        attempted transition
36724      @public
36725    */
36726    replaceWith: function () {
36727      var router = this.router;
36728      return router.replaceWith.apply(router, arguments);
36729    },
36730
36731    /**
36732      Sends an action to the router, which will delegate it to the currently
36733      active route hierarchy per the bubbling rules explained under `actions`.
36734       Example
36735       ```javascript
36736      App.Router.map(function() {
36737        this.route('index');
36738      });
36739       App.ApplicationRoute = Ember.Route.extend({
36740        actions: {
36741          track: function(arg) {
36742            console.log(arg, 'was clicked');
36743          }
36744        }
36745      });
36746       App.IndexRoute = Ember.Route.extend({
36747        actions: {
36748          trackIfDebug: function(arg) {
36749            if (debug) {
36750              this.send('track', arg);
36751            }
36752          }
36753        }
36754      });
36755      ```
36756       @method send
36757      @param {String} name the name of the action to trigger
36758      @param {...*} args
36759      @public
36760    */
36761    send: function () {
36762      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
36763        args[_key] = arguments[_key];
36764      }
36765
36766      if (this.router && this.router.router || !_emberMetalCore.default.testing) {
36767        var _router;
36768
36769        (_router = this.router).send.apply(_router, args);
36770      } else {
36771        var name = args[0];
36772        args = slice.call(args, 1);
36773        var action = this.actions[name];
36774        if (action) {
36775          return this.actions[name].apply(this, args);
36776        }
36777      }
36778    },
36779
36780    /**
36781      This hook is the entry point for router.js
36782       @private
36783      @method setup
36784    */
36785    setup: function (context, transition) {
36786      var controller;
36787
36788      var controllerName = this.controllerName || this.routeName;
36789      var definedController = this.controllerFor(controllerName, true);
36790
36791      if (!definedController) {
36792        controller = this.generateController(controllerName, context);
36793      } else {
36794        controller = definedController;
36795      }
36796
36797      // Assign the route's controller so that it can more easily be
36798      // referenced in action handlers. Side effects. Side effects everywhere.
36799      if (!this.controller) {
36800        var propNames = _emberMetalProperty_get.get(this, '_qp.propertyNames');
36801        addQueryParamsObservers(controller, propNames);
36802        this.controller = controller;
36803      }
36804
36805      var queryParams = _emberMetalProperty_get.get(this, '_qp');
36806
36807      var states = queryParams.states;
36808      if (transition) {
36809        // Update the model dep values used to calculate cache keys.
36810        _emberRoutingUtils.stashParamNames(this.router, transition.state.handlerInfos);
36811
36812        var params = transition.params;
36813        var allParams = queryParams.propertyNames;
36814        var cache = this._bucketCache;
36815
36816        allParams.forEach(function (prop) {
36817          var aQp = queryParams.map[prop];
36818
36819          aQp.values = params;
36820          var cacheKey = _emberRoutingUtils.calculateCacheKey(aQp.prefix, aQp.parts, aQp.values);
36821
36822          if (cache) {
36823            var value = cache.lookup(cacheKey, prop, aQp.undecoratedDefaultValue);
36824            _emberMetalProperty_set.set(controller, prop, value);
36825          }
36826        });
36827      }
36828
36829      controller._qpDelegate = states.allowOverrides;
36830
36831      if (transition) {
36832        var qpValues = getQueryParamsFor(this, transition.state);
36833        controller.setProperties(qpValues);
36834      }
36835
36836      this.setupController(controller, context, transition);
36837
36838      if (!this._environment || this._environment.options.shouldRender) {
36839        this.renderTemplate(controller, context);
36840      }
36841    },
36842
36843    /*
36844      Called when a query parameter for this route changes, regardless of whether the route
36845      is currently part of the active route hierarchy. This will update the query parameter's
36846      value in the cache so if this route becomes active, the cache value has been updated.
36847    */
36848    _qpChanged: function (prop, value, qp) {
36849      if (!qp) {
36850        return;
36851      }
36852
36853      var cacheKey = _emberRoutingUtils.calculateCacheKey(qp.prefix || '', qp.parts, qp.values);
36854
36855      // Update model-dep cache
36856      var cache = this._bucketCache;
36857      if (cache) {
36858        cache.stash(cacheKey, prop, value);
36859      }
36860    },
36861    /**
36862      This hook is the first of the route entry validation hooks
36863      called when an attempt is made to transition into a route
36864      or one of its children. It is called before `model` and
36865      `afterModel`, and is appropriate for cases when:
36866       1) A decision can be made to redirect elsewhere without
36867         needing to resolve the model first.
36868      2) Any async operations need to occur first before the
36869         model is attempted to be resolved.
36870       This hook is provided the current `transition` attempt
36871      as a parameter, which can be used to `.abort()` the transition,
36872      save it for a later `.retry()`, or retrieve values set
36873      on it from a previous hook. You can also just call
36874      `this.transitionTo` to another route to implicitly
36875      abort the `transition`.
36876       You can return a promise from this hook to pause the
36877      transition until the promise resolves (or rejects). This could
36878      be useful, for instance, for retrieving async code from
36879      the server that is required to enter a route.
36880       ```javascript
36881      App.PostRoute = Ember.Route.extend({
36882        beforeModel: function(transition) {
36883          if (!App.Post) {
36884            return Ember.$.getScript('/models/post.js');
36885          }
36886        }
36887      });
36888      ```
36889       If `App.Post` doesn't exist in the above example,
36890      `beforeModel` will use jQuery's `getScript`, which
36891      returns a promise that resolves after the server has
36892      successfully retrieved and executed the code from the
36893      server. Note that if an error were to occur, it would
36894      be passed to the `error` hook on `Ember.Route`, but
36895      it's also possible to handle errors specific to
36896      `beforeModel` right from within the hook (to distinguish
36897      from the shared error handling behavior of the `error`
36898      hook):
36899       ```javascript
36900      App.PostRoute = Ember.Route.extend({
36901        beforeModel: function(transition) {
36902          if (!App.Post) {
36903            var self = this;
36904            return Ember.$.getScript('post.js').then(null, function(e) {
36905              self.transitionTo('help');
36906               // Note that the above transitionTo will implicitly
36907              // halt the transition. If you were to return
36908              // nothing from this promise reject handler,
36909              // according to promise semantics, that would
36910              // convert the reject into a resolve and the
36911              // transition would continue. To propagate the
36912              // error so that it'd be handled by the `error`
36913              // hook, you would have to
36914              return Ember.RSVP.reject(e);
36915            });
36916          }
36917        }
36918      });
36919      ```
36920       @method beforeModel
36921      @param {Transition} transition
36922      @return {Promise} if the value returned from this hook is
36923        a promise, the transition will pause until the transition
36924        resolves. Otherwise, non-promise return values are not
36925        utilized in any way.
36926      @public
36927    */
36928    beforeModel: K,
36929
36930    /**
36931      This hook is called after this route's model has resolved.
36932      It follows identical async/promise semantics to `beforeModel`
36933      but is provided the route's resolved model in addition to
36934      the `transition`, and is therefore suited to performing
36935      logic that can only take place after the model has already
36936      resolved.
36937       ```javascript
36938      App.PostsRoute = Ember.Route.extend({
36939        afterModel: function(posts, transition) {
36940          if (posts.get('length') === 1) {
36941            this.transitionTo('post.show', posts.get('firstObject'));
36942          }
36943        }
36944      });
36945      ```
36946       Refer to documentation for `beforeModel` for a description
36947      of transition-pausing semantics when a promise is returned
36948      from this hook.
36949       @method afterModel
36950      @param {Object} resolvedModel the value returned from `model`,
36951        or its resolved value if it was a promise
36952      @param {Transition} transition
36953      @return {Promise} if the value returned from this hook is
36954        a promise, the transition will pause until the transition
36955        resolves. Otherwise, non-promise return values are not
36956        utilized in any way.
36957      @public
36958     */
36959    afterModel: K,
36960
36961    /**
36962      A hook you can implement to optionally redirect to another route.
36963       If you call `this.transitionTo` from inside of this hook, this route
36964      will not be entered in favor of the other hook.
36965       `redirect` and `afterModel` behave very similarly and are
36966      called almost at the same time, but they have an important
36967      distinction in the case that, from one of these hooks, a
36968      redirect into a child route of this route occurs: redirects
36969      from `afterModel` essentially invalidate the current attempt
36970      to enter this route, and will result in this route's `beforeModel`,
36971      `model`, and `afterModel` hooks being fired again within
36972      the new, redirecting transition. Redirects that occur within
36973      the `redirect` hook, on the other hand, will _not_ cause
36974      these hooks to be fired again the second time around; in
36975      other words, by the time the `redirect` hook has been called,
36976      both the resolved model and attempted entry into this route
36977      are considered to be fully validated.
36978       @method redirect
36979      @param {Object} model the model for this route
36980      @param {Transition} transition the transition object associated with the current transition
36981      @public
36982    */
36983    redirect: K,
36984
36985    /**
36986      Called when the context is changed by router.js.
36987       @private
36988      @method contextDidChange
36989    */
36990    contextDidChange: function () {
36991      this.currentModel = this.context;
36992    },
36993
36994    /**
36995      A hook you can implement to convert the URL into the model for
36996      this route.
36997       ```javascript
36998      App.Router.map(function() {
36999        this.route('post', { path: '/posts/:post_id' });
37000      });
37001      ```
37002       The model for the `post` route is `store.findRecord('post', params.post_id)`.
37003       By default, if your route has a dynamic segment ending in `_id`:
37004       * The model class is determined from the segment (`post_id`'s
37005        class is `App.Post`)
37006      * The find method is called on the model class with the value of
37007        the dynamic segment.
37008       Note that for routes with dynamic segments, this hook is not always
37009      executed. If the route is entered through a transition (e.g. when
37010      using the `link-to` Handlebars helper or the `transitionTo` method
37011      of routes), and a model context is already provided this hook
37012      is not called.
37013       A model context does not include a primitive string or number,
37014      which does cause the model hook to be called.
37015       Routes without dynamic segments will always execute the model hook.
37016       ```javascript
37017      // no dynamic segment, model hook always called
37018      this.transitionTo('posts');
37019       // model passed in, so model hook not called
37020      thePost = store.findRecord('post', 1);
37021      this.transitionTo('post', thePost);
37022       // integer passed in, model hook is called
37023      this.transitionTo('post', 1);
37024       // model id passed in, model hook is called
37025      // useful for forcing the hook to execute
37026      thePost = store.findRecord('post', 1);
37027      this.transitionTo('post', thePost.id);
37028      ```
37029        This hook follows the asynchronous/promise semantics
37030      described in the documentation for `beforeModel`. In particular,
37031      if a promise returned from `model` fails, the error will be
37032      handled by the `error` hook on `Ember.Route`.
37033       Example
37034       ```javascript
37035      App.PostRoute = Ember.Route.extend({
37036        model: function(params) {
37037          return this.store.findRecord('post', params.post_id);
37038        }
37039      });
37040      ```
37041       @method model
37042      @param {Object} params the parameters extracted from the URL
37043      @param {Transition} transition
37044      @return {Object|Promise} the model for this route. If
37045        a promise is returned, the transition will pause until
37046        the promise resolves, and the resolved value of the promise
37047        will be used as the model for this route.
37048      @public
37049    */
37050    model: function (params, transition) {
37051      var match, name, sawParams, value;
37052      var queryParams = _emberMetalProperty_get.get(this, '_qp.map');
37053
37054      for (var prop in params) {
37055        if (prop === 'queryParams' || queryParams && prop in queryParams) {
37056          continue;
37057        }
37058
37059        if (match = prop.match(/^(.*)_id$/)) {
37060          name = match[1];
37061          value = params[prop];
37062        }
37063        sawParams = true;
37064      }
37065
37066      if (!name && sawParams) {
37067        return _emberRuntimeCopy.default(params);
37068      } else if (!name) {
37069        if (transition.resolveIndex < 1) {
37070          return;
37071        }
37072
37073        var parentModel = transition.state.handlerInfos[transition.resolveIndex - 1].context;
37074
37075        return parentModel;
37076      }
37077
37078      return this.findModel(name, value);
37079    },
37080
37081    /**
37082      @private
37083      @method deserialize
37084      @param {Object} params the parameters extracted from the URL
37085      @param {Transition} transition
37086      @return {Object|Promise} the model for this route.
37087       Router.js hook.
37088     */
37089    deserialize: function (params, transition) {
37090      return this.model(this.paramsFor(this.routeName), transition);
37091    },
37092
37093    /**
37094       @method findModel
37095      @param {String} type the model type
37096      @param {Object} value the value passed to find
37097      @private
37098    */
37099    findModel: function () {
37100      var store = _emberMetalProperty_get.get(this, 'store');
37101      return store.find.apply(store, arguments);
37102    },
37103
37104    /**
37105      Store property provides a hook for data persistence libraries to inject themselves.
37106       By default, this store property provides the exact same functionality previously
37107      in the model hook.
37108       Currently, the required interface is:
37109       `store.find(modelName, findArguments)`
37110       @method store
37111      @param {Object} store
37112      @private
37113    */
37114    store: _emberMetalComputed.computed(function () {
37115      var owner = _containerOwner.getOwner(this);
37116      var routeName = this.routeName;
37117      var namespace = _emberMetalProperty_get.get(this, 'router.namespace');
37118
37119      return {
37120        find: function (name, value) {
37121          var modelClass = owner._lookupFactory('model:' + name);
37122
37123          _emberMetalDebug.assert('You used the dynamic segment ' + name + '_id in your route ' + routeName + ', but ' + namespace + '.' + _emberRuntimeSystemString.classify(name) + ' did not exist and you did not override your route\'s `model` hook.', !!modelClass);
37124
37125          if (!modelClass) {
37126            return;
37127          }
37128
37129          _emberMetalDebug.assert(_emberRuntimeSystemString.classify(name) + ' has no method `find`.', typeof modelClass.find === 'function');
37130
37131          return modelClass.find(value);
37132        }
37133      };
37134    }),
37135
37136    /**
37137      A hook you can implement to convert the route's model into parameters
37138      for the URL.
37139       ```javascript
37140      App.Router.map(function() {
37141        this.route('post', { path: '/posts/:post_id' });
37142      });
37143       App.PostRoute = Ember.Route.extend({
37144        model: function(params) {
37145          // the server returns `{ id: 12 }`
37146          return Ember.$.getJSON('/posts/' + params.post_id);
37147        },
37148         serialize: function(model) {
37149          // this will make the URL `/posts/12`
37150          return { post_id: model.id };
37151        }
37152      });
37153      ```
37154       The default `serialize` method will insert the model's `id` into the
37155      route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'.
37156      If the route has multiple dynamic segments or does not contain '_id', `serialize`
37157      will return `Ember.getProperties(model, params)`
37158       This method is called when `transitionTo` is called with a context
37159      in order to populate the URL.
37160       @method serialize
37161      @param {Object} model the routes model
37162      @param {Array} params an Array of parameter names for the current
37163        route (in the example, `['post_id']`.
37164      @return {Object} the serialized parameters
37165      @public
37166    */
37167    serialize: function (model, params) {
37168      if (params.length < 1) {
37169        return;
37170      }
37171      if (!model) {
37172        return;
37173      }
37174
37175      var name = params[0];
37176      var object = {};
37177
37178      if (params.length === 1) {
37179        if (name in model) {
37180          object[name] = _emberMetalProperty_get.get(model, name);
37181        } else if (/_id$/.test(name)) {
37182          object[name] = _emberMetalProperty_get.get(model, 'id');
37183        }
37184      } else {
37185        object = _emberMetalGet_properties.default(model, params);
37186      }
37187
37188      return object;
37189    },
37190
37191    /**
37192      A hook you can use to setup the controller for the current route.
37193       This method is called with the controller for the current route and the
37194      model supplied by the `model` hook.
37195       By default, the `setupController` hook sets the `model` property of
37196      the controller to the `model`.
37197       If you implement the `setupController` hook in your Route, it will
37198      prevent this default behavior. If you want to preserve that behavior
37199      when implementing your `setupController` function, make sure to call
37200      `_super`:
37201       ```javascript
37202      App.PhotosRoute = Ember.Route.extend({
37203        model: function() {
37204          return this.store.findAll('photo');
37205        },
37206         setupController: function(controller, model) {
37207          // Call _super for default behavior
37208          this._super(controller, model);
37209          // Implement your custom setup after
37210          this.controllerFor('application').set('showingPhotos', true);
37211        }
37212      });
37213      ```
37214       The provided controller will be one resolved based on the name
37215      of this route.
37216       If no explicit controller is defined, Ember will automatically create one.
37217       As an example, consider the router:
37218       ```javascript
37219      App.Router.map(function() {
37220        this.route('post', { path: '/posts/:post_id' });
37221      });
37222      ```
37223       For the `post` route, a controller named `App.PostController` would
37224      be used if it is defined. If it is not defined, a basic `Ember.Controller`
37225      instance would be used.
37226       Example
37227       ```javascript
37228      App.PostRoute = Ember.Route.extend({
37229        setupController: function(controller, model) {
37230          controller.set('model', model);
37231        }
37232      });
37233      ```
37234       @method setupController
37235      @param {Controller} controller instance
37236      @param {Object} model
37237      @public
37238    */
37239    setupController: function (controller, context, transition) {
37240      if (controller && context !== undefined) {
37241        _emberMetalProperty_set.set(controller, 'model', context);
37242      }
37243    },
37244
37245    /**
37246      Returns the controller for a particular route or name.
37247       The controller instance must already have been created, either through entering the
37248      associated route or using `generateController`.
37249       ```javascript
37250      App.PostRoute = Ember.Route.extend({
37251        setupController: function(controller, post) {
37252          this._super(controller, post);
37253          this.controllerFor('posts').set('currentPost', post);
37254        }
37255      });
37256      ```
37257       @method controllerFor
37258      @param {String} name the name of the route or controller
37259      @return {Ember.Controller}
37260      @public
37261    */
37262    controllerFor: function (name, _skipAssert) {
37263      var owner = _containerOwner.getOwner(this);
37264      var route = owner.lookup('route:' + name);
37265      var controller;
37266
37267      if (route && route.controllerName) {
37268        name = route.controllerName;
37269      }
37270
37271      controller = owner.lookup('controller:' + name);
37272
37273      // NOTE: We're specifically checking that skipAssert is true, because according
37274      //   to the old API the second parameter was model. We do not want people who
37275      //   passed a model to skip the assertion.
37276      _emberMetalDebug.assert('The controller named \'' + name + '\' could not be found. Make sure that this route exists and has already been entered at least once. If you are accessing a controller not associated with a route, make sure the controller class is explicitly defined.', controller || _skipAssert === true);
37277
37278      return controller;
37279    },
37280
37281    /**
37282      Generates a controller for a route.
37283       Example
37284       ```javascript
37285      App.PostRoute = Ember.Route.extend({
37286        setupController: function(controller, post) {
37287          this._super(controller, post);
37288          this.generateController('posts', post);
37289        }
37290      });
37291      ```
37292       @method generateController
37293      @param {String} name the name of the controller
37294      @param {Object} model the model to infer the type of the controller (optional)
37295      @private
37296    */
37297    generateController: function (name, model) {
37298      var owner = _containerOwner.getOwner(this);
37299
37300      model = model || this.modelFor(name);
37301
37302      return _emberRoutingSystemGenerate_controller.default(owner, name, model);
37303    },
37304
37305    /**
37306      Returns the resolved model of a parent (or any ancestor) route
37307      in a route hierarchy.  During a transition, all routes
37308      must resolve a model object, and if a route
37309      needs access to a parent route's model in order to
37310      resolve a model (or just reuse the model from a parent),
37311      it can call `this.modelFor(theNameOfParentRoute)` to
37312      retrieve it. If the ancestor route's model was a promise,
37313      its resolved result is returned.
37314       Example
37315       ```javascript
37316      App.Router.map(function() {
37317          this.route('post', { path: '/post/:post_id' }, function() {
37318            this.route('comments', { resetNamespace: true });
37319          });
37320      });
37321       App.CommentsRoute = Ember.Route.extend({
37322          afterModel: function() {
37323            this.set('post', this.modelFor('post'));
37324          }
37325      });
37326      ```
37327       @method modelFor
37328      @param {String} name the name of the route
37329      @return {Object} the model object
37330      @public
37331    */
37332    modelFor: function (name) {
37333      var route = _containerOwner.getOwner(this).lookup('route:' + name);
37334      var transition = this.router ? this.router.router.activeTransition : null;
37335
37336      // If we are mid-transition, we want to try and look up
37337      // resolved parent contexts on the current transitionEvent.
37338      if (transition) {
37339        var modelLookupName = route && route.routeName || name;
37340        if (transition.resolvedModels.hasOwnProperty(modelLookupName)) {
37341          return transition.resolvedModels[modelLookupName];
37342        }
37343      }
37344
37345      return route && route.currentModel;
37346    },
37347
37348    /**
37349      A hook you can use to render the template for the current route.
37350       This method is called with the controller for the current route and the
37351      model supplied by the `model` hook. By default, it renders the route's
37352      template, configured with the controller for the route.
37353       This method can be overridden to set up and render additional or
37354      alternative templates.
37355       ```javascript
37356      App.PostsRoute = Ember.Route.extend({
37357        renderTemplate: function(controller, model) {
37358          var favController = this.controllerFor('favoritePost');
37359           // Render the `favoritePost` template into
37360          // the outlet `posts`, and display the `favoritePost`
37361          // controller.
37362          this.render('favoritePost', {
37363            outlet: 'posts',
37364            controller: favController
37365          });
37366        }
37367      });
37368      ```
37369       @method renderTemplate
37370      @param {Object} controller the route's controller
37371      @param {Object} model the route's model
37372      @public
37373    */
37374    renderTemplate: function (controller, model) {
37375      this.render();
37376    },
37377
37378    /**
37379      `render` is used to render a template into a region of another template
37380      (indicated by an `{{outlet}}`). `render` is used both during the entry
37381      phase of routing (via the `renderTemplate` hook) and later in response to
37382      user interaction.
37383       For example, given the following minimal router and templates:
37384       ```javascript
37385      Router.map(function() {
37386        this.route('photos');
37387      });
37388      ```
37389       ```handlebars
37390      <!-- application.hbs -->
37391      <div class='something-in-the-app-hbs'>
37392        {{outlet "anOutletName"}}
37392
37393      </div>
37394      ```
37395       ```handlebars
37396      <!-- photos.hbs -->
37397      <h1>Photos</h1>
37398      ```
37399       You can render `photos.hbs` into the `"anOutletName"` outlet of
37400      `application.hbs` by calling `render`:
37401       ```javascript
37402      // posts route
37403      Ember.Route.extend({
37404        renderTemplate: function() {
37405          this.render('photos', {
37406            into: 'application',
37407            outlet: 'anOutletName'
37408          })
37409        }
37410      });
37411      ```
37412       `render` additionally allows you to supply which `view`, `controller`, and
37413      `model` objects should be loaded and associated with the rendered template.
37414        ```javascript
37415      // posts route
37416      Ember.Route.extend({
37417        renderTemplate: function(controller, model){
37418          this.render('posts', {    // the template to render, referenced by name
37419            into: 'application',    // the template to render into, referenced by name
37420            outlet: 'anOutletName', // the outlet inside `options.template` to render into.
37421            view: 'aViewName',      // the view to use for this template, referenced by name
37422            controller: 'someControllerName', // the controller to use for this template, referenced by name
37423            model: model            // the model to set on `options.controller`.
37424          })
37425        }
37426      });
37427      ```
37428       The string values provided for the template name, view, and controller
37429      will eventually pass through to the resolver for lookup. See
37430      Ember.Resolver for how these are mapped to JavaScript objects in your
37431      application.
37432       Not all options need to be passed to `render`. Default values will be used
37433      based on the name of the route specified in the router or the Route's
37434      `controllerName`, `viewName` and `templateName` properties.
37435       For example:
37436       ```javascript
37437      // router
37438      Router.map(function() {
37439        this.route('index');
37440        this.route('post', { path: '/posts/:post_id' });
37441      });
37442      ```
37443       ```javascript
37444      // post route
37445      PostRoute = App.Route.extend({
37446        renderTemplate: function() {
37447          this.render(); // all defaults apply
37448        }
37449      });
37450      ```
37451       The name of the `PostRoute`, defined by the router, is `post`.
37452       The following equivalent default options will be applied when
37453      the Route calls `render`:
37454       ```javascript
37455      //
37456      this.render('post', {  // the template name associated with 'post' Route
37457        into: 'application', // the parent route to 'post' Route
37458        outlet: 'main',      // {{outlet}} and {{outlet 'main'}} are synonymous,
37459        view: 'post',        // the view associated with the 'post' Route
37460        controller: 'post',  // the controller associated with the 'post' Route
37461      })
37462      ```
37463       By default the controller's `model` will be the route's model, so it does not
37464      need to be passed unless you wish to change which model is being used.
37465       @method render
37466      @param {String} name the name of the template to render
37467      @param {Object} [options] the options
37468      @param {String} [options.into] the template to render into,
37469                      referenced by name. Defaults to the parent template
37470      @param {String} [options.outlet] the outlet inside `options.template` to render into.
37471                      Defaults to 'main'
37472      @param {String|Object} [options.controller] the controller to use for this template,
37473                      referenced by name or as a controller instance. Defaults to the Route's paired controller
37474      @param {Object} [options.model] the model object to set on `options.controller`.
37475                      Defaults to the return value of the Route's model hook
37476      @public
37477    */
37478    render: function (_name, options) {
37479      _emberMetalDebug.assert('The name in the given arguments is undefined', arguments.length > 0 ? !_emberMetalIs_none.default(arguments[0]) : true);
37480
37481      var namePassed = typeof _name === 'string' && !!_name;
37482      var isDefaultRender = arguments.length === 0 || _emberMetalIs_empty.default(arguments[0]);
37483      var name;
37484
37485      if (typeof _name === 'object' && !options) {
37486        name = this.routeName;
37487        options = _name;
37488      } else {
37489        name = _name;
37490      }
37491
37492      var renderOptions = buildRenderOptions(this, namePassed, isDefaultRender, name, options);
37493      this.connections.push(renderOptions);
37494      _emberMetalRun_loop.default.once(this.router, '_setOutlets');
37495    },
37496
37497    /**
37498      Disconnects a view that has been rendered into an outlet.
37499       You may pass any or all of the following options to `disconnectOutlet`:
37500       * `outlet`: the name of the outlet to clear (default: 'main')
37501      * `parentView`: the name of the view containing the outlet to clear
37502         (default: the view rendered by the parent route)
37503       Example:
37504       ```javascript
37505      App.ApplicationRoute = App.Route.extend({
37506        actions: {
37507          showModal: function(evt) {
37508            this.render(evt.modalName, {
37509              outlet: 'modal',
37510              into: 'application'
37511            });
37512          },
37513          hideModal: function(evt) {
37514            this.disconnectOutlet({
37515              outlet: 'modal',
37516              parentView: 'application'
37517            });
37518          }
37519        }
37520      });
37521      ```
37522       Alternatively, you can pass the `outlet` name directly as a string.
37523       Example:
37524       ```javascript
37525      hideModal: function(evt) {
37526        this.disconnectOutlet('modal');
37527      }
37528      ```
37529       @method disconnectOutlet
37530      @param {Object|String} options the options hash or outlet name
37531      @public
37532    */
37533    disconnectOutlet: function (options) {
37534      var outletName;
37535      var parentView;
37536      if (!options || typeof options === 'string') {
37537        outletName = options;
37538      } else {
37539        outletName = options.outlet;
37540        parentView = options.parentView;
37541
37542        if (options && Object.keys(options).indexOf('outlet') !== -1 && typeof options.outlet === 'undefined') {
37543          throw new _emberMetalError.default('You passed undefined as the outlet name.');
37544        }
37545      }
37546      parentView = parentView && parentView.replace(/\//g, '.');
37547      outletName = outletName || 'main';
37548      this._disconnectOutlet(outletName, parentView);
37549      for (var i = 0; i < this.router.router.currentHandlerInfos.length; i++) {
37550        // This non-local state munging is sadly necessary to maintain
37551        // backward compatibility with our existing semantics, which allow
37552        // any route to disconnectOutlet things originally rendered by any
37553        // other route. This should all get cut in 2.0.
37554        this.router.router.currentHandlerInfos[i].handler._disconnectOutlet(outletName, parentView);
37555      }
37556    },
37557
37558    _disconnectOutlet: function (outletName, parentView) {
37559      var parent = parentRoute(this);
37560      if (parent && parentView === parent.routeName) {
37561        parentView = undefined;
37562      }
37563      for (var i = 0; i < this.connections.length; i++) {
37564        var connection = this.connections[i];
37565        if (connection.outlet === outletName && connection.into === parentView) {
37566          // This neuters the disconnected outlet such that it doesn't
37567          // render anything, but it leaves an entry in the outlet
37568          // hierarchy so that any existing other renders that target it
37569          // don't suddenly blow up. They will still stick themselves
37570          // into its outlets, which won't render anywhere. All of this
37571          // statefulness should get the machete in 2.0.
37572          this.connections[i] = {
37573            into: connection.into,
37574            outlet: connection.outlet,
37575            name: connection.name
37576          };
37577          _emberMetalRun_loop.default.once(this.router, '_setOutlets');
37578        }
37579      }
37580    },
37581
37582    willDestroy: function () {
37583      this.teardownViews();
37584    },
37585
37586    /**
37587      @private
37588       @method teardownViews
37589    */
37590    teardownViews: function () {
37591      if (this.connections && this.connections.length > 0) {
37592        this.connections = [];
37593        _emberMetalRun_loop.default.once(this.router, '_setOutlets');
37594      }
37595    }
37596  });
37597
37598  _emberRuntimeMixinsAction_handler.deprecateUnderscoreActions(Route);
37599
37600  Route.reopenClass({
37601    isRouteFactory: true
37602  });
37603
37604  function parentRoute(route) {
37605    var handlerInfo = handlerInfoFor(route, route.router.router.state.handlerInfos, -1);
37606    return handlerInfo && handlerInfo.handler;
37607  }
37608
37609  function handlerInfoFor(route, handlerInfos, _offset) {
37610    if (!handlerInfos) {
37611      return;
37612    }
37613
37614    var offset = _offset || 0;
37615    var current;
37616    for (var i = 0, l = handlerInfos.length; i < l; i++) {
37617      current = handlerInfos[i].handler;
37618      if (current === route) {
37619        return handlerInfos[i + offset];
37620      }
37621    }
37622  }
37623
37624  function buildRenderOptions(route, namePassed, isDefaultRender, name, options) {
37625    var controller = options && options.controller;
37626    var templateName;
37627    var viewName;
37628    var ViewClass;
37629    var template;
37630    var LOG_VIEW_LOOKUPS = _emberMetalProperty_get.get(route.router, 'namespace.LOG_VIEW_LOOKUPS');
37631    var into = options && options.into && options.into.replace(/\//g, '.');
37632    var outlet = options && options.outlet || 'main';
37633    var owner = _containerOwner.getOwner(route);
37634
37635    if (name) {
37636      name = name.replace(/\//g, '.');
37637      templateName = name;
37638    } else {
37639      name = route.routeName;
37640      templateName = route.templateName || name;
37641    }
37642
37643    if (!controller) {
37644      if (namePassed) {
37645        controller = owner.lookup('controller:' + name) || route.controllerName || route.routeName;
37646      } else {
37647        controller = route.controllerName || owner.lookup('controller:' + name);
37648      }
37649    }
37650
37651    if (typeof controller === 'string') {
37652      var controllerName = controller;
37653      controller = owner.lookup('controller:' + controllerName);
37654      if (!controller) {
37655        throw new _emberMetalError.default('You passed `controller: \'' + controllerName + '\'` into the `render` method, but no such controller could be found.');
37656      }
37657    }
37658
37659    if (options && Object.keys(options).indexOf('outlet') !== -1 && typeof options.outlet === 'undefined') {
37660      throw new _emberMetalError.default('You passed undefined as the outlet name.');
37661    }
37662
37663    if (options && options.model) {
37664      controller.set('model', options.model);
37665    }
37666
37667    viewName = options && options.view || namePassed && name || route.viewName || name;
37668    ViewClass = owner._lookupFactory('view:' + viewName);
37669    template = owner.lookup('template:' + templateName);
37670
37671    var parent;
37672    if (into && (parent = parentRoute(route)) && into === parentRoute(route).routeName) {
37673      into = undefined;
37674    }
37675
37676    var renderOptions = {
37677      owner: owner,
37678      into: into,
37679      outlet: outlet,
37680      name: name,
37681      controller: controller,
37682      ViewClass: ViewClass,
37683      template: template
37684    };
37685
37686    var Component = undefined;
37687
37688    if (!ViewClass && !template && !Component) {
37689      _emberMetalDebug.assert('Could not find "' + name + '" template, view, or component.', isDefaultRender);
37690      if (LOG_VIEW_LOOKUPS) {
37691        var fullName = 'template:' + name;
37692        _emberMetalDebug.info('Could not find "' + name + '" template or view. Nothing will be rendered', { fullName: fullName });
37693      }
37694    }
37695
37696    return renderOptions;
37697  }
37698
37699  function getFullQueryParams(router, state) {
37700    if (state.fullQueryParams) {
37701      return state.fullQueryParams;
37702    }
37703
37704    state.fullQueryParams = {};
37705    _emberMetalAssign.default(state.fullQueryParams, state.queryParams);
37706
37707    var targetRouteName = state.handlerInfos[state.handlerInfos.length - 1].name;
37708    router._deserializeQueryParams(targetRouteName, state.fullQueryParams);
37709    return state.fullQueryParams;
37710  }
37711
37712  function getQueryParamsFor(route, state) {
37713    state.queryParamsFor = state.queryParamsFor || {};
37714    var name = route.routeName;
37715
37716    if (state.queryParamsFor[name]) {
37717      return state.queryParamsFor[name];
37718    }
37719
37720    var fullQueryParams = getFullQueryParams(route.router, state);
37721
37722    var params = state.queryParamsFor[name] = {};
37723
37724    // Copy over all the query params for this route/controller into params hash.
37725    var qpMeta = _emberMetalProperty_get.get(route, '_qp');
37726    var qps = qpMeta.qps;
37727    for (var i = 0, len = qps.length; i < len; ++i) {
37728      // Put deserialized qp on params hash.
37729      var qp = qps[i];
37730
37731      var qpValueWasPassedIn = (qp.prop in fullQueryParams);
37732      params[qp.prop] = qpValueWasPassedIn ? fullQueryParams[qp.prop] : copyDefaultValue(qp.defaultValue);
37733    }
37734
37735    return params;
37736  }
37737
37738  function copyDefaultValue(value) {
37739    if (Array.isArray(value)) {
37740      return _emberRuntimeSystemNative_array.A(value.slice());
37741    }
37742    return value;
37743  }
37744
37745  /*
37746    Merges all query parameters from a controller with those from
37747    a route, returning a new object and avoiding any mutations to
37748    the existing objects.
37749  */
37750  function mergeEachQueryParams(controllerQP, routeQP) {
37751    var keysAlreadyMergedOrSkippable;
37752    var qps = {};
37753
37754    keysAlreadyMergedOrSkippable = {
37755      defaultValue: true,
37756      type: true,
37757      scope: true,
37758      as: true
37759    };
37760
37761    // first loop over all controller qps, merging them with any matching route qps
37762    // into a new empty object to avoid mutating.
37763    for (var cqpName in controllerQP) {
37764      if (!controllerQP.hasOwnProperty(cqpName)) {
37765        continue;
37766      }
37767
37768      var newControllerParameterConfiguration = {};
37769      _emberMetalAssign.default(newControllerParameterConfiguration, controllerQP[cqpName]);
37770      _emberMetalAssign.default(newControllerParameterConfiguration, routeQP[cqpName]);
37771
37772      qps[cqpName] = newControllerParameterConfiguration;
37773
37774      // allows us to skip this QP when we check route QPs.
37775      keysAlreadyMergedOrSkippable[cqpName] = true;
37776    }
37777
37778    // loop over all route qps, skipping those that were merged in the first pass
37779    // because they also appear in controller qps
37780    for (var rqpName in routeQP) {
37781      if (!routeQP.hasOwnProperty(rqpName) || keysAlreadyMergedOrSkippable[rqpName]) {
37782        continue;
37783      }
37784
37785      var newRouteParameterConfiguration = {};
37786      _emberMetalAssign.default(newRouteParameterConfiguration, routeQP[rqpName], controllerQP[rqpName]);
37787      qps[rqpName] = newRouteParameterConfiguration;
37788    }
37789
37790    return qps;
37791  }
37792
37793  function addQueryParamsObservers(controller, propNames) {
37794    propNames.forEach(function (prop) {
37795      controller.addObserver(prop + '.[]', controller, controller._qpChanged);
37796    });
37797  }
37798
37799  function deprecateQueryParamDefaultValuesSetOnController(controllerName, routeName, propName) {
37800    _emberMetalDebug.deprecate('Configuring query parameter default values on controllers is deprecated. Please move the value for the property \'' + propName + '\' from the \'' + controllerName + '\' controller to the \'' + routeName + '\' route in the format: {queryParams: ' + propName + ': {defaultValue: <default value> }}', false, { id: 'ember-routing.deprecate-query-param-default-values-set-on-controller', until: '3.0.0' });
37801  }
37802
37803  exports.default = Route;
37804});
37805// FEATURES, A, deprecate, assert, Logger
37806
37807// apply default values to controllers
37808// detect that default value defined on router config
37809
37810// detect that property was not defined on controller
37811enifed('ember-routing/system/router', ['exports', 'ember-metal/logger', 'ember-metal/debug', 'ember-metal/error', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/properties', 'ember-metal/empty_object', 'ember-metal/computed', 'ember-metal/assign', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-runtime/mixins/evented', 'ember-routing/system/dsl', 'ember-routing/location/api', 'ember-routing/utils', 'ember-metal/utils', 'ember-routing/system/router_state', 'container/owner', 'ember-metal/dictionary', 'router', 'router/transition'], function (exports, _emberMetalLogger, _emberMetalDebug, _emberMetalError, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalProperties, _emberMetalEmpty_object, _emberMetalComputed, _emberMetalAssign, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberRuntimeMixinsEvented, _emberRoutingSystemDsl, _emberRoutingLocationApi, _emberRoutingUtils, _emberMetalUtils, _emberRoutingSystemRouter_state, _containerOwner, _emberMetalDictionary, _router4, _routerTransition) {
37812  'use strict';
37813
37814  exports.triggerEvent = triggerEvent;
37815
37816  function K() {
37817    return this;
37818  }
37819
37820  var slice = [].slice;
37821
37822  /**
37823    The `Ember.Router` class manages the application state and URLs. Refer to
37824    the [routing guide](http://emberjs.com/guides/routing/) for documentation.
37825  
37826    @class Router
37827    @namespace Ember
37828    @extends Ember.Object
37829    @uses Ember.Evented
37830    @public
37831  */
37832  var EmberRouter = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsEvented.default, {
37833    /**
37834      The `location` property determines the type of URL's that your
37835      application will use.
37836       The following location types are currently available:
37837       * `history` - use the browser's history API to make the URLs look just like any standard URL
37838      * `hash` - use `#` to separate the server part of the URL from the Ember part: `/blog/#/posts/new`
37839      * `none` - do not store the Ember URL in the actual browser URL (mainly used for testing)
37840      * `auto` - use the best option based on browser capabilites: `history` if possible, then `hash` if possible, otherwise `none`
37841       Note: If using ember-cli, this value is defaulted to `auto` by the `locationType` setting of `/config/environment.js`
37842       @property location
37843      @default 'hash'
37844      @see {Ember.Location}
37845      @public
37846    */
37847    location: 'hash',
37848
37849    /**
37850     Represents the URL of the root of the application, often '/'. This prefix is
37851     assumed on all routes defined on this router.
37852      @property rootURL
37853     @default '/'
37854     @public
37855    */
37856    rootURL: '/',
37857
37858    _initRouterJs: function () {
37859      var router = this.router = new _router4.default();
37860      router.triggerEvent = triggerEvent;
37861
37862      router._triggerWillChangeContext = K;
37863      router._triggerWillLeave = K;
37864
37865      var dslCallbacks = this.constructor.dslCallbacks || [K];
37866      var dsl = this._buildDSL();
37867
37868      dsl.route('application', { path: '/', resetNamespace: true, overrideNameAssertion: true }, function () {
37869        for (var i = 0; i < dslCallbacks.length; i++) {
37870          dslCallbacks[i].call(this);
37871        }
37872      });
37873
37874      if (_emberMetalProperty_get.get(this, 'namespace.LOG_TRANSITIONS_INTERNAL')) {
37875        router.log = _emberMetalLogger.default.debug;
37876      }
37877
37878      router.map(dsl.generate());
37879    },
37880
37881    _buildDSL: function () {
37882      var moduleBasedResolver = this._hasModuleBasedResolver();
37883
37884      return new _emberRoutingSystemDsl.default(null, {
37885        enableLoadingSubstates: !!moduleBasedResolver
37886      });
37887    },
37888
37889    init: function () {
37890      this._super.apply(this, arguments);
37891
37892      this._activeViews = {};
37893      this._qpCache = new _emberMetalEmpty_object.default();
37894      this._resetQueuedQueryParameterChanges();
37895      this._handledErrors = _emberMetalDictionary.default(null);
37896    },
37897
37898    /*
37899      Resets all pending query paramter changes.
37900      Called after transitioning to a new route
37901      based on query parameter changes.
37902    */
37903    _resetQueuedQueryParameterChanges: function () {
37904      this._queuedQPChanges = {};
37905    },
37906
37907    /**
37908      Represents the current URL.
37909       @method url
37910      @return {String} The current URL.
37911      @private
37912    */
37913    url: _emberMetalComputed.computed(function () {
37914      return _emberMetalProperty_get.get(this, 'location').getURL();
37915    }),
37916
37917    _hasModuleBasedResolver: function () {
37918      var owner = _containerOwner.getOwner(this);
37919
37920      if (!owner) {
37921        return false;
37922      }
37923
37924      var resolver = owner.application && owner.application.__registry__ && owner.application.__registry__.resolver;
37925
37926      if (!resolver) {
37927        return false;
37928      }
37929
37930      return !!resolver.moduleBasedResolver;
37931    },
37932
37933    /**
37934      Initializes the current router instance and sets up the change handling
37935      event listeners used by the instances `location` implementation.
37936       A property named `initialURL` will be used to determine the initial URL.
37937      If no value is found `/` will be used.
37938       @method startRouting
37939      @private
37940    */
37941    startRouting: function () {
37942      var initialURL = _emberMetalProperty_get.get(this, 'initialURL');
37943
37944      if (this.setupRouter()) {
37945        if (typeof initialURL === 'undefined') {
37946          initialURL = _emberMetalProperty_get.get(this, 'location').getURL();
37947        }
37948        var initialTransition = this.handleURL(initialURL);
37949        if (initialTransition && initialTransition.error) {
37950          throw initialTransition.error;
37951        }
37952      }
37953    },
37954
37955    setupRouter: function () {
37956      var _this = this;
37957
37958      this._initRouterJs();
37959      this._setupLocation();
37960
37961      var router = this.router;
37962      var location = _emberMetalProperty_get.get(this, 'location');
37963
37964      // Allow the Location class to cancel the router setup while it refreshes
37965      // the page
37966      if (_emberMetalProperty_get.get(location, 'cancelRouterSetup')) {
37967        return false;
37968      }
37969
37970      this._setupRouter(router, location);
37971
37972      location.onUpdateURL(function (url) {
37973        _this.handleURL(url);
37974      });
37975
37976      return true;
37977    },
37978
37979    /**
37980      Handles updating the paths and notifying any listeners of the URL
37981      change.
37982       Triggers the router level `didTransition` hook.
37983       For example, to notify google analytics when the route changes,
37984      you could use this hook.  (Note: requires also including GA scripts, etc.)
37985       ```javascript
37986      var Router = Ember.Router.extend({
37987        location: config.locationType,
37988         didTransition: function() {
37989          this._super(...arguments);
37990           return ga('send', 'pageview', {
37991            'page': this.get('url'),
37992            'title': this.get('url')
37993          });
37994        }
37995      });
37996      ```
37997       @method didTransition
37998      @public
37999      @since 1.2.0
38000    */
38001    didTransition: function (infos) {
38002      updatePaths(this);
38003
38004      this._cancelSlowTransitionTimer();
38005
38006      this.notifyPropertyChange('url');
38007      this.set('currentState', this.targetState);
38008
38009      // Put this in the runloop so url will be accurate. Seems
38010      // less surprising than didTransition being out of sync.
38011      _emberMetalRun_loop.default.once(this, this.trigger, 'didTransition');
38012
38013      if (_emberMetalProperty_get.get(this, 'namespace').LOG_TRANSITIONS) {
38014        _emberMetalLogger.default.log('Transitioned into \'' + EmberRouter._routePath(infos) + '\'');
38015      }
38016    },
38017
38018    _setOutlets: function () {
38019      var handlerInfos = this.router.currentHandlerInfos;
38020      var route;
38021      var defaultParentState;
38022      var liveRoutes = null;
38023
38024      if (!handlerInfos) {
38025        return;
38026      }
38027
38028      for (var i = 0; i < handlerInfos.length; i++) {
38029        route = handlerInfos[i].handler;
38030        var connections = route.connections;
38031        var ownState;
38032        for (var j = 0; j < connections.length; j++) {
38033          var appended = appendLiveRoute(liveRoutes, defaultParentState, connections[j]);
38034          liveRoutes = appended.liveRoutes;
38035          if (appended.ownState.render.name === route.routeName || appended.ownState.render.outlet === 'main') {
38036            ownState = appended.ownState;
38037          }
38038        }
38039        if (connections.length === 0) {
38040          ownState = representEmptyRoute(liveRoutes, defaultParentState, route);
38041        }
38042        defaultParentState = ownState;
38043      }
38044      if (!this._toplevelView) {
38045        var owner = _containerOwner.getOwner(this);
38046        var OutletView = owner._lookupFactory('view:-outlet');
38047        this._toplevelView = OutletView.create();
38048        var instance = owner.lookup('-application-instance:main');
38049        instance.didCreateRootView(this._toplevelView);
38050      }
38051      this._toplevelView.setOutletState(liveRoutes);
38052    },
38053
38054    /**
38055      Handles notifying any listeners of an impending URL
38056      change.
38057       Triggers the router level `willTransition` hook.
38058       @method willTransition
38059      @public
38060      @since 1.11.0
38061    */
38062    willTransition: function (oldInfos, newInfos, transition) {
38063      _emberMetalRun_loop.default.once(this, this.trigger, 'willTransition', transition);
38064
38065      if (_emberMetalProperty_get.get(this, 'namespace').LOG_TRANSITIONS) {
38066        _emberMetalLogger.default.log('Preparing to transition from \'' + EmberRouter._routePath(oldInfos) + '\' to \'' + EmberRouter._routePath(newInfos) + '\'');
38067      }
38068    },
38069
38070    handleURL: function (url) {
38071      // Until we have an ember-idiomatic way of accessing #hashes, we need to
38072      // remove it because router.js doesn't know how to handle it.
38073      url = url.split(/#(.+)?/)[0];
38074      return this._doURLTransition('handleURL', url);
38075    },
38076
38077    _doURLTransition: function (routerJsMethod, url) {
38078      var transition = this.router[routerJsMethod](url || '/');
38079      didBeginTransition(transition, this);
38080      return transition;
38081    },
38082
38083    /**
38084      Transition the application into another route. The route may
38085      be either a single route or route path:
38086       See [Route.transitionTo](http://emberjs.com/api/classes/Ember.Route.html#method_transitionTo) for more info.
38087       @method transitionTo
38088      @param {String} name the name of the route or a URL
38089      @param {...Object} models the model(s) or identifier(s) to be used while
38090        transitioning to the route.
38091      @param {Object} [options] optional hash with a queryParams property
38092        containing a mapping of query parameters
38093      @return {Transition} the transition object associated with this
38094        attempted transition
38095      @public
38096    */
38097    transitionTo: function () {
38098      var queryParams;
38099
38100      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
38101        args[_key] = arguments[_key];
38102      }
38103
38104      if (resemblesURL(args[0])) {
38105        return this._doURLTransition('transitionTo', args[0]);
38106      }
38107
38108      var possibleQueryParams = args[args.length - 1];
38109      if (possibleQueryParams && possibleQueryParams.hasOwnProperty('queryParams')) {
38110        queryParams = args.pop().queryParams;
38111      } else {
38112        queryParams = {};
38113      }
38114
38115      var targetRouteName = args.shift();
38116      return this._doTransition(targetRouteName, args, queryParams);
38117    },
38118
38119    intermediateTransitionTo: function () {
38120      var _router;
38121
38122      (_router = this.router).intermediateTransitionTo.apply(_router, arguments);
38123
38124      updatePaths(this);
38125
38126      var infos = this.router.currentHandlerInfos;
38127      if (_emberMetalProperty_get.get(this, 'namespace').LOG_TRANSITIONS) {
38128        _emberMetalLogger.default.log('Intermediate-transitioned into \'' + EmberRouter._routePath(infos) + '\'');
38129      }
38130    },
38131
38132    replaceWith: function () {
38133      return this.transitionTo.apply(this, arguments).method('replace');
38134    },
38135
38136    generate: function () {
38137      var _router2;
38138
38139      var url = (_router2 = this.router).generate.apply(_router2, arguments);
38140      return this.location.formatURL(url);
38141    },
38142
38143    /**
38144      Determines if the supplied route is currently active.
38145       @method isActive
38146      @param routeName
38147      @return {Boolean}
38148      @private
38149    */
38150    isActive: function (routeName) {
38151      var router = this.router;
38152      return router.isActive.apply(router, arguments);
38153    },
38154
38155    /**
38156      An alternative form of `isActive` that doesn't require
38157      manual concatenation of the arguments into a single
38158      array.
38159       @method isActiveIntent
38160      @param routeName
38161      @param models
38162      @param queryParams
38163      @return {Boolean}
38164      @private
38165      @since 1.7.0
38166    */
38167    isActiveIntent: function (routeName, models, queryParams) {
38168      return this.currentState.isActiveIntent(routeName, models, queryParams);
38169    },
38170
38171    send: function (name, context) {
38172      var _router3;
38173
38174      (_router3 = this.router).trigger.apply(_router3, arguments);
38175    },
38176
38177    /**
38178      Does this router instance have the given route.
38179       @method hasRoute
38180      @return {Boolean}
38181      @private
38182    */
38183    hasRoute: function (route) {
38184      return this.router.hasRoute(route);
38185    },
38186
38187    /**
38188      Resets the state of the router by clearing the current route
38189      handlers and deactivating them.
38190       @private
38191      @method reset
38192     */
38193    reset: function () {
38194      if (this.router) {
38195        this.router.reset();
38196      }
38197    },
38198
38199    willDestroy: function () {
38200      if (this._toplevelView) {
38201        this._toplevelView.destroy();
38202        this._toplevelView = null;
38203      }
38204      this._super.apply(this, arguments);
38205      this.reset();
38206    },
38207
38208    _lookupActiveComponentNode: function (templateName) {
38209      return this._activeViews[templateName];
38210    },
38211
38212    /*
38213      Called when an active route's query parameter has changed.
38214      These changes are batched into a runloop run and trigger
38215      a single transition.
38216    */
38217    _activeQPChanged: function (queryParameterName, newValue) {
38218      this._queuedQPChanges[queryParameterName] = newValue;
38219      _emberMetalRun_loop.default.once(this, this._fireQueryParamTransition);
38220    },
38221
38222    _updatingQPChanged: function (queryParameterName) {
38223      if (!this._qpUpdates) {
38224        this._qpUpdates = {};
38225      }
38226      this._qpUpdates[queryParameterName] = true;
38227    },
38228
38229    /*
38230      Triggers a transition to a route based on query parameter changes.
38231      This is called once per runloop, to batch changes.
38232       e.g.
38233       if these methods are called in succession:
38234      this._activeQPChanged('foo', '10');
38235        // results in _queuedQPChanges = {foo: '10'}
38236      this._activeQPChanged('bar', false);
38237        // results in _queuedQPChanges = {foo: '10', bar: false}
38238        _queuedQPChanges will represent both of these changes
38239      and the transition using `transitionTo` will be triggered
38240      once.
38241    */
38242    _fireQueryParamTransition: function () {
38243      this.transitionTo({ queryParams: this._queuedQPChanges });
38244      this._resetQueuedQueryParameterChanges();
38245    },
38246
38247    _connectActiveComponentNode: function (templateName, componentNode) {
38248      _emberMetalDebug.assert('cannot connect an activeView that already exists', !this._activeViews[templateName]);
38249
38250      var _activeViews = this._activeViews;
38251      function disconnectActiveView() {
38252        delete _activeViews[templateName];
38253      }
38254
38255      this._activeViews[templateName] = componentNode;
38256      componentNode.renderNode.addDestruction({ destroy: disconnectActiveView });
38257    },
38258
38259    _setupLocation: function () {
38260      var location = _emberMetalProperty_get.get(this, 'location');
38261      var rootURL = _emberMetalProperty_get.get(this, 'rootURL');
38262      var owner = _containerOwner.getOwner(this);
38263
38264      if ('string' === typeof location && owner) {
38265        var resolvedLocation = owner.lookup('location:' + location);
38266
38267        if ('undefined' !== typeof resolvedLocation) {
38268          location = _emberMetalProperty_set.set(this, 'location', resolvedLocation);
38269        } else {
38270          // Allow for deprecated registration of custom location API's
38271          var options = {
38272            implementation: location
38273          };
38274
38275          location = _emberMetalProperty_set.set(this, 'location', _emberRoutingLocationApi.default.create(options));
38276        }
38277      }
38278
38279      if (location !== null && typeof location === 'object') {
38280        if (rootURL) {
38281          _emberMetalProperty_set.set(location, 'rootURL', rootURL);
38282        }
38283
38284        // Allow the location to do any feature detection, such as AutoLocation
38285        // detecting history support. This gives it a chance to set its
38286        // `cancelRouterSetup` property which aborts routing.
38287        if (typeof location.detect === 'function') {
38288          location.detect();
38289        }
38290
38291        // ensure that initState is called AFTER the rootURL is set on
38292        // the location instance
38293        if (typeof location.initState === 'function') {
38294          location.initState();
38295        }
38296      }
38297    },
38298
38299    _getHandlerFunction: function () {
38300      var _this2 = this;
38301
38302      var seen = new _emberMetalEmpty_object.default();
38303      var owner = _containerOwner.getOwner(this);
38304      var DefaultRoute = owner._lookupFactory('route:basic');
38305
38306      return function (name) {
38307        var routeName = 'route:' + name;
38308        var handler = owner.lookup(routeName);
38309
38310        if (seen[name]) {
38311          return handler;
38312        }
38313
38314        seen[name] = true;
38315
38316        if (!handler) {
38317          owner.register(routeName, DefaultRoute.extend());
38318          handler = owner.lookup(routeName);
38319
38320          if (_emberMetalProperty_get.get(_this2, 'namespace.LOG_ACTIVE_GENERATION')) {
38321            _emberMetalDebug.info('generated -> ' + routeName, { fullName: routeName });
38322          }
38323        }
38324
38325        handler.routeName = name;
38326        return handler;
38327      };
38328    },
38329
38330    _setupRouter: function (router, location) {
38331      var lastURL;
38332      var emberRouter = this;
38333
38334      router.getHandler = this._getHandlerFunction();
38335
38336      var doUpdateURL = function () {
38337        location.setURL(lastURL);
38338      };
38339
38340      router.updateURL = function (path) {
38341        lastURL = path;
38342        _emberMetalRun_loop.default.once(doUpdateURL);
38343      };
38344
38345      if (location.replaceURL) {
38346        var doReplaceURL = function () {
38347          location.replaceURL(lastURL);
38348        };
38349
38350        router.replaceURL = function (path) {
38351          lastURL = path;
38352          _emberMetalRun_loop.default.once(doReplaceURL);
38353        };
38354      }
38355
38356      router.didTransition = function (infos) {
38357        emberRouter.didTransition(infos);
38358      };
38359
38360      router.willTransition = function (oldInfos, newInfos, transition) {
38361        emberRouter.willTransition(oldInfos, newInfos, transition);
38362      };
38363    },
38364
38365    _serializeQueryParams: function (targetRouteName, queryParams) {
38366      var groupedByUrlKey = {};
38367
38368      forEachQueryParam(this, targetRouteName, queryParams, function (key, value, qp) {
38369        var urlKey = qp.urlKey;
38370        if (!groupedByUrlKey[urlKey]) {
38371          groupedByUrlKey[urlKey] = [];
38372        }
38373        groupedByUrlKey[urlKey].push({
38374          qp: qp,
38375          value: value
38376        });
38377        delete queryParams[key];
38378      });
38379
38380      for (var key in groupedByUrlKey) {
38381        var qps = groupedByUrlKey[key];
38382        _emberMetalDebug.assert('You\'re not allowed to have more than one controller property map to the same query param key, but both `' + qps[0].qp.scopedPropertyName + '` and `' + (qps[1] ? qps[1].qp.scopedPropertyName : '') + '` map to `' + qps[0].qp.urlKey + '`. You can fix this by mapping one of the controller properties to a different query param key via the `as` config option, e.g. `' + qps[0].qp.prop + ': { as: \'other-' + qps[0].qp.prop + '\' }`', qps.length <= 1);
38383        var qp = qps[0].qp;
38384        queryParams[qp.urlKey] = qp.route.serializeQueryParam(qps[0].value, qp.urlKey, qp.type);
38385      }
38386    },
38387
38388    _deserializeQueryParams: function (targetRouteName, queryParams) {
38389      forEachQueryParam(this, targetRouteName, queryParams, function (key, value, qp) {
38390        delete queryParams[key];
38391        queryParams[qp.prop] = qp.route.deserializeQueryParam(value, qp.urlKey, qp.type);
38392      });
38393    },
38394
38395    _pruneDefaultQueryParamValues: function (targetRouteName, queryParams) {
38396      var qps = this._queryParamsFor(targetRouteName);
38397      for (var key in queryParams) {
38398        var qp = qps.map[key];
38399        if (qp && qp.serializedDefaultValue === queryParams[key]) {
38400          delete queryParams[key];
38401        }
38402      }
38403    },
38404
38405    _doTransition: function (_targetRouteName, models, _queryParams) {
38406      var targetRouteName = _targetRouteName || _emberRoutingUtils.getActiveTargetName(this.router);
38407      _emberMetalDebug.assert('The route ' + targetRouteName + ' was not found', targetRouteName && this.router.hasRoute(targetRouteName));
38408
38409      var queryParams = {};
38410      // merge in any queryParams from the active transition which could include
38411      // queryparams from the url on initial load.
38412      if (this.router.activeTransition) {
38413        _emberMetalAssign.default(queryParams, this.router.activeTransition.queryParams);
38414      }
38415
38416      _emberMetalAssign.default(queryParams, _queryParams);
38417      this._prepareQueryParams(targetRouteName, models, queryParams);
38418
38419      var transitionArgs = _emberRoutingUtils.routeArgs(targetRouteName, models, queryParams);
38420      var transition = this.router.transitionTo.apply(this.router, transitionArgs);
38421
38422      didBeginTransition(transition, this);
38423
38424      return transition;
38425    },
38426
38427    _prepareQueryParams: function (targetRouteName, models, queryParams) {
38428      this._hydrateUnsuppliedQueryParams(targetRouteName, models, queryParams);
38429      this._serializeQueryParams(targetRouteName, queryParams);
38430      this._pruneDefaultQueryParamValues(targetRouteName, queryParams);
38431    },
38432
38433    /**
38434      Returns a merged query params meta object for a given route.
38435      Useful for asking a route what its known query params are.
38436       @private
38437     */
38438    _queryParamsFor: function (leafRouteName) {
38439      if (this._qpCache[leafRouteName]) {
38440        return this._qpCache[leafRouteName];
38441      }
38442
38443      var map = {};
38444      var qps = [];
38445      this._qpCache[leafRouteName] = {
38446        map: map,
38447        qps: qps
38448      };
38449
38450      var routerjs = this.router;
38451      var recogHandlerInfos = routerjs.recognizer.handlersFor(leafRouteName);
38452
38453      for (var i = 0, len = recogHandlerInfos.length; i < len; ++i) {
38454        var recogHandler = recogHandlerInfos[i];
38455        var route = routerjs.getHandler(recogHandler.handler);
38456        var qpMeta = _emberMetalProperty_get.get(route, '_qp');
38457
38458        if (!qpMeta) {
38459          continue;
38460        }
38461
38462        _emberMetalAssign.default(map, qpMeta.map);
38463        qps.push.apply(qps, qpMeta.qps);
38464      }
38465
38466      return {
38467        qps: qps,
38468        map: map
38469      };
38470    },
38471
38472    _hydrateUnsuppliedQueryParams: function (leafRouteName, contexts, queryParams) {
38473      var state = calculatePostTransitionState(this, leafRouteName, contexts);
38474      var handlerInfos = state.handlerInfos;
38475      var appCache = this._bucketCache;
38476      _emberRoutingUtils.stashParamNames(this, handlerInfos);
38477
38478      for (var i = 0, len = handlerInfos.length; i < len; ++i) {
38479        var route = handlerInfos[i].handler;
38480        var qpMeta = _emberMetalProperty_get.get(route, '_qp');
38481
38482        for (var j = 0, qpLen = qpMeta.qps.length; j < qpLen; ++j) {
38483          var qp = qpMeta.qps[j];
38484
38485          var presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName;
38486
38487          if (presentProp) {
38488            if (presentProp !== qp.scopedPropertyName) {
38489              queryParams[qp.scopedPropertyName] = queryParams[presentProp];
38490              delete queryParams[presentProp];
38491            }
38492          } else {
38493            var cacheKey = _emberRoutingUtils.calculateCacheKey(qp.ctrl, qp.parts, state.params);
38494            queryParams[qp.scopedPropertyName] = appCache.lookup(cacheKey, qp.prop, qp.defaultValue);
38495          }
38496        }
38497      }
38498    },
38499
38500    _scheduleLoadingEvent: function (transition, originRoute) {
38501      this._cancelSlowTransitionTimer();
38502      this._slowTransitionTimer = _emberMetalRun_loop.default.scheduleOnce('routerTransitions', this, '_handleSlowTransition', transition, originRoute);
38503    },
38504
38505    currentState: null,
38506    targetState: null,
38507
38508    _handleSlowTransition: function (transition, originRoute) {
38509      if (!this.router.activeTransition) {
38510        // Don't fire an event if we've since moved on from
38511        // the transition that put us in a loading state.
38512        return;
38513      }
38514
38515      this.set('targetState', _emberRoutingSystemRouter_state.default.create({
38516        emberRouter: this,
38517        routerJs: this.router,
38518        routerJsState: this.router.activeTransition.state
38519      }));
38520
38521      transition.trigger(true, 'loading', transition, originRoute);
38522    },
38523
38524    _cancelSlowTransitionTimer: function () {
38525      if (this._slowTransitionTimer) {
38526        _emberMetalRun_loop.default.cancel(this._slowTransitionTimer);
38527      }
38528      this._slowTransitionTimer = null;
38529    },
38530
38531    // These three helper functions are used to ensure errors aren't
38532    // re-raised if they're handled in a route's error action.
38533    _markErrorAsHandled: function (errorGuid) {
38534      this._handledErrors[errorGuid] = true;
38535    },
38536
38537    _isErrorHandled: function (errorGuid) {
38538      return this._handledErrors[errorGuid];
38539    },
38540
38541    _clearHandledError: function (errorGuid) {
38542      delete this._handledErrors[errorGuid];
38543    }
38544  });
38545
38546  /*
38547    Helper function for iterating root-ward, starting
38548    from (but not including) the provided `originRoute`.
38549  
38550    Returns true if the last callback fired requested
38551    to bubble upward.
38552  
38553    @private
38554   */
38555  function forEachRouteAbove(originRoute, transition, callback) {
38556    var handlerInfos = transition.state.handlerInfos;
38557    var originRouteFound = false;
38558    var handlerInfo, route;
38559
38560    for (var i = handlerInfos.length - 1; i >= 0; --i) {
38561      handlerInfo = handlerInfos[i];
38562      route = handlerInfo.handler;
38563
38564      if (!originRouteFound) {
38565        if (originRoute === route) {
38566          originRouteFound = true;
38567        }
38568        continue;
38569      }
38570
38571      if (callback(route, handlerInfos[i + 1].handler) !== true) {
38572        return false;
38573      }
38574    }
38575    return true;
38576  }
38577
38578  // These get invoked when an action bubbles above ApplicationRoute
38579  // and are not meant to be overridable.
38580  var defaultActionHandlers = {
38581
38582    willResolveModel: function (transition, originRoute) {
38583      originRoute.router._scheduleLoadingEvent(transition, originRoute);
38584    },
38585
38586    error: function (error, transition, originRoute) {
38587      // Attempt to find an appropriate error substate to enter.
38588      var router = originRoute.router;
38589
38590      var tryTopLevel = forEachRouteAbove(originRoute, transition, function (route, childRoute) {
38591        var childErrorRouteName = findChildRouteName(route, childRoute, 'error');
38592        if (childErrorRouteName) {
38593          router.intermediateTransitionTo(childErrorRouteName, error);
38594          return;
38595        }
38596        return true;
38597      });
38598
38599      if (tryTopLevel) {
38600        // Check for top-level error state to enter.
38601        if (routeHasBeenDefined(originRoute.router, 'application_error')) {
38602          router.intermediateTransitionTo('application_error', error);
38603          return;
38604        }
38605      }
38606
38607      logError(error, 'Error while processing route: ' + transition.targetName);
38608    },
38609
38610    loading: function (transition, originRoute) {
38611      // Attempt to find an appropriate loading substate to enter.
38612      var router = originRoute.router;
38613
38614      var tryTopLevel = forEachRouteAbove(originRoute, transition, function (route, childRoute) {
38615        var childLoadingRouteName = findChildRouteName(route, childRoute, 'loading');
38616
38617        if (childLoadingRouteName) {
38618          router.intermediateTransitionTo(childLoadingRouteName);
38619          return;
38620        }
38621
38622        // Don't bubble above pivot route.
38623        if (transition.pivotHandler !== route) {
38624          return true;
38625        }
38626      });
38627
38628      if (tryTopLevel) {
38629        // Check for top-level loading state to enter.
38630        if (routeHasBeenDefined(originRoute.router, 'application_loading')) {
38631          router.intermediateTransitionTo('application_loading');
38632          return;
38633        }
38634      }
38635    }
38636  };
38637
38638  function logError(_error, initialMessage) {
38639    var errorArgs = [];
38640    var error;
38641    if (_error && typeof _error === 'object' && typeof _error.errorThrown === 'object') {
38642      error = _error.errorThrown;
38643    } else {
38644      error = _error;
38645    }
38646
38647    if (initialMessage) {
38648      errorArgs.push(initialMessage);
38649    }
38650
38651    if (error) {
38652      if (error.message) {
38653        errorArgs.push(error.message);
38654      }
38655      if (error.stack) {
38656        errorArgs.push(error.stack);
38657      }
38658
38659      if (typeof error === 'string') {
38660        errorArgs.push(error);
38661      }
38662    }
38663
38664    _emberMetalLogger.default.error.apply(this, errorArgs);
38665  }
38666
38667  function findChildRouteName(parentRoute, originatingChildRoute, name) {
38668    var router = parentRoute.router;
38669    var childName;
38670    var targetChildRouteName = originatingChildRoute.routeName.split('.').pop();
38671    var namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.';
38672
38673    // First, try a named loading state, e.g. 'foo_loading'
38674    childName = namespace + targetChildRouteName + '_' + name;
38675    if (routeHasBeenDefined(router, childName)) {
38676      return childName;
38677    }
38678
38679    // Second, try general loading state, e.g. 'loading'
38680    childName = namespace + name;
38681    if (routeHasBeenDefined(router, childName)) {
38682      return childName;
38683    }
38684  }
38685
38686  function routeHasBeenDefined(router, name) {
38687    var owner = _containerOwner.getOwner(router);
38688    return router.hasRoute(name) && (owner.hasRegistration('template:' + name) || owner.hasRegistration('route:' + name));
38689  }
38690
38691  function triggerEvent(handlerInfos, ignoreFailure, args) {
38692    var name = args.shift();
38693
38694    if (!handlerInfos) {
38695      if (ignoreFailure) {
38696        return;
38697      }
38698      throw new _emberMetalError.default('Can\'t trigger action \'' + name + '\' because your app hasn\'t finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call `.send()` on the `Transition` object passed to the `model/beforeModel/afterModel` hooks.');
38699    }
38700
38701    var eventWasHandled = false;
38702    var handlerInfo, handler;
38703
38704    for (var i = handlerInfos.length - 1; i >= 0; i--) {
38705      handlerInfo = handlerInfos[i];
38706      handler = handlerInfo.handler;
38707
38708      if (handler.actions && handler.actions[name]) {
38709        if (handler.actions[name].apply(handler, args) === true) {
38710          eventWasHandled = true;
38711        } else {
38712          // Should only hit here if a non-bubbling error action is triggered on a route.
38713          if (name === 'error') {
38714            var errorId = _emberMetalUtils.guidFor(args[0]);
38715            handler.router._markErrorAsHandled(errorId);
38716          }
38717          return;
38718        }
38719      }
38720    }
38721
38722    if (defaultActionHandlers[name]) {
38723      defaultActionHandlers[name].apply(null, args);
38724      return;
38725    }
38726
38727    if (!eventWasHandled && !ignoreFailure) {
38728      throw new _emberMetalError.default('Nothing handled the action \'' + name + '\'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.');
38729    }
38730  }
38731
38732  function calculatePostTransitionState(emberRouter, leafRouteName, contexts) {
38733    var routerjs = emberRouter.router;
38734    var state = routerjs.applyIntent(leafRouteName, contexts);
38735    var handlerInfos = state.handlerInfos;
38736    var params = state.params;
38737
38738    for (var i = 0, len = handlerInfos.length; i < len; ++i) {
38739      var handlerInfo = handlerInfos[i];
38740      if (!handlerInfo.isResolved) {
38741        handlerInfo = handlerInfo.becomeResolved(null, handlerInfo.context);
38742      }
38743      params[handlerInfo.name] = handlerInfo.params;
38744    }
38745    return state;
38746  }
38747
38748  function updatePaths(router) {
38749    var infos = router.router.currentHandlerInfos;
38750    var path = EmberRouter._routePath(infos);
38751    var currentRouteName = infos[infos.length - 1].name;
38752
38753    _emberMetalProperty_set.set(router, 'currentPath', path);
38754    _emberMetalProperty_set.set(router, 'currentRouteName', currentRouteName);
38755
38756    var appController = _containerOwner.getOwner(router).lookup('controller:application');
38757
38758    if (!appController) {
38759      // appController might not exist when top-level loading/error
38760      // substates have been entered since ApplicationRoute hasn't
38761      // actually been entered at that point.
38762      return;
38763    }
38764
38765    if (!('currentPath' in appController)) {
38766      _emberMetalProperties.defineProperty(appController, 'currentPath');
38767    }
38768
38769    _emberMetalProperty_set.set(appController, 'currentPath', path);
38770
38771    if (!('currentRouteName' in appController)) {
38772      _emberMetalProperties.defineProperty(appController, 'currentRouteName');
38773    }
38774
38775    _emberMetalProperty_set.set(appController, 'currentRouteName', currentRouteName);
38776  }
38777
38778  EmberRouter.reopenClass({
38779    router: null,
38780
38781    /**
38782      The `Router.map` function allows you to define mappings from URLs to routes
38783      in your application. These mappings are defined within the
38784      supplied callback function using `this.route`.
38785       The first parameter is the name of the route which is used by default as the
38786      path name as well.
38787       The second parameter is the optional options hash. Available options are:
38788        * `path`: allows you to provide your own path as well as mark dynamic
38789          segments.
38790        * `resetNamespace`: false by default; when nesting routes, ember will
38791          combine the route names to form the fully-qualified route name, which is
38792          used with `{{link-to}}` or manually transitioning to routes. Setting
38793          `resetNamespace: true` will cause the route not to inherit from its
38794          parent route's names. This is handy for resources which can be accessed
38795          in multiple places as well as preventing extremely long route names.
38796          Keep in mind that the actual URL path behavior is still retained.
38797       The third parameter is a function, which can be used to nest routes.
38798      Nested routes, by default, will have the parent route tree's route name and
38799      path prepended to it's own.
38800       ```javascript
38801      App.Router.map(function(){
38802        this.route('post', { path: '/post/:post_id' }, function() {
38803          this.route('edit');
38804          this.route('comments', { resetNamespace: true }, function() {
38805            this.route('new');
38806          });
38807        });
38808      });
38809      ```
38810       For more detailed documentation and examples please see
38811      [the guides](http://emberjs.com/guides/routing/defining-your-routes/).
38812       @method map
38813      @param callback
38814      @public
38815    */
38816    map: function (callback) {
38817      if (!this.dslCallbacks) {
38818        this.dslCallbacks = [];
38819        this.reopenClass({ dslCallbacks: this.dslCallbacks });
38820      }
38821
38822      this.dslCallbacks.push(callback);
38823
38824      return this;
38825    },
38826
38827    _routePath: function (handlerInfos) {
38828      var path = [];
38829
38830      // We have to handle coalescing resource names that
38831      // are prefixed with their parent's names, e.g.
38832      // ['foo', 'foo.bar.baz'] => 'foo.bar.baz', not 'foo.foo.bar.baz'
38833
38834      function intersectionMatches(a1, a2) {
38835        for (var i = 0, len = a1.length; i < len; ++i) {
38836          if (a1[i] !== a2[i]) {
38837            return false;
38838          }
38839        }
38840        return true;
38841      }
38842
38843      var name, nameParts, oldNameParts;
38844      for (var i = 1, l = handlerInfos.length; i < l; i++) {
38845        name = handlerInfos[i].name;
38846        nameParts = name.split('.');
38847        oldNameParts = slice.call(path);
38848
38849        while (oldNameParts.length) {
38850          if (intersectionMatches(oldNameParts, nameParts)) {
38851            break;
38852          }
38853          oldNameParts.shift();
38854        }
38855
38856        path.push.apply(path, nameParts.slice(oldNameParts.length));
38857      }
38858
38859      return path.join('.');
38860    }
38861  });
38862
38863  function didBeginTransition(transition, router) {
38864    var routerState = _emberRoutingSystemRouter_state.default.create({
38865      emberRouter: router,
38866      routerJs: router.router,
38867      routerJsState: transition.state
38868    });
38869
38870    if (!router.currentState) {
38871      router.set('currentState', routerState);
38872    }
38873    router.set('targetState', routerState);
38874
38875    transition.promise = transition.catch(function (error) {
38876      var errorId = _emberMetalUtils.guidFor(error);
38877
38878      if (router._isErrorHandled(errorId)) {
38879        router._clearHandledError(errorId);
38880      } else {
38881        throw error;
38882      }
38883    });
38884  }
38885
38886  function resemblesURL(str) {
38887    return typeof str === 'string' && (str === '' || str.charAt(0) === '/');
38888  }
38889
38890  function forEachQueryParam(router, targetRouteName, queryParams, callback) {
38891    var qpCache = router._queryParamsFor(targetRouteName);
38892
38893    for (var key in queryParams) {
38894      if (!queryParams.hasOwnProperty(key)) {
38895        continue;
38896      }
38897      var value = queryParams[key];
38898      var qp = qpCache.map[key];
38899
38900      if (qp) {
38901        callback(key, value, qp);
38902      }
38903    }
38904  }
38905
38906  function findLiveRoute(liveRoutes, name) {
38907    if (!liveRoutes) {
38908      return;
38909    }
38910    var stack = [liveRoutes];
38911    while (stack.length > 0) {
38912      var test = stack.shift();
38913      if (test.render.name === name) {
38914        return test;
38915      }
38916      var outlets = test.outlets;
38917      for (var outletName in outlets) {
38918        stack.push(outlets[outletName]);
38919      }
38920    }
38921  }
38922
38923  function appendLiveRoute(liveRoutes, defaultParentState, renderOptions) {
38924    var target;
38925    var myState = {
38926      render: renderOptions,
38927      outlets: new _emberMetalEmpty_object.default()
38928    };
38929    if (renderOptions.into) {
38930      target = findLiveRoute(liveRoutes, renderOptions.into);
38931    } else {
38932      target = defaultParentState;
38933    }
38934    if (target) {
38935      _emberMetalProperty_set.set(target.outlets, renderOptions.outlet, myState);
38936    } else {
38937      if (renderOptions.into) {
38938        // Megahax time. Post-2.0-breaking-changes, we will just assert
38939        // right here that the user tried to target a nonexistent
38940        // thing. But for now we still need to support the `render`
38941        // helper, and people are allowed to target templates rendered
38942        // by the render helper. So instead we defer doing anyting with
38943        // these orphan renders until afterRender.
38944        appendOrphan(liveRoutes, renderOptions.into, myState);
38945      } else {
38946        liveRoutes = myState;
38947      }
38948    }
38949    return {
38950      liveRoutes: liveRoutes,
38951      ownState: myState
38952    };
38953  }
38954
38955  function appendOrphan(liveRoutes, into, myState) {
38956    if (!liveRoutes.outlets.__ember_orphans__) {
38957      liveRoutes.outlets.__ember_orphans__ = {
38958        render: {
38959          name: '__ember_orphans__'
38960        },
38961        outlets: new _emberMetalEmpty_object.default()
38962      };
38963    }
38964    liveRoutes.outlets.__ember_orphans__.outlets[into] = myState;
38965    _emberMetalRun_loop.default.schedule('afterRender', function () {
38966      // `wasUsed` gets set by the render helper. See the function
38967      // `impersonateAnOutlet`.
38968      _emberMetalDebug.assert('You attempted to render into \'' + into + '\' but it was not found', liveRoutes.outlets.__ember_orphans__.outlets[into].wasUsed);
38969    });
38970  }
38971
38972  function representEmptyRoute(liveRoutes, defaultParentState, route) {
38973    // the route didn't render anything
38974    var alreadyAppended = findLiveRoute(liveRoutes, route.routeName);
38975    if (alreadyAppended) {
38976      // But some other route has already rendered our default
38977      // template, so that becomes the default target for any
38978      // children we may have.
38979      return alreadyAppended;
38980    } else {
38981      // Create an entry to represent our default template name,
38982      // just so other routes can target it and inherit its place
38983      // in the outlet hierarchy.
38984      defaultParentState.outlets.main = {
38985        render: {
38986          name: route.routeName,
38987          outlet: 'main'
38988        },
38989        outlets: {}
38990      };
38991      return defaultParentState;
38992    }
38993  }
38994
38995  exports.default = EmberRouter;
38996});
38997
38998/**
38999@module ember
39000@submodule ember-routing
39001*/
39002enifed('ember-routing/system/router_state', ['exports', 'ember-metal/is_empty', 'ember-runtime/system/object', 'ember-metal/assign'], function (exports, _emberMetalIs_empty, _emberRuntimeSystemObject, _emberMetalAssign) {
39003  'use strict';
39004
39005  var keys = Object.keys;
39006
39007  var RouterState = _emberRuntimeSystemObject.default.extend({
39008    emberRouter: null,
39009    routerJs: null,
39010    routerJsState: null,
39011
39012    isActiveIntent: function (routeName, models, queryParams, queryParamsMustMatch) {
39013      var state = this.routerJsState;
39014      if (!this.routerJs.isActiveIntent(routeName, models, null, state)) {
39015        return false;
39016      }
39017
39018      var emptyQueryParams = _emberMetalIs_empty.default(keys(queryParams));
39019
39020      if (queryParamsMustMatch && !emptyQueryParams) {
39021        var visibleQueryParams = {};
39022        _emberMetalAssign.default(visibleQueryParams, queryParams);
39023
39024        this.emberRouter._prepareQueryParams(routeName, models, visibleQueryParams);
39025        return shallowEqual(visibleQueryParams, state.queryParams);
39026      }
39027
39028      return true;
39029    }
39030  });
39031
39032  function shallowEqual(a, b) {
39033    var k;
39034    for (k in a) {
39035      if (a.hasOwnProperty(k) && a[k] !== b[k]) {
39036        return false;
39037      }
39038    }
39039    for (k in b) {
39040      if (b.hasOwnProperty(k) && a[k] !== b[k]) {
39041        return false;
39042      }
39043    }
39044    return true;
39045  }
39046
39047  exports.default = RouterState;
39048});
39049enifed('ember-routing/utils', ['exports', 'ember-metal/assign', 'ember-metal/property_get'], function (exports, _emberMetalAssign, _emberMetalProperty_get) {
39050  'use strict';
39051
39052  exports.routeArgs = routeArgs;
39053  exports.getActiveTargetName = getActiveTargetName;
39054  exports.stashParamNames = stashParamNames;
39055  exports.calculateCacheKey = calculateCacheKey;
39056  exports.normalizeControllerQueryParams = normalizeControllerQueryParams;
39057
39058  function routeArgs(targetRouteName, models, queryParams) {
39059    var args = [];
39060    if (typeof targetRouteName === 'string') {
39061      args.push('' + targetRouteName);
39062    }
39063    args.push.apply(args, models);
39064    args.push({ queryParams: queryParams });
39065    return args;
39066  }
39067
39068  function getActiveTargetName(router) {
39069    var handlerInfos = router.activeTransition ? router.activeTransition.state.handlerInfos : router.state.handlerInfos;
39070    return handlerInfos[handlerInfos.length - 1].name;
39071  }
39072
39073  function stashParamNames(router, handlerInfos) {
39074    if (handlerInfos._namesStashed) {
39075      return;
39076    }
39077
39078    // This helper exists because router.js/route-recognizer.js awkwardly
39079    // keeps separate a handlerInfo's list of parameter names depending
39080    // on whether a URL transition or named transition is happening.
39081    // Hopefully we can remove this in the future.
39082    var targetRouteName = handlerInfos[handlerInfos.length - 1].name;
39083    var recogHandlers = router.router.recognizer.handlersFor(targetRouteName);
39084    var dynamicParent = null;
39085
39086    for (var i = 0, len = handlerInfos.length; i < len; ++i) {
39087      var handlerInfo = handlerInfos[i];
39088      var names = recogHandlers[i].names;
39089
39090      if (names.length) {
39091        dynamicParent = handlerInfo;
39092      }
39093
39094      handlerInfo._names = names;
39095
39096      var route = handlerInfo.handler;
39097      route._stashNames(handlerInfo, dynamicParent);
39098    }
39099
39100    handlerInfos._namesStashed = true;
39101  }
39102
39103  function _calculateCacheValuePrefix(prefix, part) {
39104    // calculates the dot seperated sections from prefix that are also
39105    // at the start of part - which gives us the route name
39106
39107    // given : prefix = site.article.comments, part = site.article.id
39108    //      - returns: site.article (use get(values[site.article], 'id') to get the dynamic part - used below)
39109
39110    // given : prefix = site.article, part = site.article.id
39111    //      - returns: site.article. (use get(values[site.article], 'id') to get the dynamic part - used below)
39112
39113    var prefixParts = prefix.split('.');
39114    var currPrefix = '';
39115
39116    for (var i = 0, len = prefixParts.length; i < len; i++) {
39117      var currPart = prefixParts.slice(0, i + 1).join('.');
39118      if (part.indexOf(currPart) !== 0) {
39119        break;
39120      }
39121      currPrefix = currPart;
39122    }
39123
39124    return currPrefix;
39125  }
39126
39127  /*
39128    Stolen from Controller
39129  */
39130
39131  function calculateCacheKey(prefix, _parts, values) {
39132    var parts = _parts || [];
39133    var suffixes = '';
39134    for (var i = 0, len = parts.length; i < len; ++i) {
39135      var part = parts[i];
39136      var cacheValuePrefix = _calculateCacheValuePrefix(prefix, part);
39137      var value;
39138      if (values) {
39139        if (cacheValuePrefix && cacheValuePrefix in values) {
39140          var partRemovedPrefix = part.indexOf(cacheValuePrefix) === 0 ? part.substr(cacheValuePrefix.length + 1) : part;
39141          value = _emberMetalProperty_get.get(values[cacheValuePrefix], partRemovedPrefix);
39142        } else {
39143          value = _emberMetalProperty_get.get(values, part);
39144        }
39145      }
39146      suffixes += '::' + part + ':' + value;
39147    }
39148    return prefix + suffixes.replace(ALL_PERIODS_REGEX, '-');
39149  }
39150
39151  var ALL_PERIODS_REGEX = /\./g;
39152
39153  /*
39154    Controller-defined query parameters can come in three shapes:
39155  
39156    Array
39157      queryParams: ['foo', 'bar']
39158    Array of simple objects where value is an alias
39159      queryParams: [
39160        {
39161          'foo': 'rename_foo_to_this'
39162        },
39163        {
39164          'bar': 'call_bar_this_instead'
39165        }
39166      ]
39167    Array of fully defined objects
39168      queryParams: [
39169        {
39170          'foo': {
39171            as: 'rename_foo_to_this'
39172          },
39173        }
39174        {
39175          'bar': {
39176            as: 'call_bar_this_instead',
39177            scope: 'controller'
39178          }
39179        }
39180      ]
39181  
39182    This helper normalizes all three possible styles into the
39183    'Array of fully defined objects' style.
39184  */
39185
39186  function normalizeControllerQueryParams(queryParams) {
39187    if (queryParams._qpMap) {
39188      return queryParams._qpMap;
39189    }
39190
39191    var qpMap = queryParams._qpMap = {};
39192
39193    for (var i = 0, len = queryParams.length; i < len; ++i) {
39194      accumulateQueryParamDescriptors(queryParams[i], qpMap);
39195    }
39196
39197    return qpMap;
39198  }
39199
39200  function accumulateQueryParamDescriptors(_desc, accum) {
39201    var desc = _desc;
39202    var tmp;
39203    if (typeof desc === 'string') {
39204      tmp = {};
39205      tmp[desc] = { as: null };
39206      desc = tmp;
39207    }
39208
39209    for (var key in desc) {
39210      if (!desc.hasOwnProperty(key)) {
39211        return;
39212      }
39213
39214      var singleDesc = desc[key];
39215      if (typeof singleDesc === 'string') {
39216        singleDesc = { as: singleDesc };
39217      }
39218
39219      tmp = accum[key] || { as: null, scope: 'model' };
39220      _emberMetalAssign.default(tmp, singleDesc);
39221
39222      accum[key] = tmp;
39223    }
39224  }
39225});
39226enifed('ember-routing-htmlbars/helpers/query-params', ['exports', 'ember-metal/debug', 'ember-routing/system/query_params'], function (exports, _emberMetalDebug, _emberRoutingSystemQuery_params) {
39227  /**
39228  @module ember
39229  @submodule ember-routing-htmlbars
39230  */
39231
39232  'use strict';
39233
39234  exports.queryParamsHelper = queryParamsHelper;
39235
39236  /**
39237    This is a helper to be used in conjunction with the link-to helper.
39238    It will supply url query parameters to the target route.
39239  
39240    Example
39241  
39242    ```handlebars
39243    {{#link-to 'posts' (query-params direction="asc")}}Sort{{/link-to}}
39244    ```
39245  
39246    @method query-params
39247    @for Ember.Templates.helpers
39248    @param {Object} hash takes a hash of query parameters
39249    @return {Object} A `QueryParams` object for `{{link-to}}`
39250    @public
39251  */
39252
39253  function queryParamsHelper(params, hash) {
39254    _emberMetalDebug.assert('The `query-params` helper only accepts hash parameters, e.g. (query-params queryParamPropertyName=\'foo\') as opposed to just (query-params \'foo\')', params.length === 0);
39255
39256    return _emberRoutingSystemQuery_params.default.create({
39257      values: hash
39258    });
39259  }
39260});
39261enifed('ember-routing-htmlbars/index', ['exports', 'ember-metal/core', 'ember-htmlbars/helpers', 'ember-htmlbars/keywords', 'ember-routing-htmlbars/helpers/query-params', 'ember-routing-htmlbars/keywords/action', 'ember-routing-htmlbars/keywords/element-action', 'ember-routing-htmlbars/keywords/render'], function (exports, _emberMetalCore, _emberHtmlbarsHelpers, _emberHtmlbarsKeywords, _emberRoutingHtmlbarsHelpersQueryParams, _emberRoutingHtmlbarsKeywordsAction, _emberRoutingHtmlbarsKeywordsElementAction, _emberRoutingHtmlbarsKeywordsRender) {
39262  /**
39263  @module ember
39264  @submodule ember-routing-htmlbars
39265  */
39266
39267  'use strict';
39268
39269  _emberHtmlbarsHelpers.registerHelper('query-params', _emberRoutingHtmlbarsHelpersQueryParams.queryParamsHelper);
39270
39271  _emberHtmlbarsKeywords.registerKeyword('action', _emberRoutingHtmlbarsKeywordsAction.default);
39272  _emberHtmlbarsKeywords.registerKeyword('@element_action', _emberRoutingHtmlbarsKeywordsElementAction.default);
39273  _emberHtmlbarsKeywords.registerKeyword('render', _emberRoutingHtmlbarsKeywordsRender.default);
39274
39275  exports.default = _emberMetalCore.default;
39276});
39277enifed('ember-routing-htmlbars/keywords/action', ['exports', 'htmlbars-runtime/hooks', 'ember-routing-htmlbars/keywords/closure-action'], function (exports, _htmlbarsRuntimeHooks, _emberRoutingHtmlbarsKeywordsClosureAction) {
39278  /**
39279  @module ember
39280  @submodule ember-templates
39281  */
39282
39283  'use strict';
39284
39285  /**
39286    The `{{action}}` helper provides a way to pass triggers for behavior (usually
39287    just a function) between components, and into components from controllers.
39288  
39289    ### Passing functions with the action helper
39290  
39291    There are three contexts an action helper can be used in. The first two
39292    contexts to discuss are attribute context, and Handlebars value context.
39293  
39294    ```handlebars
39295    {{! An example of attribute context }}
39296    <div onclick={{action "save"}}></div>
39297    {{! Examples of Handlebars value context }}
39298    {{input on-input=(action "save")}}
39299    {{yield (action "refreshData") andAnotherParam}}
39300    ```
39301  
39302    In these contexts,
39303    the helper is called a "closure action" helper. Its behavior is simple:
39304    If passed a function name, read that function off the `actions` property
39305    of the current context. Once that function is read (or if a function was
39306    passed), create a closure over that function and any arguments.
39307  
39308    The resulting value of an action helper used this way is simply a function.
39309    For example, in the attribute context:
39310  
39311    ```handlebars
39312    {{! An example of attribute context }}
39313    <div onclick={{action "save"}}></div>
39314    ```
39315  
39316    The resulting template render logic would be:
39317  
39318    ```js
39319    var div = document.createElement('div');
39320    var actionFunction = (function(context){
39321      return function() {
39322        return context.actions.save.apply(context, arguments);
39323      };
39324    })(context);
39325    div.onclick = actionFunction;
39326    ```
39327  
39328    Thus when the div is clicked, the action on that context is called.
39329    Because the `actionFunction` is just a function, closure actions can be
39330    passed between components and still execute in the correct context.
39331  
39332    Here is an example action handler on a component:
39333  
39334    ```js
39335    export default Ember.Component.extend({
39336      actions: {
39337        save() {
39338          this.get('model').save();
39339        }
39340      }
39341    });
39342    ```
39343  
39344    Actions are always looked up on the `actions` property of the current context.
39345    This avoids collisions in the naming of common actions, such as `destroy`.
39346  
39347    Two options can be passed to the `action` helper when it is used in this way.
39348  
39349    * `target=someProperty` will look to `someProperty` instead of the current
39350      context for the `actions` hash. This can be useful when targetting a
39351      service for actions.
39352    * `value="target.value"` will read the path `target.value` off the first
39353      argument to the action when it is called and rewrite the first argument
39354      to be that value. This is useful when attaching actions to event listeners.
39355  
39356    ### Invoking an action
39357  
39358    Closure actions curry both their scope and any arguments. When invoked, any
39359    additional arguments are added to the already curried list.
39360  
39361    Actions should be invoked using the [sendAction](/api/classes/Ember.Component.html#method_sendAction)
39362    method. The first argument to `sendAction` is the action to be called, and
39363    additional arguments are passed to the action function. This has interesting
39364    properties combined with currying of arguments. For example:
39365  
39366    ```js
39367    export default Ember.Component.extend({
39368      actions: {
39369        // Usage {{input on-input=(action (action 'setName' model) value="target.value")}}
39370        setName(model, name) {
39371          model.set('name', name);
39372        }
39373      }
39374    });
39375    ```
39376  
39377    The first argument (`model`) was curried over, and the run-time argument (`event`)
39378    becomes a second argument. Action calls can be nested this way because each simply
39379    returns a function. Any function can be passed to the `{{action}}` helper, including
39380    other actions.
39381  
39382    Actions invoked with `sendAction` have the same currying behavior as demonstrated
39383    with `on-input` above. For example:
39384  
39385    ```js
39386    export default Ember.Component.extend({
39387      actions: {
39388        setName(model, name) {
39389          model.set('name', name);
39390        }
39391      }
39392    });
39393    ```
39394  
39395    ```handlebars
39396    {{my-input submit=(action 'setName' model)}}
39397    ```
39398  
39399    ```js
39400    
39400// app/components/my-component.js
39401    export default Ember.Component.extend({
39402      click() {
39403        // Note that model is not passed, it was curried in the template
39404        this.sendAction('submit', 'bob');
39405      }
39406    });
39407    ```
39408  
39409    ### Attaching actions to DOM elements
39410  
39411    The third context of the `{{action}}` helper can be called "element space".
39412    For example:
39413  
39414    ```handlebars
39415    {{! An example of element space }}
39416    <div {{action "save"}}></div>
39417    ```
39418  
39419    Used this way, the `{{action}}` helper provides a useful shortcut for
39420    registering an HTML element in a template for a single DOM event and
39421    forwarding that interaction to the template's context (controller or component).
39422  
39423    If the context of a template is a controller, actions used this way will
39424    bubble to routes when the controller does not implement the specified action.
39425    Once an action hits a route, it will bubble through the route hierarchy.
39426  
39427    ### Event Propagation
39428  
39429    `{{action}}` helpers called in element space can control event bubbling. Note
39430    that the closure style actions cannot.
39431  
39432    Events triggered through the action helper will automatically have
39433    `.preventDefault()` called on them. You do not need to do so in your event
39434    handlers. If you need to allow event propagation (to handle file inputs for
39435    example) you can supply the `preventDefault=false` option to the `{{action}}` helper:
39436  
39437    ```handlebars
39438    <div {{action "sayHello" preventDefault=false}}>
39439      <input type="file" />
39440      <input type="checkbox" />
39441    </div>
39442    ```
39443  
39444    To disable bubbling, pass `bubbles=false` to the helper:
39445  
39446    ```handlebars
39447    <button {{action 'edit' post bubbles=false}}>Edit</button>
39448    ```
39449  
39450    To disable bubbling with closure style actions you must create your own
39451    wrapper helper that makes use of `event.stopPropagation()`:
39452  
39453    ```handlebars
39454    <div onclick={{disable-bubbling (action "sayHello")}}>Hello</div>
39455    ```
39456  
39457    ```js
39458    
39458// app/helpers/disable-bubbling.js
39459    import Ember from 'ember';
39460  
39461    export function disableBubbling([action]) {
39462      return function(event) {
39463        event.stopPropagation();
39464  
39465        return action(event);
39466      };
39467    }
39468  
39469    export default Ember.Helper.helper(disableBubbling);
39470    ```
39471  
39472    If you need the default handler to trigger you should either register your
39473    own event handler, or use event methods on your view class. See
39474    ["Responding to Browser Events"](/api/classes/Ember.View.html#toc_responding-to-browser-events)
39475    in the documentation for Ember.View for more information.
39476  
39477    ### Specifying DOM event type
39478  
39479    `{{action}}` helpers called in element space can specify an event type.
39480  
39481    By default the `{{action}}` helper registers for DOM `click` events. You can
39482    supply an `on` option to the helper to specify a different DOM event name:
39483  
39484    ```handlebars
39485    <div {{action "anActionName" on="doubleClick"}}>
39486      click me
39487    </div>
39488    ```
39489  
39490    See ["Event Names"](/api/classes/Ember.View.html#toc_event-names) for a list of
39491    acceptable DOM event names.
39492  
39493    ### Specifying whitelisted modifier keys
39494  
39495    `{{action}}
39495` helpers called in element space can specify modifier keys.
39496  
39497    By default the `{{action}}` helper will ignore click events with pressed modifier
39498    keys. You can supply an `allowedKeys` option to specify which keys should not be ignored.
39499  
39500    ```handlebars
39501    <div {{action "anActionName" allowedKeys="alt"}}>
39502      click me
39503    </div>
39504    ```
39505  
39506    This way the action will fire when clicking with the alt key pressed down.
39507  
39508    Alternatively, supply "any" to the `allowedKeys` option to accept any combination of modifier keys.
39509  
39510    ```handlebars
39511    <div {{action "anActionName" allowedKeys="any"}}>
39512      click me with any key pressed
39513    </div>
39514    ```
39515  
39516    ### Specifying a Target
39517  
39518    A `target` option can be provided to the helper to change
39519    which object will receive the method call. This option must be a path
39520    to an object, accessible in the current context:
39521  
39522    ```handlebars
39523    {{! app/templates/application.hbs }}
39524    <div {{action "anActionName" target=someService}}>
39525      click me
39526    </div>
39527    ```
39528  
39529    ```javascript
39530    
39530// app/controllers/application.js
39531    export default Ember.Controller.extend({
39532      someService: Ember.inject.service()
39533    });
39534    ```
39535  
39536    @method action
39537    @for Ember.Templates.helpers
39538    @public
39539  */
39540
39541  exports.default = function (morph, env, scope, params, hash, template, inverse, visitor) {
39542    if (morph) {
39543      _htmlbarsRuntimeHooks.keyword('@element_action', morph, env, scope, params, hash, template, inverse, visitor);
39544      return true;
39545    }
39546
39547    return _emberRoutingHtmlbarsKeywordsClosureAction.default(morph, env, scope, params, hash, template, inverse, visitor);
39548  };
39549});
39550enifed('ember-routing-htmlbars/keywords/closure-action', ['exports', 'ember-metal/streams/stream', 'ember-metal/streams/utils', 'ember-metal/symbol', 'ember-metal/property_get', 'ember-htmlbars/hooks/subexpr', 'ember-metal/error', 'ember-metal/run_loop'], function (exports, _emberMetalStreamsStream, _emberMetalStreamsUtils, _emberMetalSymbol, _emberMetalProperty_get, _emberHtmlbarsHooksSubexpr, _emberMetalError, _emberMetalRun_loop) {
39551  'use strict';
39552
39553  exports.default = closureAction;
39554  var INVOKE = _emberMetalSymbol.default('INVOKE');
39555  exports.INVOKE = INVOKE;
39556  var ACTION = _emberMetalSymbol.default('ACTION');
39557
39558  exports.ACTION = ACTION;
39559
39560  function closureAction(morph, env, scope, params, hash, template, inverse, visitor) {
39561    var s = new _emberMetalStreamsStream.Stream(function () {
39562      var rawAction = params[0];
39563      var actionArguments = _emberMetalStreamsUtils.readArray(params.slice(1, params.length));
39564
39565      var target, action, valuePath;
39566      if (rawAction[INVOKE]) {
39567        // on-change={{action (mut name)}}
39568        target = rawAction;
39569        action = rawAction[INVOKE];
39570      } else {
39571        // on-change={{action setName}}
39572        // element-space actions look to "controller" then target. Here we only
39573        // look to "target".
39574        target = _emberMetalStreamsUtils.read(scope.getSelf());
39575        action = _emberMetalStreamsUtils.read(rawAction);
39576        var actionType = typeof action;
39577
39578        if (actionType === 'string') {
39579          var actionName = action;
39580          action = null;
39581          // on-change={{action 'setName'}}
39582          if (hash.target) {
39583            // on-change={{action 'setName' target=alternativeComponent}}
39584            target = _emberMetalStreamsUtils.read(hash.target);
39585          }
39586          if (target.actions) {
39587            action = target.actions[actionName];
39588          }
39589
39590          if (!action) {
39591            throw new _emberMetalError.default('An action named \'' + actionName + '\' was not found in ' + target + '.');
39592          }
39593        } else if (action && typeof action[INVOKE] === 'function') {
39594          target = action;
39595          action = action[INVOKE];
39596        } else if (actionType !== 'function') {
39597          throw new _emberMetalError.default('An action could not be made for `' + rawAction.label + '` in ' + target + '. Please confirm that you are using either a quoted action name (i.e. `(action \'' + rawAction.label + '\')`) or a function available in ' + target + '.');
39598        }
39599      }
39600
39601      if (hash.value) {
39602        // <button on-keypress={{action (mut name) value="which"}}
39603        // on-keypress is not even an Ember feature yet
39604        valuePath = _emberMetalStreamsUtils.read(hash.value);
39605      }
39606
39607      return createClosureAction(target, action, valuePath, actionArguments);
39608    }, function () {
39609      return _emberHtmlbarsHooksSubexpr.labelForSubexpr(params, hash, 'action');
39610    });
39611
39612    params.forEach(s.addDependency, s);
39613    Object.keys(hash).forEach(function (item) {
39614      return s.addDependency(item);
39615    });
39616
39617    return s;
39618  }
39619
39620  function createClosureAction(target, action, valuePath, actionArguments) {
39621    var closureAction;
39622
39623    if (actionArguments.length > 0) {
39624      closureAction = function () {
39625        var args = actionArguments;
39626
39627        for (var _len = arguments.length, passedArguments = Array(_len), _key = 0; _key < _len; _key++) {
39628          passedArguments[_key] = arguments[_key];
39629        }
39630
39631        if (passedArguments.length > 0) {
39632          args = actionArguments.concat(passedArguments);
39633        }
39634        if (valuePath && args.length > 0) {
39635          args[0] = _emberMetalProperty_get.get(args[0], valuePath);
39636        }
39637
39638        return _emberMetalRun_loop.default.join.apply(_emberMetalRun_loop.default, [target, action].concat(args));
39639      };
39640    } else {
39641      closureAction = function () {
39642        for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
39643          args[_key2] = arguments[_key2];
39644        }
39645
39646        if (valuePath && args.length > 0) {
39647          args[0] = _emberMetalProperty_get.get(args[0], valuePath);
39648        }
39649
39650        return _emberMetalRun_loop.default.join.apply(_emberMetalRun_loop.default, [target, action].concat(args));
39651      };
39652    }
39653
39654    closureAction[ACTION] = true;
39655
39656    return closureAction;
39657  }
39658});
39659enifed('ember-routing-htmlbars/keywords/element-action', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/stream
39659s/utils', 'ember-metal/run_loop', 'ember-views/streams/utils', 'ember-views/system/utils', 'ember-views/system/action_manager'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberMetalStreamsUtils, _emberMetalRun_loop, _emberViewsStreamsUtils, _emberViewsSystemUtils, _emberViewsSystemAction_manager) {
39660  'use strict';
39661
39662  exports.default = {
39663    setupState: function (state, env, scope, params, hash) {
39664      var getStream = env.hooks.get;
39665      var read = env.hooks.getValue;
39666
39667      var actionName = read(params[0]);
39668
39669      _emberMetalDebug.assert('You specified a quoteless path to the {{action}} helper ' + 'which did not resolve to an action name (a string). ' + 'Perhaps you meant to use a quoted actionName? (e.g. {{action \'save\'}}).', typeof actionName === 'string' || typeof actionName === 'function');
39670
39671      var actionArgs = [];
39672      for (var i = 1, l = params.length; i < l; i++) {
39673        actionArgs.push(_emberViewsStreamsUtils.readUnwrappedModel(params[i]));
39674      }
39675
39676      var target;
39677      if (hash.target) {
39678        if (typeof hash.target === 'string') {
39679          target = read(getStream(env, scope, hash.target));
39680        } else {
39681          target = read(hash.target);
39682        }
39683      } else {
39684        target = read(scope.getLocal('controller')) || read(scope.getSelf());
39685      }
39686
39687      return { actionName: actionName, actionArgs: actionArgs, target: target };
39688    },
39689
39690    isStable: function (state, env, scope, params, hash) {
39691      return true;
39692    },
39693
39694    render: function (node, env, scope, params, hash, template, inverse, visitor) {
39695      var actionId = env.dom.getAttribute(node.element, 'data-ember-action') || _emberMetalUtils.uuid();
39696
39697      ActionHelper.registerAction({
39698        actionId: actionId,
39699        node: node,
39700        eventName: hash.on || 'click',
39701        bubbles: hash.bubbles,
39702        preventDefault: hash.preventDefault,
39703        withKeyCode: hash.withKeyCode,
39704        allowedKeys: hash.allowedKeys
39705      });
39706
39707      node.cleanup = function () {
39708        ActionHelper.unregisterAction(actionId);
39709      };
39710
39711      env.dom.setAttribute(node.element, 'data-ember-action', actionId);
39712    }
39713  };
39714  var ActionHelper = {};
39715
39716  exports.ActionHelper = ActionHelper;
39717  // registeredActions is re-exported for compatibility with older plugins
39718  // that were using this undocumented API.
39719  ActionHelper.registeredActions = _emberViewsSystemAction_manager.default.registeredActions;
39720
39721  ActionHelper.registerAction = function (_ref) {
39722    var actionId = _ref.actionId;
39723    var node = _ref.node;
39724    var eventName = _ref.eventName;
39725    var preventDefault = _ref.preventDefault;
39726    var bubbles = _ref.bubbles;
39727    var allowedKeys = _ref.allowedKeys;
39728
39729    var actions = _emberViewsSystemAction_manager.default.registeredActions[actionId];
39730
39731    if (!actions) {
39732      actions = _emberViewsSystemAction_manager.default.registeredActions[actionId] = [];
39733    }
39734
39735    actions.push({
39736      eventName: eventName,
39737      handler: function (event) {
39738        if (!isAllowedEvent(event, _emberMetalStreamsUtils.read(allowedKeys))) {
39739          return true;
39740        }
39741
39742        if (_emberMetalStreamsUtils.read(preventDefault) !== false) {
39743          event.preventDefault();
39744        }
39745
39746        if (_emberMetalStreamsUtils.read(bubbles) === false) {
39747          event.stopPropagation();
39748        }
39749
39750        var _node$getState = node.getState();
39751
39752        var target = _node$getState.target;
39753        var actionName = _node$getState.actionName;
39754        var actionArgs = _node$getState.actionArgs;
39755
39756        _emberMetalRun_loop.default(function runRegisteredAction() {
39757          if (typeof actionName === 'function') {
39758            actionName.apply(target, actionArgs);
39759            return;
39760          }
39761          if (target.send) {
39762            target.send.apply(target, [actionName].concat(actionArgs));
39763          } else {
39764            _emberMetalDebug.assert('The action \'' + actionName + '\' did not exist on ' + target, typeof target[actionName] === 'function');
39765
39766            target[actionName].apply(target, actionArgs);
39767          }
39768        });
39769      }
39770    });
39771
39772    return actionId;
39773  };
39774
39775  ActionHelper.unregisterAction = function (actionId) {
39776    delete _emberViewsSystemAction_manager.default.registeredActions[actionId];
39777  };
39778
39779  var MODIFIERS = ['alt', 'shift', 'meta', 'ctrl'];
39780  var POINTER_EVENT_TYPE_REGEX = /^click|mouse|touch/;
39781
39782  function isAllowedEvent(event, allowedKeys) {
39783    if (typeof allowedKeys === 'undefined') {
39784      if (POINTER_EVENT_TYPE_REGEX.test(event.type)) {
39785        return _emberViewsSystemUtils.isSimpleClick(event);
39786      } else {
39787        allowedKeys = '';
39788      }
39789    }
39790
39791    if (allowedKeys.indexOf('any') >= 0) {
39792      return true;
39793    }
39794
39795    for (var i = 0, l = MODIFIERS.length; i < l; i++) {
39796      if (event[MODIFIERS[i] + 'Key'] && allowedKeys.indexOf(MODIFIERS[i]) === -1) {
39797        return false;
39798      }
39799    }
39800
39801    return true;
39802  }
39803});
39804enifed('ember-routing-htmlbars/keywords/render', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/empty_object', 'ember-metal/error', 'ember-metal/streams/utils', 'ember-runtime/system/string', 'ember-routing/system/generate_controller', 'ember-htmlbars/node-managers/view-node-manager'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalEmpty_object, _emberMetalError, _emberMetalStreamsUtils, _emberRuntimeSystemString, _emberRoutingSystemGenerate_controller, _emberHtmlbarsNodeManagersViewNodeManager) {
39805  /**
39806  @module ember
39807  @submodule ember-templates
39808  */
39809
39810  'use strict';
39811
39812  /**
39813    Calling ``{{render}}`` from within a template will insert another
39814    template that matches the provided name. The inserted template will
39815    access its properties on its own controller (rather than the controller
39816    of the parent template).
39817    If a view class with the same name exists, the view class also will be used.
39818    Note: A given controller may only be used *once* in your app in this manner.
39819    A singleton instance of the controller will be created for you.
39820    Example:
39821  
39822    ```javascript
39823    App.NavigationController = Ember.Controller.extend({
39824      who: "world"
39825    });
39826    ```
39827  
39828    ```handlebars
39829    <!-- navigation.hbs -->
39830    Hello, {{who}}.
39831    ```
39832  
39833    ```handlebars
39834    <!-- application.hbs -->
39835    <h1>My great app</h1>
39836    {{render "navigation"}}
39837    ```
39838  
39839    ```html
39840    <h1>My great app</h1>
39841    <div class='ember-view'>
39842      Hello, world.
39843    </div>
39844    ```
39845  
39846    Optionally you may provide a second argument: a property path
39847    that will be bound to the `model` property of the controller.
39848    If a `model` property path is specified, then a new instance of the
39849    controller will be created and `{{render}}` can be used multiple times
39850    with the same name.
39851  
39852    For example if you had this `author` template.
39853  
39854    ```handlebars
39855    <div class="author">
39856      Written by {{firstName}} {{lastName}}.
39857      Total Posts: {{postCount}}
39858    </div>
39859    ```
39860  
39861    You could render it inside the `post` template using the `render` helper.
39862  
39863    ```handlebars
39864    <div class="post">
39865      <h1>{{title}}</h1>
39866      <div>{{body}}</div>
39867      {{render "author" author}}
39868    </div>
39869    ```
39870  
39871    @method render
39872    @for Ember.Templates.helpers
39873    @param {String} name
39874    @param {Object?} context
39875    @param {Hash} options
39876    @return {String} HTML string
39877    @public
39878  */
39879  exports.default = {
39880    willRender: function (renderNode, env) {
39881      if (env.view.ownerView._outlets) {
39882        // We make sure we will get dirtied when outlet state changes.
39883        env.view.ownerView._outlets.push(renderNode);
39884      }
39885    },
39886
39887    setupState: function (prevState, env, scope, params, hash) {
39888      var name = params[0];
39889
39890      _emberMetalDebug.assert('The first argument of {{render}} must be quoted, e.g. {{render "sidebar"}}.', typeof name === 'string');
39891
39892      return {
39893        parentView: env.view,
39894        manager: prevState.manager,
39895        controller: prevState.controller,
39896        childOutletState: childOutletState(name, env)
39897      };
39898    },
39899
39900    childEnv: function (state, env) {
39901      return env.childWithOutletState(state.childOutletState);
39902    },
39903
39904    isStable: function (lastState, nextState) {
39905      return isStable(lastState.childOutletState, nextState.childOutletState);
39906    },
39907
39908    isEmpty: function (state) {
39909      return false;
39910    },
39911
39912    render: function (node, env, scope, params, hash, template, inverse, visitor) {
39913      var state = node.getState();
39914      var name = params[0];
39915      var context = params[1];
39916
39917      var owner = env.owner;
39918
39919      // The render keyword presumes it can work without a router. This is really
39920      // only to satisfy the test:
39921      //
39922      //     {{view}} should not override class bindings defined on a child view"
39923      //
39924      var router = owner.lookup('router:main');
39925
39926      _emberMetalDebug.assert('The second argument of {{render}} must be a path, e.g. {{render "post" post}}.', params.length < 2 || _emberMetalStreamsUtils.isStream(params[1]));
39927
39928      if (params.length === 1) {
39929        // use the singleton controller
39930        _emberMetalDebug.assert('You can only use the {{render}} helper once without a model object as ' + 'its second argument, as in {{render "post" post}}.', !router || !router._lookupActiveComponentNode(name));
39931      } else if (params.length !== 2) {
39932        throw new _emberMetalError.default('You must pass a templateName to render');
39933      }
39934
39935      var templateName = 'template:' + name;
39936      _emberMetalDebug.assert('You used `{{render \'' + name + '\'}}`, but \'' + name + '\' can not be ' + 'found as either a template or a view.', owner.hasRegistration('view:' + name) || owner.hasRegistration(templateName) || !!template);
39937
39938      var view = owner.lookup('view:' + name);
39939      if (!view) {
39940        view = owner.lookup('view:default');
39941      }
39942      var viewHasTemplateSpecified = view && !!_emberMetalProperty_get.get(view, 'template');
39943      if (!template && !viewHasTemplateSpecified) {
39944        template = owner.lookup(templateName);
39945      }
39946
39947      if (view) {
39948        view.ownerView = env.view.ownerView;
39949      }
39950
39951      // provide controller override
39952      var controllerName;
39953      var controllerFullName;
39954
39955      if (hash.controller) {
39956        controllerName = hash.controller;
39957        controllerFullName = 'controller:' + controllerName;
39958        delete hash.controller;
39959
39960        _emberMetalDebug.assert('The controller name you supplied \'' + controllerName + '\' ' + 'did not resolve to a controller.', owner.hasRegistration(controllerFullName));
39961      } else {
39962        controllerName = name;
39963        controllerFullName = 'controller:' + controllerName;
39964      }
39965
39966      var parentController = _emberMetalStreamsUtils.read(scope.getLocal('controller'));
39967      var target = parentController || router;
39968      var controller;
39969
39970      // choose name
39971      if (params.length > 1) {
39972        var factory = owner._lookupFactory(controllerFullName) || _emberRoutingSystemGenerate_controller.generateControllerFactory(owner, controllerName);
39973
39974        controller = factory.create({
39975          model: _emberMetalStreamsUtils.read(context),
39976          parentController: parentController,
39977          target: target
39978        });
39979
39980        node.addDestruction(controller);
39981      } else {
39982        controller = owner.lookup(controllerFullName) || _emberRoutingSystemGenerate_controller.default(owner, controllerName);
39983
39984        controller.setProperties({
39985          target: target,
39986          parentController: parentController
39987        });
39988      }
39989
39990      if (view) {
39991        view.set('controller', controller);
39992      }
39993      state.controller = controller;
39994
39995      hash.viewName = _emberRuntimeSystemString.camelize(name);
39996
39997      if (template && template.raw) {
39998        template = template.raw;
39999      }
40000
40001      var options = {
40002        layout: null,
40003        self: controller
40004      };
40005
40006      if (view) {
40007        options.component = view;
40008      }
40009
40010      var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(node, env, hash, options, state.parentView, null, null, template);
40011      state.manager = nodeManager;
40012
40013      if (router && params.length === 1) {
40014        router._connectActiveComponentNode(name, nodeManager);
40015      }
40016
40017      nodeManager.render(env, hash, visitor);
40018    },
40019
40020    rerender: function (node, env, scope, params, hash, template, inverse, visitor) {
40021      if (params.length > 1) {
40022        var model = _emberMetalStreamsUtils.read(params[1]);
40023        node.getState().controller.set('model', model);
40024      }
40025    }
40026  };
40027
40028  function childOutletState(name, env) {
40029    var topLevel = env.view.ownerView;
40030    if (!topLevel || !topLevel.outletState) {
40031      return;
40032    }
40033
40034    var outletState = topLevel.outletState;
40035    if (!outletState.main) {
40036      return;
40037    }
40038
40039    var selectedOutletState = outletState.main.outlets['__ember_orphans__'];
40040    if (!selectedOutletState) {
40041      return;
40042    }
40043    var matched = selectedOutletState.outlets[name];
40044    if (matched) {
40045      var childState = new _emberMetalEmpty_object.default();
40046      childState[matched.render.outlet] = matched;
40047      matched.wasUsed = true;
40048      return childState;
40049    }
40050  }
40051
40052  function isStable(a, b) {
40053    if (!a && !b) {
40054      return true;
40055    }
40056    if (!a || !b) {
40057      return false;
40058    }
40059    for (var outletName in a) {
40060      if (!isStableOutlet(a[outletName], b[outletName])) {
40061        return false;
40062      }
40063    }
40064    return true;
40065  }
40066
40067  function isStableOutlet(a, b) {
40068    if (!a && !b) {
40069      return true;
40070    }
40071    if (!a || !b) {
40072      return false;
40073    }
40074    a = a.render;
40075    b = b.render;
40076    for (var key in a) {
40077      if (a.hasOwnProperty(key)) {
40078        // name is only here for logging & debugging. If two different
40079        // names result in otherwise identical states, they're still
40080        // identical.
40081        if (a[key] !== b[key] && key !== 'name') {
40082          return false;
40083        }
40084      }
40085    }
40086    return true;
40087  }
40088});
40089enifed('ember-routing-views/components/link-to', ['exports', 'ember-metal/logger', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/computed', 'ember-metal/computed_macros', 'ember-views/system/utils', 'ember-views/components/component', 'ember-runtime/inject', 'ember-runtime/system/service', 'ember-runtime/mixins/controller', 'ember-htmlbars/node-managers/component-node-manager', 'ember-htmlbars/templates/link-to'], function (exports, _emberMetalLogger, _emberMetalDebug, _emberMetalProperty_get, _emberMetalComputed, _emberMetalComputed_macros, _emberViewsSystemUtils, _emberViewsComponentsComponent, _emberRuntimeInject, _emberRuntimeSystemService, _emberRuntimeMixinsController, _emberHtmlbarsNodeManagersComponentNodeManager, _emberHtmlbarsTemplatesLinkTo) {
40090  /**
40091  @module ember
40092  @submodule ember-templates
40093  */
40094
40095  /**
40096    The `{{link-to}}` component renders a link to the supplied
40097    `routeName` passing an optionally supplied model to the
40098    route as its `model` context of the route. The block
40099    for `{{link-to}}` becomes the innerHTML of the rendered
40100    element:
40101  
40102    ```handlebars
40103    {{#link-to 'photoGallery'}}
40104      Great Hamster Photos
40105    {{/link-to}}
40106    ```
40107  
40108    You can also use an inline form of `{{link-to}}` component by
40109    passing the link text as the first argument
40110    to the component:
40111  
40112    ```handlebars
40113    {{link-to 'Great Hamster Photos' 'photoGallery'}}
40114    ```
40115  
40116    Both will result in:
40117  
40118    ```html
40119    <a href="/hamster-photos">
40120      Great Hamster Photos
40121    </a>
40122    ```
40123  
40124    ### Supplying a tagName
40125    By default `{{link-to}}` renders an `<a>` element. This can
40126    be overridden for a single use of `{{link-to}}` by supplying
40127    a `tagName` option:
40128  
40129    ```handlebars
40130    {{#link-to 'photoGallery' tagName="li"}}
40131      Great Hamster Photos
40132    {{/link-to}}
40133    ```
40134  
40135    ```html
40136    <li>
40137      Great Hamster Photos
40138    </li>
40139    ```
40140  
40141    To override this option for your entire application, see
40142    "Overriding Application-wide Defaults".
40143  
40144    ### Disabling the `link-to` component
40145    By default `{{link-to}}` is enabled.
40146    any passed value to the `disabled` component property will disable
40147    the `link-to` component.
40148  
40149    static use: the `disabled` option:
40150  
40151    ```handlebars
40152    {{#link-to 'photoGallery' disabled=true}}
40153      Great Hamster Photos
40154    {{/link-to}}
40155    ```
40156  
40157    dynamic use: the `disabledWhen` option:
40158  
40159    ```handlebars
40160    {{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
40161      Great Hamster Photos
40162    {{/link-to}}
40163    ```
40164  
40165    any passed value to `disabled` will disable it except `undefined`.
40166    to ensure that only `true` disable the `link-to` component you can
40167    override the global behaviour of `Ember.LinkComponent`.
40168  
40169    ```javascript
40170    Ember.LinkComponent.reopen({
40171      disabled: Ember.computed(function(key, value) {
40172        if (value !== undefined) {
40173          this.set('_isDisabled', value === true);
40174        }
40175        return value === true ? get(this, 'disabledClass') : false;
40176      })
40177    });
40178    ```
40179  
40180    see "Overriding Application-wide Defaults" for more.
40181  
40182    ### Handling `href`
40183    `{{link-to}}` will use your application's Router to
40184    fill the element's `href` property with a url that
40185    matches the path to the supplied `routeName` for your
40186    router's configured `Location` scheme, which defaults
40187    to Ember.HashLocation.
40188  
40189    ### Handling current route
40190    `{{link-to}}` will apply a CSS class name of 'active'
40191    when the application's current route matches
40192    the supplied routeName. For example, if the application's
40193    current route is 'photoGallery.recent' the following
40194    use of `{{link-to}}`:
40195  
40196    ```handlebars
40197    {{#link-to 'photoGallery.recent'}}
40198      Great Hamster Photos
40199    {{/link-to}}
40200    ```
40201  
40202    will result in
40203  
40204    ```html
40205    <a href="/hamster-photos/this-week" class="active">
40206      Great Hamster Photos
40207    </a>
40208    ```
40209  
40210    The CSS class name used for active classes can be customized
40211    for a single use of `{{link-to}}` by passing an `activeClass`
40212    option:
40213  
40214    ```handlebars
40215    {{#link-to 'photoGallery.recent' activeClass="current-url"}}
40216      Great Hamster Photos
40217    {{/link-to}}
40218    ```
40219  
40220    ```html
40221    <a href="/hamster-photos/this-week" class="current-url">
40222      Great Hamster Photos
40223    </a>
40224    ```
40225  
40226    To override this option for your entire application, see
40227    "Overriding Application-wide Defaults".
40228  
40229    ### Keeping a link active for other routes
40230  
40231    If you need a link to be 'active' even when it doesn't match
40232    the current route, you can use the `current-when` argument.
40233  
40234    ```handlebars
40235    {{#link-to 'photoGallery' current-when='photos'}}
40236      Photo Gallery
40237    {{/link-to}}
40238    ```
40239  
40240    This may be helpful for keeping links active for:
40241  
40242    * non-nested routes that are logically related
40243    * some secondary menu approaches
40244    * 'top navigation' with 'sub navigation' scenarios
40245  
40246    A link will be active if `current-when` is `true` or the current
40247    route is the route this link would transition to.
40248  
40249    To match multiple routes 'space-separate' the routes:
40250  
40251    ```handlebars
40252    {{#link-to 'gallery' current-when='photos drawings paintings'}}
40253      Art Gallery
40254    {{/link-to}}
40255    ```
40256  
40257    ### Supplying a model
40258    An optional model argument can be used for routes whose
40259    paths contain dynamic segments. This argument will become
40260    the model context of the linked route:
40261  
40262    ```javascript
40263    Router.map(function() {
40264      this.route("photoGallery", {path: "hamster-photos/:photo_id"});
40265    });
40266    ```
40267  
40268    ```handlebars
40269    {{#link-to 'photoGallery' aPhoto}}
40270      {{aPhoto.title}}
40271    {{/link-to}}
40272    ```
40273  
40274    ```html
40275    <a href="/hamster-photos/42">
40276      Tomster
40277    </a>
40278    ```
40279  
40280    ### Supplying multiple models
40281    For deep-linking to route paths that contain multiple
40282    dynamic segments, multiple model arguments can be used.
40283    As the router transitions through the route path, each
40284    supplied model argument will become the context for the
40285    route with the dynamic segments:
40286  
40287    ```javascript
40288    Router.map(function() {
40289      this.route("photoGallery", { path: "hamster-photos/:photo_id" }, function() {
40290        this.route("comment", {path: "comments/:comment_id"});
40291      });
40292    });
40293    ```
40294    This argument will become the model context of the linked route:
40295  
40296    ```handlebars
40297    {{#link-to 'photoGallery.comment' aPhoto comment}}
40298      {{comment.body}}
40299    {{/link-to}}
40300    ```
40301  
40302    ```html
40303    <a href="/hamster-photos/42/comments/718">
40304      A+++ would snuggle again.
40305    </a>
40306    ```
40307  
40308    ### Supplying an explicit dynamic segment value
40309    If you don't have a model object available to pass to `{{link-to}}`,
40310    an optional string or integer argument can be passed for routes whose
40311    paths contain dynamic segments. This argument will become the value
40312    of the dynamic segment:
40313  
40314    ```javascript
40315    Router.map(function() {
40316      this.route("photoGallery", { path: "hamster-photos/:photo_id" });
40317    });
40318    ```
40319  
40320    ```handlebars
40321    {{#link-to 'photoGallery' aPhotoId}}
40322      {{aPhoto.title}}
40323    {{/link-to}}
40324    ```
40325  
40326    ```html
40327    <a href="/hamster-photos/42">
40328      Tomster
40329    </a>
40330    ```
40331  
40332    When transitioning into the linked route, the `model` hook will
40333    be triggered with parameters including this passed identifier.
40334  
40335    ### Allowing Default Action
40336  
40337   By default the `{{link-to}}` component prevents the default browser action
40338   by calling `preventDefault()` as this sort of action bubbling is normally
40339   handled internally and we do not want to take the browser to a new URL (for
40340   example).
40341  
40342   If you need to override this behavior specify `preventDefault=false` in
40343   your template:
40344  
40345    ```handlebars
40346    {{#link-to 'photoGallery' aPhotoId preventDefault=false}}
40347      {{aPhotoId.title}}
40348    {{/link-to}}
40349    ```
40350  
40351    ### Overriding attributes
40352    You can override any given property of the `Ember.LinkComponent`
40353    that is generated by the `{{link-to}}` component by passing
40354    key/value pairs, like so:
40355  
40356    ```handlebars
40357    {{#link-to  aPhoto tagName='li' title='Following this link will change your life' classNames='pic sweet'}}
40358      Uh-mazing!
40359    {{/link-to}}
40360    ```
40361  
40362    See [Ember.LinkComponent](/api/classes/Ember.LinkComponent.html) for a
40363    complete list of overrideable properties. Be sure to also
40364    check out inherited properties of `LinkComponent`.
40365  
40366    ### Overriding Application-wide Defaults
40367    ``{{link-to}}`` creates an instance of `Ember.LinkComponent`
40368    for rendering. To override options for your entire
40369    application, reopen `Ember.LinkComponent` and supply the
40370    desired values:
40371  
40372    ``` javascript
40373    Ember.LinkComponent.reopen({
40374      activeClass: "is-active",
40375      tagName: 'li'
40376    })
40377    ```
40378  
40379    It is also possible to override the default event in
40380    this manner:
40381  
40382    ``` javascript
40383    Ember.LinkComponent.reopen({
40384      eventName: 'customEventName'
40385    });
40386    ```
40387  
40388    @method link-to
40389    @for Ember.Templates.helpers
40390    @param {String} routeName
40391    @param {Object} [context]*
40392    @param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkComponent
40393    @return {String} HTML string
40394    @see {Ember.LinkComponent}
40395    @public
40396  */
40397
40398  /**
40399  @module ember
40400  @submodule ember-routing-views
40401  */
40402
40403  'use strict';
40404
40405  _emberHtmlbarsTemplatesLinkTo.default.meta.revision = '[email protected]';
40406
40407  /**
40408    `Ember.LinkComponent` renders an element whose `click` event triggers a
40409    transition of the application's instance of `Ember.Router` to
40410    a supplied route by name.
40411  
40412    `Ember.LinkComponent` components are invoked with {{#link-to}}. Properties
40413    of this class can be overridden with `reopen` to customize application-wide
40414    behavior.
40415  
40416    @class LinkComponent
40417    @namespace Ember
40418    @extends Ember.Component
40419    @see {Ember.Templates.helpers.link-to}
40420    @private
40421  **/
40422  var LinkComponent = _emberViewsComponentsComponent.default.extend({
40423    layout: _emberHtmlbarsTemplatesLinkTo.default,
40424
40425    tagName: 'a',
40426
40427    /**
40428      @deprecated Use current-when instead.
40429      @property currentWhen
40430      @private
40431    */
40432    currentWhen: _emberMetalComputed_macros.deprecatingAlias('current-when', { id: 'ember-routing-view.deprecated-current-when', until: '3.0.0' }),
40433
40434    /**
40435      Used to determine when this `LinkComponent` is active.
40436       @property currentWhen
40437      @public
40438    */
40439    'current-when': null,
40440
40441    /**
40442      Sets the `title` attribute of the `LinkComponent`'s HTML element.
40443       @property title
40444      @default null
40445      @public
40446    **/
40447    title: null,
40448
40449    /**
40450      Sets the `rel` attribute of the `LinkComponent`'s HTML element.
40451       @property rel
40452      @default null
40453      @public
40454    **/
40455    rel: null,
40456
40457    /**
40458      Sets the `tabindex` attribute of the `LinkComponent`'s HTML element.
40459       @property tabindex
40460      @default null
40461      @public
40462    **/
40463    tabindex: null,
40464
40465    /**
40466      Sets the `target` attribute of the `LinkComponent`'s HTML element.
40467       @since 1.8.0
40468      @property target
40469      @default null
40470      @public
40471    **/
40472    target: null,
40473
40474    /**
40475      The CSS class to apply to `LinkComponent`'s element when its `active`
40476      property is `true`.
40477       @property activeClass
40478      @type String
40479      @default active
40480      @private
40481    **/
40482    activeClass: 'active',
40483
40484    /**
40485      The CSS class to apply to `LinkComponent`'s element when its `loading`
40486      property is `true`.
40487       @property loadingClass
40488      @type String
40489      @default loading
40490      @private
40491    **/
40492    loadingClass: 'loading',
40493
40494    /**
40495      The CSS class to apply to a `LinkComponent`'s element when its `disabled`
40496      property is `true`.
40497       @property disabledClass
40498      @type String
40499      @default disabled
40500      @private
40501    **/
40502    disabledClass: 'disabled',
40503    _isDisabled: false,
40504
40505    /**
40506      Determines whether the `LinkComponent` will trigger routing via
40507      the `replaceWith` routing strategy.
40508       @property replace
40509      @type Boolean
40510      @default false
40511      @public
40512    **/
40513    replace: false,
40514
40515    /**
40516      By default the `{{link-to}}` component will bind to the `href` and
40517      `title` attributes. It's discouraged that you override these defaults,
40518      however you can push onto the array if needed.
40519       @property attributeBindings
40520      @type Array | String
40521      @default ['title', 'rel', 'tabindex', 'target']
40522      @public
40523    */
40524    attributeBindings: ['href', 'title', 'rel', 'tabindex', 'target'],
40525
40526    /**
40527      By default the `{{link-to}}` component will bind to the `active`, `loading`,
40528      and `disabled` classes. It is discouraged to override these directly.
40529       @property classNameBindings
40530      @type Array
40531      @default ['active', 'loading', 'disabled', 'ember-transitioning-in', 'ember-transitioning-out']
40532      @public
40533    */
40534    classNameBindings: ['active', 'loading', 'disabled', 'transitioningIn', 'transitioningOut'],
40535
40536    /**
40537      By default the `{{link-to}}` component responds to the `click` event. You
40538      can override this globally by setting this property to your custom
40539      event name.
40540       This is particularly useful on mobile when one wants to avoid the 300ms
40541      click delay using some sort of custom `tap` event.
40542       @property eventName
40543      @type String
40544      @default click
40545      @private
40546    */
40547    eventName: 'click',
40548
40549    // this is doc'ed here so it shows up in the events
40550    // section of the API documentation, which is where
40551    // people will likely go looking for it.
40552    /**
40553      Triggers the `LinkComponent`'s routing behavior. If
40554      `eventName` is changed to a value other than `click`
40555      the routing behavior will trigger on that custom event
40556      instead.
40557       @event click
40558      @private
40559    */
40560
40561    /**
40562      An overridable method called when `LinkComponent` objects are instantiated.
40563       Example:
40564       ```javascript
40565      App.MyLinkComponent = Ember.LinkComponent.extend({
40566        init: function() {
40567          this._super(...arguments);
40568          Ember.Logger.log('Event is ' + this.get('eventName'));
40569        }
40570      });
40571      ```
40572       NOTE: If you do override `init` for a framework class like `Ember.View`,
40573      be sure to call `this._super(...arguments)` in your
40574      `init` declaration! If you don't, Ember may not have an opportunity to
40575      do important setup work, and you'll see strange behavior in your
40576      application.
40577       @method init
40578      @private
40579    */
40580    init: function () {
40581      this._super.apply(this, arguments);
40582
40583      // Map desired event name to invoke function
40584      var eventName = _emberMetalProperty_get.get(this, 'eventName');
40585      this.on(eventName, this, this._invoke);
40586    },
40587
40588    _routing: _emberRuntimeInject.default.service('-routing'),
40589
40590    /**
40591      Accessed as a classname binding to apply the `LinkComponent`'s `disabledClass`
40592      CSS `class` to the element when the link is disabled.
40593       When `true` interactions with the element will not trigger route changes.
40594      @property disabled
40595      @private
40596    */
40597    disabled: _emberMetalComputed.computed({
40598      get: function (key, value) {
40599        return false;
40600      },
40601      set: function (key, value) {
40602        if (value !== undefined) {
40603          this.set('_isDisabled', value);
40604        }
40605
40606        return value ? _emberMetalProperty_get.get(this, 'disabledClass') : false;
40607      }
40608    }),
40609
40610    _computeActive: function (routerState) {
40611      if (_emberMetalProperty_get.get(this, 'loading')) {
40612        return false;
40613      }
40614
40615      var routing = _emberMetalProperty_get.get(this, '_routing');
40616      var models = _emberMetalProperty_get.get(this, 'models');
40617      var resolvedQueryParams = _emberMetalProperty_get.get(this, 'resolvedQueryParams');
40618
40619      var currentWhen = _emberMetalProperty_get.get(this, 'current-when');
40620      var isCurrentWhenSpecified = !!currentWhen;
40621      currentWhen = currentWhen || _emberMetalProperty_get.get(this, 'qualifiedRouteName');
40622      currentWhen = currentWhen.split(' ');
40623
40624      for (var i = 0, len = currentWhen.length; i < len; i++) {
40625        if (routing.isActiveForRoute(models, resolvedQueryParams, currentWhen[i], routerState, isCurrentWhenSpecified)) {
40626          return _emberMetalProperty_get.get(this, 'activeClass');
40627        }
40628      }
40629
40630      return false;
40631    },
40632
40633    /**
40634      Accessed as a classname binding to apply the `LinkComponent`'s `activeClass`
40635      CSS `class` to the element when the link is active.
40636       A `LinkComponent` is considered active when its `currentWhen` property is `true`
40637      or the application's current route is the route the `LinkComponent` would trigger
40638      transitions into.
40639       The `currentWhen` property can match against multiple routes by separating
40640      route names using the ` ` (space) character.
40641       @property active
40642      @private
40643    */
40644    active: _emberMetalComputed.computed('attrs.params', '_routing.currentState', function computeLinkToComponentActive() {
40645      var currentState = _emberMetalProperty_get.get(this, '_routing.currentState');
40646      if (!currentState) {
40647        return false;
40648      }
40649
40650      return this._computeActive(currentState);
40651    }),
40652
40653    willBeActive: _emberMetalComputed.computed('_routing.targetState', function computeLinkToComponentWillBeActive() {
40654      var routing = _emberMetalProperty_get.get(this, '_routing');
40655      var targetState = _emberMetalProperty_get.get(routing, 'targetState');
40656      if (_emberMetalProperty_get.get(routing, 'currentState') === targetState) {
40657        return;
40658      }
40659
40660      return !!this._computeActive(targetState);
40661    }),
40662
40663    transitioningIn: _emberMetalComputed.computed('active', 'willBeActive', function computeLinkToComponentTransitioningIn() {
40664      var willBeActive = _emberMetalProperty_get.get(this, 'willBeActive');
40665      if (typeof willBeActive === 'undefined') {
40666        return false;
40667      }
40668
40669      return !_emberMetalProperty_get.get(this, 'active') && willBeActive && 'ember-transitioning-in';
40670    }),
40671
40672    transitioningOut: _emberMetalComputed.computed('active', 'willBeActive', function computeLinkToComponentTransitioningOut() {
40673      var willBeActive = _emberMetalProperty_get.get(this, 'willBeActive');
40674      if (typeof willBeActive === 'undefined') {
40675        return false;
40676      }
40677
40678      return _emberMetalProperty_get.get(this, 'active') && !willBeActive && 'ember-transitioning-out';
40679    }),
40680
40681    /**
40682      Event handler that invokes the link, activating the associated route.
40683       @private
40684      @method _invoke
40685      @param {Event} event
40686      @private
40687    */
40688    _invoke: function (event) {
40689      if (!_emberViewsSystemUtils.isSimpleClick(event)) {
40690        return true;
40691      }
40692
40693      var preventDefault = _emberMetalProperty_get.get(this, 'preventDefault');
40694      var targetAttribute = _emberMetalProperty_get.get(this, 'target');
40695
40696      if (preventDefault !== false) {
40697        if (!targetAttribute || targetAttribute === '_self') {
40698          event.preventDefault();
40699        }
40700      }
40701
40702      if (_emberMetalProperty_get.get(this, 'bubbles') === false) {
40703        event.stopPropagation();
40704      }
40705
40706      if (_emberMetalProperty_get.get(this, '_isDisabled')) {
40707        return false;
40708      }
40709
40710      if (_emberMetalProperty_get.get(this, 'loading')) {
40711        _emberMetalLogger.default.warn('This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.');
40712        return false;
40713      }
40714
40715      if (targetAttribute && targetAttribute !== '_self') {
40716        return false;
40717      }
40718
40719      var routing = _emberMetalProperty_get.get(this, '_routing');
40720      var qualifiedRouteName = _emberMetalProperty_get.get(this, 'qualifiedRouteName');
40721      var models = _emberMetalProperty_get.get(this, 'models');
40722      var queryParamValues = _emberMetalProperty_get.get(this, 'queryParams.values');
40723      var shouldReplace = _emberMetalProperty_get.get(this, 'replace');
40724
40725      routing.transitionTo(qualifiedRouteName, models, queryParamValues, shouldReplace);
40726    },
40727
40728    queryParams: null,
40729
40730    qualifiedRouteName: _emberMetalComputed.computed('targetRouteName', '_routing.currentState', function computeLinkToComponentQualifiedRouteName() {
40731      var params = _emberMetalProperty_get.get(this, 'params').slice();
40732      var lastParam = params[params.length - 1];
40733      if (lastParam && lastParam.isQueryParams) {
40734        params.pop();
40735      }
40736      var onlyQueryParamsSupplied = this[_emberHtmlbarsNodeManagersComponentNodeManager.HAS_BLOCK] ? params.length === 0 : params.length === 1;
40737      if (onlyQueryParamsSupplied) {
40738        return _emberMetalProperty_get.get(this, '_routing.currentRouteName');
40739      }
40740      return _emberMetalProperty_get.get(this, 'targetRouteName');
40741    }),
40742
40743    resolvedQueryParams: _emberMetalComputed.computed('queryParams', function computeLinkToComponentResolvedQueryParams() {
40744      var resolvedQueryParams = {};
40745      var queryParams = _emberMetalProperty_get.get(this, 'queryParams');
40746
40747      if (!queryParams) {
40748        return resolvedQueryParams;
40749      }
40750
40751      var values = queryParams.values;
40752      for (var key in values) {
40753        if (!values.hasOwnProperty(key)) {
40754          continue;
40755        }
40756        resolvedQueryParams[key] = values[key];
40757      }
40758
40759      return resolvedQueryParams;
40760    }),
40761
40762    /**
40763      Sets the element's `href` attribute to the url for
40764      the `LinkComponent`'s targeted route.
40765       If the `LinkComponent`'s `tagName` is changed to a value other
40766      than `a`, this property will be ignored.
40767       @property href
40768      @private
40769    */
40770    href: _emberMetalComputed.computed('models', 'qualifiedRouteName', function computeLinkToComponentHref() {
40771      if (_emberMetalProperty_get.get(this, 'tagName') !== 'a') {
40772        return;
40773      }
40774
40775      var qualifiedRouteName = _emberMetalProperty_get.get(this, 'qualifiedRouteName');
40776      var models = _emberMetalProperty_get.get(this, 'models');
40777
40778      if (_emberMetalProperty_get.get(this, 'loading')) {
40779        return _emberMetalProperty_get.get(this, 'loadingHref');
40780      }
40781
40782      var routing = _emberMetalProperty_get.get(this, '_routing');
40783      var queryParams = _emberMetalProperty_get.get(this, 'queryParams.values');
40784      return routing.generateURL(qualifiedRouteName, models, queryParams);
40785    }),
40786
40787    loading: _emberMetalComputed.computed('_modelsAreLoaded', 'qualifiedRouteName', function computeLinkToComponentLoading() {
40788      var qualifiedRouteName = _emberMetalProperty_get.get(this, 'qualifiedRouteName');
40789      var modelsAreLoaded = _emberMetalProperty_get.get(this, '_modelsAreLoaded');
40790
40791      if (!modelsAreLoaded || qualifiedRouteName == null) {
40792        return _emberMetalProperty_get.get(this, 'loadingClass');
40793      }
40794    }),
40795
40796    _modelsAreLoaded: _emberMetalComputed.computed('models', function computeLinkToComponentModelsAreLoaded() {
40797      var models = _emberMetalProperty_get.get(this, 'models');
40798      for (var i = 0, l = models.length; i < l; i++) {
40799        if (models[i] == null) {
40800          return false;
40801        }
40802      }
40803
40804      return true;
40805    }),
40806
40807    _getModels: function (params) {
40808      var modelCount = params.length - 1;
40809      var models = new Array(modelCount);
40810
40811      for (var i = 0; i < modelCount; i++) {
40812        var value = params[i + 1];
40813
40814        while (_emberRuntimeMixinsController.default.detect(value)) {
40815          _emberMetalDebug.deprecate('Providing `{{link-to}}` with a param that is wrapped in a controller is deprecated. ' + (this.parentView ? 'Please update `' + this.parentView + '` to use `{{link-to "post" someController.model}}` instead.' : ''), false, { id: 'ember-routing-views.controller-wrapped-param', until: '3.0.0' });
40816          value = value.get('model');
40817        }
40818
40819        models[i] = value;
40820      }
40821
40822      return models;
40823    },
40824
40825    /**
40826      The default href value to use while a link-to is loading.
40827      Only applies when tagName is 'a'
40828       @property loadingHref
40829      @type String
40830      @default #
40831      @private
40832    */
40833    loadingHref: '#',
40834
40835    willRender: function () {
40836      var queryParams = undefined;
40837
40838      // Do not mutate params in place
40839      var params = _emberMetalProperty_get.get(this, 'params').slice();
40840
40841      _emberMetalDebug.assert('You must provide one or more parameters to the link-to component.', params.length);
40842
40843      var disabledWhen = _emberMetalProperty_get.get(this, 'disabledWhen');
40844      if (disabledWhen !== undefined) {
40845        this.set('disabled', disabledWhen);
40846      }
40847
40848      // Process the positional arguments, in order.
40849      // 1. Inline link title comes first, if present.
40850      if (!this[_emberHtmlbarsNodeManagersComponentNodeManager.HAS_BLOCK]) {
40851        this.set('linkTitle', params.shift());
40852      }
40853
40854      // 2. `targetRouteName` is now always at index 0.
40855      this.set('targetRouteName', params[0]);
40856
40857      // 3. The last argument (if still remaining) is the `queryParams` object.
40858      var lastParam = params[params.length - 1];
40859
40860      if (lastParam && lastParam.isQueryParams) {
40861        queryParams = params.pop();
40862      } else {
40863        queryParams = {};
40864      }
40865      this.set('queryParams', queryParams);
40866
40867      // 4. Any remaining indices (excepting `targetRouteName` at 0) are `models`.
40868      if (params.length > 1) {
40869        this.set('models', this._getModels(params));
40870      } else {
40871        this.set('models', []);
40872      }
40873    }
40874  });
40875
40876  LinkComponent.toString = function () {
40877    return 'LinkComponent';
40878  };
40879
40880  LinkComponent.reopenClass({
40881    positionalParams: 'params'
40882  });
40883
40884  exports.default = LinkComponent;
40885});
40886// creates inject.service
40887enifed('ember-routing-views/index', ['exports', 'ember-metal/core', 'ember-routing-views/components/link-to', 'ember-routing-views/views/outlet'], function (exports, _emberMetalCore, _emberRoutingViewsComponentsLinkTo, _emberRoutingViewsViewsOutlet) {
40888  /**
40889  @module ember
40890  @submodule ember-routing-views
40891  */
40892
40893  'use strict';
40894
40895  _emberMetalCore.default.LinkComponent = _emberRoutingViewsComponentsLinkTo.default;
40896  _emberMetalCore.default.OutletView = _emberRoutingViewsViewsOutlet.OutletView;
40897
40898  exports.default = _emberMetalCore.default;
40899});
40900enifed('ember-routing-views/views/outlet', ['exports', 'ember-views/views/view', 'ember-htmlbars/templates/top-level-view'], function (exports, _emberViewsViewsView, _emberHtmlbarsTemplatesTopLevelView) {
40901  /**
40902  @module ember
40903  @submodule ember-routing-views
40904  */
40905
40906  'use strict';
40907
40908  _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = '[email protected]';
40909
40910  var CoreOutletView = _emberViewsViewsView.default.extend({
40911    defaultTemplate: _emberHtmlbarsTemplatesTopLevelView.default,
40912
40913    init: function () {
40914      this._super();
40915      this._outlets = [];
40916    },
40917
40918    setOutletState: function (state) {
40919      this.outletState = { main: state };
40920
40921      if (this.env) {
40922        this.env.outletState = this.outletState;
40923      }
40924
40925      if (this.lastResult) {
40926        this.dirtyOutlets();
40927        this._outlets = [];
40928
40929        this.scheduleRevalidate(null, null);
40930      }
40931    },
40932
40933    dirtyOutlets: function () {
40934      // Dirty any render nodes that correspond to outlets
40935      for (var i = 0; i < this._outlets.length; i++) {
40936        this._outlets[i].isDirty = true;
40937      }
40938    }
40939  });
40940
40941  exports.CoreOutletView = CoreOutletView;
40942  var OutletView = CoreOutletView.extend({ tagName: '' });
40943  exports.OutletView = OutletView;
40944});
40945enifed('ember-runtime/compare', ['exports', 'ember-runtime/utils', 'ember-runtime/mixins/comparable'], function (exports, _emberRuntimeUtils, _emberRuntimeMixinsComparable) {
40946  'use strict';
40947
40948  exports.default = compare;
40949
40950  var TYPE_ORDER = {
40951    'undefined': 0,
40952    'null': 1,
40953    'boolean': 2,
40954    'number': 3,
40955    'string': 4,
40956    'array': 5,
40957    'object': 6,
40958    'instance': 7,
40959    'function': 8,
40960    'class': 9,
40961    'date': 10
40962  };
40963
40964  //
40965  // the spaceship operator
40966  //
40967  //                      `. ___
40968  //                     __,' __`.                _..----....____
40969  //         __...--.'``;.   ,.   ;``--..__     .'    ,-._    _.-'
40970  //   _..-''-------'   `'   `'   `'     O ``-''._   (,;') _,'
40971  // ,'________________                          \`-._`-','
40972  //  `._              ```````````------...___   '-.._'-:
40973  //     ```--.._      ,.                     ````--...__\-.
40974  //             `.--. `-` "INFINTIY IS LESS     ____    |  |`
40975  //               `. `.   THAN BEYOND"        ,'`````.  ;  ;`
40976  //                 `._`.        __________   `.      \'__/`
40977  //                    `-:._____/______/___/____`.     \  `
40978  //                                |       `._    `.    \
40979  //                                `._________`-.   `.   `.___
40980  //                                              SSt  `------'`
40981  function spaceship(a, b) {
40982    var diff = a - b;
40983    return (diff > 0) - (diff < 0);
40984  }
40985
40986  /**
40987   Compares two javascript values and returns:
40988  
40989    - -1 if the first is smaller than the second,
40990    - 0 if both are equal,
40991    - 1 if the first is greater than the second.
40992  
40993    ```javascript
40994    Ember.compare('hello', 'hello');  // 0
40995    Ember.compare('abc', 'dfg');      // -1
40996    Ember.compare(2, 1);              // 1
40997    ```
40998  
40999   If the types of the two objects are different precedence occurs in the
41000   following order, with types earlier in the list considered `<` types
41001   later in the list:
41002  
41003    - undefined
41004    - null
41005    - boolean
41006    - number
41007    - string
41008    - array
41009    - object
41010    - instance
41011    - function
41012    - class
41013    - date
41014  
41015    ```javascript
41016    Ember.compare('hello', 50);       // 1
41017    Ember.compare(50, 'hello');       // -1
41018    ```
41019  
41020   @method compare
41021   @for Ember
41022   @param {Object} v First value to compare
41023   @param {Object} w Second value to compare
41024   @return {Number} -1 if v < w, 0 if v = w and 1 if v > w.
41025   @public
41026  */
41027
41028  function compare(v, w) {
41029    if (v === w) {
41030      return 0;
41031    }
41032
41033    var type1 = _emberRuntimeUtils.typeOf(v);
41034    var type2 = _emberRuntimeUtils.typeOf(w);
41035
41036    if (_emberRuntimeMixinsComparable.default) {
41037      if (type1 === 'instance' && _emberRuntimeMixinsComparable.default.detect(v) && v.constructor.compare) {
41038        return v.constructor.compare(v, w);
41039      }
41040
41041      if (type2 === 'instance' && _emberRuntimeMixinsComparable.default.detect(w) && w.constructor.compare) {
41042        return w.constructor.compare(w, v) * -1;
41043      }
41044    }
41045
41046    var res = spaceship(TYPE_ORDER[type1], TYPE_ORDER[type2]);
41047
41048    if (res !== 0) {
41049      return res;
41050    }
41051
41052    // types are equal - so we have to check values now
41053    switch (type1) {
41054      case 'boolean':
41055      case 'number':
41056        return spaceship(v, w);
41057
41058      case 'string':
41059        return spaceship(v.localeCompare(w), 0);
41060
41061      case 'array':
41062        var vLen = v.length;
41063        var wLen = w.length;
41064        var len = Math.min(vLen, wLen);
41065
41066        for (var i = 0; i < len; i++) {
41067          var r = compare(v[i], w[i]);
41068          if (r !== 0) {
41069            return r;
41070          }
41071        }
41072
41073        // all elements are equal now
41074        // shorter array should be ordered first
41075        return spaceship(vLen, wLen);
41076
41077      case 'instance':
41078        if (_emberRuntimeMixinsComparable.default && _emberRuntimeMixinsComparable.default.detect(v)) {
41079          return v.compare(v, w);
41080        }
41081        return 0;
41082
41083      case 'date':
41084        return spaceship(v.getTime(), w.getTime());
41085
41086      default:
41087        return 0;
41088    }
41089  }
41090});
41091enifed('ember-runtime/computed/reduce_computed_macros', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/error', 'ember-metal/computed', 'ember-metal/observer', 'ember-runtime/compare', 'ember-runtime/utils', 'ember-runtime/system/native_array', 'ember-metal/is_none', 'ember-metal/get_properties', 'ember-metal/weak_map'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalError, _emberMetalComputed, _emberMetalObserver, _emberRuntimeCompare, _emberRuntimeUtils, _emberRuntimeSystemNative_array, _emberMetalIs_none, _emberMetalGet_properties, _emberMetalWeak_map) {
41092  /**
41093  @module ember
41094  @submodule ember-runtime
41095  */
41096
41097  'use strict';
41098
41099  exports.sum = sum;
41100  exports.max = max;
41101  exports.min = min;
41102  exports.map = map;
41103  exports.mapBy = mapBy;
41104  exports.filter = filter;
41105  exports.filterBy = filterBy;
41106  exports.uniq = uniq;
41107  exports.intersect = intersect;
41108  exports.setDiff = setDiff;
41109  exports.collect = collect;
41110  exports.sort = sort;
41111
41112  function reduceMacro(dependentKey, callback, initialValue) {
41113    return _emberMetalComputed.computed(dependentKey + '.[]', function () {
41114      var _this = this;
41115
41116      var arr = _emberMetalProperty_get.get(this, dependentKey);
41117
41118      if (arr === null || typeof arr !== 'object') {
41119        return initialValue;
41120      }
41121
41122      return arr.reduce(function (previousValue, currentValue, index, array) {
41123        return callback.call(_this, previousValue, currentValue, index, array);
41124      }, initialValue);
41125    }).readOnly();
41126  }
41127
41128  function arrayMacro(dependentKey, callback) {
41129    // This is a bit ugly
41130    var propertyName;
41131    if (/@each/.test(dependentKey)) {
41132      propertyName = dependentKey.replace(/\.@each.*$/, '');
41133    } else {
41134      propertyName = dependentKey;
41135      dependentKey += '.[]';
41136    }
41137
41138    return _emberMetalComputed.computed(dependentKey, function () {
41139      var value = _emberMetalProperty_get.get(this, propertyName);
41140      if (_emberRuntimeUtils.isArray(value)) {
41141        return _emberRuntimeSystemNative_array.A(callback.call(this, value));
41142      } else {
41143        return _emberRuntimeSystemNative_array.A();
41144      }
41145    }).readOnly();
41146  }
41147
41148  function multiArrayMacro(dependentKeys, callback) {
41149    var args = dependentKeys.map(function (key) {
41150      return key + '.[]';
41151    });
41152
41153    args.push(function () {
41154      return _emberRuntimeSystemNative_array.A(callback.call(this, dependentKeys));
41155    });
41156
41157    return _emberMetalComputed.computed.apply(this, args).readOnly();
41158  }
41159
41160  /**
41161    A computed property that returns the sum of the values
41162    in the dependent array.
41163  
41164    @method sum
41165    @for Ember.computed
41166    @param {String} dependentKey
41167    @return {Ember.ComputedProperty} computes the sum of all values in the dependentKey's array
41168    @since 1.4.0
41169    @public
41170  */
41171
41172  function sum(dependentKey) {
41173    return reduceMacro(dependentKey, function (sum, item) {
41174      return sum + item;
41175    }, 0);
41176  }
41177
41178  /**
41179    A computed property that calculates the maximum value in the
41180    dependent array. This will return `-Infinity` when the dependent
41181    array is empty.
41182  
41183    ```javascript
41184    var Person = Ember.Object.extend({
41185      childAges: Ember.computed.mapBy('children', 'age'),
41186      maxChildAge: Ember.computed.max('childAges')
41187    });
41188  
41189    var lordByron = Person.create({ children: [] });
41190  
41191    lordByron.get('maxChildAge'); // -Infinity
41192    lordByron.get('children').pushObject({
41193      name: 'Augusta Ada Byron', age: 7
41194    });
41195    lordByron.get('maxChildAge'); // 7
41196    lordByron.get('children').pushObjects([{
41197      name: 'Allegra Byron',
41198      age: 5
41199    }, {
41200      name: 'Elizabeth Medora Leigh',
41201      age: 8
41202    }]);
41203    lordByron.get('maxChildAge'); // 8
41204    ```
41205  
41206    @method max
41207    @for Ember.computed
41208    @param {String} dependentKey
41209    @return {Ember.ComputedProperty} computes the largest value in the dependentKey's array
41210    @public
41211  */
41212
41213  function max(dependentKey) {
41214    return reduceMacro(dependentKey, function (max, item) {
41215      return Math.max(max, item);
41216    }, -Infinity);
41217  }
41218
41219  /**
41220    A computed property that calculates the minimum value in the
41221    dependent array. This will return `Infinity` when the dependent
41222    array is empty.
41223  
41224    ```javascript
41225    var Person = Ember.Object.extend({
41226      childAges: Ember.computed.mapBy('children', 'age'),
41227      minChildAge: Ember.computed.min('childAges')
41228    });
41229  
41230    var lordByron = Person.create({ children: [] });
41231  
41232    lordByron.get('minChildAge'); // Infinity
41233    lordByron.get('children').pushObject({
41234      name: 'Augusta Ada Byron', age: 7
41235    });
41236    lordByron.get('minChildAge'); // 7
41237    lordByron.get('children').pushObjects([{
41238      name: 'Allegra Byron',
41239      age: 5
41240    }, {
41241      name: 'Elizabeth Medora Leigh',
41242      age: 8
41243    }]);
41244    lordByron.get('minChildAge'); // 5
41245    ```
41246  
41247    @method min
41248    @for Ember.computed
41249    @param {String} dependentKey
41250    @return {Ember.ComputedProperty} computes the smallest value in the dependentKey's array
41251    @public
41252  */
41253
41254  function min(dependentKey) {
41255    return reduceMacro(dependentKey, function (min, item) {
41256      return Math.min(min, item);
41257    }, Infinity);
41258  }
41259
41260  /**
41261    Returns an array mapped via the callback
41262  
41263    The callback method you provide should have the following signature.
41264    `item` is the current item in the iteration.
41265    `index` is the integer index of the current item in the iteration.
41266  
41267    ```javascript
41268    function(item, index);
41269    ```
41270  
41271    Example
41272  
41273    ```javascript
41274    var Hamster = Ember.Object.extend({
41275      excitingChores: Ember.computed.map('chores', function(chore, index) {
41276        return chore.toUpperCase() + '!';
41277      })
41278    });
41279  
41280    var hamster = Hamster.create({
41281      chores: ['clean', 'write more unit tests']
41282    });
41283  
41284    hamster.get('excitingChores'); // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
41285    ```
41286  
41287    @method map
41288    @for Ember.computed
41289    @param {String} dependentKey
41290    @param {Function} callback
41291    @return {Ember.ComputedProperty} an array mapped via the callback
41292    @public
41293  */
41294
41295  function map(dependentKey, callback) {
41296    return arrayMacro(dependentKey, function (value) {
41297      return value.map(callback, this);
41298    });
41299  }
41300
41301  /**
41302    Returns an array mapped to the specified key.
41303  
41304    ```javascript
41305    var Person = Ember.Object.extend({
41306      childAges: Ember.computed.mapBy('children', 'age')
41307    });
41308  
41309    var lordByron = Person.create({ children: [] });
41310  
41311    lordByron.get('childAges'); // []
41312    lordByron.get('children').pushObject({ name: 'Augusta Ada Byron', age: 7 });
41313    lordByron.get('childAges'); // [7]
41314    lordByron.get('children').pushObjects([{
41315      name: 'Allegra Byron',
41316      age: 5
41317    }, {
41318      name: 'Elizabeth Medora Leigh',
41319      age: 8
41320    }]);
41321    lordByron.get('childAges'); // [7, 5, 8]
41322    ```
41323  
41324    @method mapBy
41325    @for Ember.computed
41326    @param {String} dependentKey
41327    @param {String} propertyKey
41328    @return {Ember.ComputedProperty} an array mapped to the specified key
41329    @public
41330  */
41331
41332  function mapBy(dependentKey, propertyKey) {
41333    _emberMetalDebug.assert('Ember.computed.mapBy expects a property string for its second argument, ' + 'perhaps you meant to use "map"', typeof propertyKey === 'string');
41334
41335    return map(dependentKey + '.@each.' + propertyKey, function (item) {
41336      return _emberMetalProperty_get.get(item, propertyKey);
41337    });
41338  }
41339
41340  /**
41341    Filters the array by the callback.
41342  
41343    The callback method you provide should have the following signature.
41344    `item` is the current item in the iteration.
41345    `index` is the integer index of the current item in the iteration.
41346    `array` is the dependant array itself.
41347  
41348    ```javascript
41349    function(item, index, array);
41350    ```
41351  
41352    ```javascript
41353    var Hamster = Ember.Object.extend({
41354      remainingChores: Ember.computed.filter('chores', function(chore, index, array) {
41355        return !chore.done;
41356      })
41357    });
41358  
41359    var hamster = Hamster.create({
41360      chores: [
41361        { name: 'cook', done: true },
41362        { name: 'clean', done: true },
41363        { name: 'write more unit tests', done: false }
41364      ]
41365    });
41366  
41367    hamster.get('remainingChores'); // [{name: 'write more unit tests', done: false}]
41368    ```
41369  
41370    @method filter
41371    @for Ember.computed
41372    @param {String} dependentKey
41373    @param {Function} callback
41374    @return {Ember.ComputedProperty} the filtered array
41375    @public
41376  */
41377
41378  function filter(dependentKey, callback) {
41379    return arrayMacro(dependentKey, function (value) {
41380      return value.filter(callback, this);
41381    });
41382  }
41383
41384  /**
41385    Filters the array by the property and value
41386  
41387    ```javascript
41388    var Hamster = Ember.Object.extend({
41389      remainingChores: Ember.computed.filterBy('chores', 'done', false)
41390    });
41391  
41392    var hamster = Hamster.create({
41393      chores: [
41394        { name: 'cook', done: true },
41395        { name: 'clean', done: true },
41396        { name: 'write more unit tests', done: false }
41397      ]
41398    });
41399  
41400    hamster.get('remainingChores'); // [{ name: 'write more unit tests', done: false }]
41401    ```
41402  
41403    @method filterBy
41404    @for Ember.computed
41405    @param {String} dependentKey
41406    @param {String} propertyKey
41407    @param {*} value
41408    @return {Ember.ComputedProperty} the filtered array
41409    @public
41410  */
41411
41412  function filterBy(dependentKey, propertyKey, value) {
41413    var callback;
41414
41415    if (arguments.length === 2) {
41416      callback = function (item) {
41417        return _emberMetalProperty_get.get(item, propertyKey);
41418      };
41419    } else {
41420      callback = function (item) {
41421        return _emberMetalProperty_get.get(item, propertyKey) === value;
41422      };
41423    }
41424
41425    return filter(dependentKey + '.@each.' + propertyKey, callback);
41426  }
41427
41428  /**
41429    A computed property which returns a new array with all the unique
41430    elements from one or more dependent arrays.
41431  
41432    Example
41433  
41434    ```javascript
41435    var Hamster = Ember.Object.extend({
41436      uniqueFruits: Ember.computed.uniq('fruits')
41437    });
41438  
41439    var hamster = Hamster.create({
41440      fruits: [
41441        'banana',
41442        'grape',
41443        'kale',
41444        'banana'
41445      ]
41446    });
41447  
41448    hamster.get('uniqueFruits'); // ['banana', 'grape', 'kale']
41449    ```
41450  
41451    @method uniq
41452    @for Ember.computed
41453    @param {String} propertyKey*
41454    @return {Ember.ComputedProperty} computes a new array with all the
41455    unique elements from the dependent array
41456    @public
41457  */
41458
41459  function uniq() {
41460    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
41461      args[_key] = arguments[_key];
41462    }
41463
41464    return multiArrayMacro(args, function (dependentKeys) {
41465      var _this2 = this;
41466
41467      var uniq = _emberRuntimeSystemNative_array.A();
41468
41469      dependentKeys.forEach(function (dependentKey) {
41470        var value = _emberMetalProperty_get.get(_this2, dependentKey);
41471        if (_emberRuntimeUtils.isArray(value)) {
41472          value.forEach(function (item) {
41473            if (uniq.indexOf(item) === -1) {
41474              uniq.push(item);
41475            }
41476          });
41477        }
41478      });
41479
41480      return uniq;
41481    });
41482  }
41483
41484  /**
41485    Alias for [Ember.computed.uniq](/api/#method_computed_uniq).
41486  
41487    @method union
41488    @for Ember.computed
41489    @param {String} propertyKey*
41490    @return {Ember.ComputedProperty} computes a new array with all the
41491    unique elements from the dependent array
41492    @public
41493  */
41494  var union = uniq;
41495
41496  exports.union = union;
41497  /**
41498    A computed property which returns a new array with all the duplicated
41499    elements from two or more dependent arrays.
41500  
41501    Example
41502  
41503    ```javascript
41504    var obj = Ember.Object.extend({
41505      friendsInCommon: Ember.computed.intersect('adaFriends', 'charlesFriends')
41506    }).create({
41507      adaFriends: ['Charles Babbage', 'John Hobhouse', 'William King', 'Mary Somerville'],
41508      charlesFriends: ['William King', 'Mary Somerville', 'Ada Lovelace', 'George Peacock']
41509    });
41510  
41511    obj.get('friendsInCommon'); // ['William King', 'Mary Somerville']
41512    ```
41513  
41514    @method intersect
41515    @for Ember.computed
41516    @param {String} propertyKey*
41517    @return {Ember.ComputedProperty} computes a new array with all the
41518    duplicated elements from the dependent arrays
41519    @public
41520  */
41521
41522  function intersect() {
41523    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
41524      args[_key2] = arguments[_key2];
41525    }
41526
41527    return multiArrayMacro(args, function (dependentKeys) {
41528      var _this3 = this;
41529
41530      var arrays = dependentKeys.map(function (dependentKey) {
41531        var array = _emberMetalProperty_get.get(_this3, dependentKey);
41532
41533        return _emberRuntimeUtils.isArray(array) ? array : [];
41534      });
41535
41536      var results = arrays.pop().filter(function (candidate) {
41537        for (var i = 0; i < arrays.length; i++) {
41538          var found = false;
41539          var array = arrays[i];
41540          for (var j = 0; j < array.length; j++) {
41541            if (array[j] === candidate) {
41542              found = true;
41543              break;
41544            }
41545          }
41546
41547          if (found === false) {
41548            return false;
41549          }
41550        }
41551
41552        return true;
41553      });
41554
41555      return _emberRuntimeSystemNative_array.A(results);
41556    });
41557  }
41558
41559  /**
41560    A computed property which returns a new array with all the
41561    properties from the first dependent array that are not in the second
41562    dependent array.
41563  
41564    Example
41565  
41566    ```javascript
41567    var Hamster = Ember.Object.extend({
41568      likes: ['banana', 'grape', 'kale'],
41569      wants: Ember.computed.setDiff('likes', 'fruits')
41570    });
41571  
41572    var hamster = Hamster.create({
41573      fruits: [
41574        'grape',
41575        'kale',
41576      ]
41577    });
41578  
41579    hamster.get('wants'); // ['banana']
41580    ```
41581  
41582    @method setDiff
41583    @for Ember.computed
41584    @param {String} setAProperty
41585    @param {String} setBProperty
41586    @return {Ember.ComputedProperty} computes a new array with all the
41587    items from the first dependent array that are not in the second
41588    dependent array
41589    @public
41590  */
41591
41592  function setDiff(setAProperty, setBProperty) {
41593    if (arguments.length !== 2) {
41594      throw new _emberMetalError.default('setDiff requires exactly two dependent arrays.');
41595    }
41596
41597    return _emberMetalComputed.computed(setAProperty + '.[]', setBProperty + '.[]', function () {
41598      var setA = this.get(setAProperty);
41599      var setB = this.get(setBProperty);
41600
41601      if (!_emberRuntimeUtils.isArray(setA)) {
41602        return _emberRuntimeSystemNative_array.A();
41603      }
41604      if (!_emberRuntimeUtils.isArray(setB)) {
41605        return _emberRuntimeSystemNative_array.A(setA);
41606      }
41607
41608      return setA.filter(function (x) {
41609        return setB.indexOf(x) === -1;
41610      });
41611    }).readOnly();
41612  }
41613
41614  /**
41615    A computed property that returns the array of values
41616    for the provided dependent properties.
41617  
41618    Example
41619  
41620    ```javascript
41621    var Hamster = Ember.Object.extend({
41622      clothes: Ember.computed.collect('hat', 'shirt')
41623    });
41624  
41625    var hamster = Hamster.create();
41626  
41627    hamster.get('clothes'); // [null, null]
41628    hamster.set('hat', 'Camp Hat');
41629    hamster.set('shirt', 'Camp Shirt');
41630    hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt']
41631    ```
41632  
41633    @method collect
41634    @for Ember.computed
41635    @param {String} dependentKey*
41636    @return {Ember.ComputedProperty} computed property which maps
41637    values of all passed in properties to an array.
41638    @public
41639  */
41640
41641  function collect() {
41642    for (var _len3 = arguments.length, dependentKeys = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
41643      dependentKeys[_key3] = arguments[_key3];
41644    }
41645
41646    return multiArrayMacro(dependentKeys, function () {
41647      var properties = _emberMetalGet_properties.default(this, dependentKeys);
41648      var res = _emberRuntimeSystemNative_array.A();
41649      for (var key in properties) {
41650        if (properties.hasOwnProperty(key)) {
41651          if (_emberMetalIs_none.default(properties[key])) {
41652            res.push(null);
41653          } else {
41654            res.push(properties[key]);
41655          }
41656        }
41657      }
41658      return res;
41659    });
41660  }
41661
41662  /**
41663    A computed property which returns a new array with all the
41664    properties from the first dependent array sorted based on a property
41665    or sort function.
41666  
41667    The callback method you provide should have the following signature:
41668  
41669    ```javascript
41670    function(itemA, itemB);
41671    ```
41672  
41673    - `itemA` the first item to compare.
41674    - `itemB` the second item to compare.
41675  
41676    This function should return negative number (e.g. `-1`) when `itemA` should come before
41677    `itemB`. It should return positive number (e.g. `1`) when `itemA` should come after
41678    `itemB`. If the `itemA` and `itemB` are equal this function should return `0`.
41679  
41680    Therefore, if this function is comparing some numeric values, simple `itemA - itemB` or
41681    `itemA.get( 'foo' ) - itemB.get( 'foo' )` can be used instead of series of `if`.
41682  
41683    Example
41684  
41685    ```javascript
41686    var ToDoList = Ember.Object.extend({
41687      // using standard ascending sort
41688      todosSorting: ['name'],
41689      sortedTodos: Ember.computed.sort('todos', 'todosSorting'),
41690  
41691      // using descending sort
41692      todosSortingDesc: ['name:desc'],
41693      sortedTodosDesc: Ember.computed.sort('todos', 'todosSortingDesc'),
41694  
41695      // using a custom sort function
41696      priorityTodos: Ember.computed.sort('todos', function(a, b){
41697        if (a.priority > b.priority) {
41698          return 1;
41699        } else if (a.priority < b.priority) {
41700          return -1;
41701        }
41702  
41703        return 0;
41704      })
41705    });
41706  
41707    var todoList = ToDoList.create({todos: [
41708      { name: 'Unit Test', priority: 2 },
41709      { name: 'Documentation', priority: 3 },
41710      { name: 'Release', priority: 1 }
41711    ]});
41712  
41713    todoList.get('sortedTodos');      // [{ name:'Documentation', priority:3 }, { name:'Release', priority:1 }, { name:'Unit Test', priority:2 }]
41714    todoList.get('sortedTodosDesc');  // [{ name:'Unit Test', priority:2 }, { name:'Release', priority:1 }, { name:'Documentation', priority:3 }]
41715    todoList.get('priorityTodos');    // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
41716    ```
41717  
41718    @method sort
41719    @for Ember.computed
41720    @param {String} itemsKey
41721    @param {String or Function} sortDefinition a dependent key to an
41722    array of sort properties (add `:desc` to the arrays sort properties to sort descending) or a function to use when sorting
41723    @return {Ember.ComputedProperty} computes a new sorted array based
41724    on the sort property array or callback function
41725    @public
41726  */
41727
41728  function sort(itemsKey, sortDefinition) {
41729    _emberMetalDebug.assert('Ember.computed.sort requires two arguments: an array key to sort and ' + 'either a sort properties key or sort function', arguments.length === 2);
41730
41731    if (typeof sortDefinition === 'function') {
41732      return customSort(itemsKey, sortDefinition);
41733    } else {
41734      return propertySort(itemsKey, sortDefinition);
41735    }
41736  }
41737
41738  function customSort(itemsKey, comparator) {
41739    return arrayMacro(itemsKey, function (value) {
41740      var _this4 = this;
41741
41742      return value.slice().sort(function (x, y) {
41743        return comparator.call(_this4, x, y);
41744      });
41745    });
41746  }
41747
41748  // This one needs to dynamically set up and tear down observers on the itemsKey
41749  // depending on the sortProperties
41750  function propertySort(itemsKey, sortPropertiesKey) {
41751    var cp = new _emberMetalComputed.ComputedProperty(function (key) {
41752      var _this5 = this;
41753
41754      var itemsKeyIsAtThis = itemsKey === '@this';
41755      var sortProperties = _emberMetalProperty_get.get(this, sortPropertiesKey);
41756
41757      _emberMetalDebug.assert('The sort definition for \'' + key + '\' on ' + this + ' must be a function or an array of str
41757ings', _emberRuntimeUtils.isArray(sortProperties) && sortProperties.every(function (s) {
41758        return typeof s === 'string';
41759      }));
41760
41761      var normalizedSortProperties = normalizeSortProperties(sortProperties);
41762
41763      // Add/remove property observers as required.
41764      var activeObserversMap = cp._activeObserverMap || (cp._activeObserverMap = new _emberMetalWeak_map.default());
41765      var activeObservers = activeObserversMap.get(this);
41766
41767      if (activeObservers) {
41768        activeObservers.forEach(function (args) {
41769          _emberMetalObserver.removeObserver.apply(null, args);
41770        });
41771      }
41772
41773      function sortPropertyDidChange() {
41774        this.notifyPropertyChange(key);
41775      }
41776
41777      activeObservers = normalizedSortProperties.map(function (_ref) {
41778        var prop = _ref[0];
41779
41780        var path = itemsKeyIsAtThis ? '@each.' + prop : itemsKey + '.@each.' + prop;
41781        var args = [_this5, path, sortPropertyDidChange];
41782        _emberMetalObserver.addObserver.apply(null, args);
41783        return args;
41784      });
41785
41786      activeObserversMap.set(this, activeObservers);
41787
41788      // Sort and return the array.
41789      var items = itemsKeyIsAtThis ? this : _emberMetalProperty_get.get(this, itemsKey);
41790
41791      if (_emberRuntimeUtils.isArray(items)) {
41792        return sortByNormalizedSortProperties(items, normalizedSortProperties);
41793      } else {
41794        return _emberRuntimeSystemNative_array.A();
41795      }
41796    });
41797
41798    cp._activeObserverMap = undefined;
41799
41800    return cp.property(sortPropertiesKey + '.[]').readOnly();
41801  }
41802
41803  function normalizeSortProperties(sortProperties) {
41804    return sortProperties.map(function (p) {
41805      var _p$split = p.split(':');
41806
41807      var prop = _p$split[0];
41808      var direction = _p$split[1];
41809
41810      direction = direction || 'asc';
41811
41812      return [prop, direction];
41813    });
41814  }
41815
41816  function sortByNormalizedSortProperties(items, normalizedSortProperties) {
41817    return _emberRuntimeSystemNative_array.A(items.slice().sort(function (itemA, itemB) {
41818      for (var i = 0; i < normalizedSortProperties.length; i++) {
41819        var _normalizedSortProperties$i = normalizedSortProperties[i];
41820        var prop = _normalizedSortProperties$i[0];
41821        var direction = _normalizedSortProperties$i[1];
41822
41823        var result = _emberRuntimeCompare.default(_emberMetalProperty_get.get(itemA, prop), _emberMetalProperty_get.get(itemB, prop));
41824        if (result !== 0) {
41825          return direction === 'desc' ? -1 * result : result;
41826        }
41827      }
41828
41829      return 0;
41830    }));
41831  }
41832});
41833enifed('ember-runtime/controllers/controller', ['exports', 'ember-metal/debug', 'ember-runtime/system/object', 'ember-runtime/mixins/controller', 'ember-runtime/inject', 'ember-runtime/mixins/action_handler'], function (exports, _emberMetalDebug, _emberRuntimeSystemObject, _emberRuntimeMixinsController, _emberRuntimeInject, _emberRuntimeMixinsAction_handler) {
41834  'use strict';
41835
41836  /**
41837  @module ember
41838  @submodule ember-runtime
41839  */
41840
41841  /**
41842    @class Controller
41843    @namespace Ember
41844    @extends Ember.Object
41845    @uses Ember.ControllerMixin
41846    @public
41847  */
41848  var Controller = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsController.default);
41849
41850  _emberRuntimeMixinsAction_handler.deprecateUnderscoreActions(Controller);
41851
41852  function controllerInjectionHelper(factory) {
41853    _emberMetalDebug.assert('Defining an injected controller property on a ' + 'non-controller is not allowed.', _emberRuntimeMixinsController.default.detect(factory.PrototypeMixin));
41854  }
41855
41856  /**
41857    Creates a property that lazily looks up another controller in the container.
41858    Can only be used when defining another controller.
41859  
41860    Example:
41861  
41862    ```javascript
41863    App.PostController = Ember.Controller.extend({
41864      posts: Ember.inject.controller()
41865    });
41866    ```
41867  
41868    This example will create a `posts` property on the `post` controller that
41869    looks up the `posts` controller in the container, making it easy to
41870    reference other controllers. This is functionally equivalent to:
41871  
41872    ```javascript
41873    App.PostController = Ember.Controller.extend({
41874      needs: 'posts',
41875      posts: Ember.computed.alias('controllers.posts')
41876    });
41877    ```
41878  
41879    @method controller
41880    @since 1.10.0
41881    @for Ember.inject
41882    @param {String} name (optional) name of the controller to inject, defaults
41883           to the property's name
41884    @return {Ember.InjectedProperty} injection descriptor instance
41885    @public
41886  */
41887  _emberRuntimeInject.createInjectionHelper('controller', controllerInjectionHelper);
41888
41889  exports.default = Controller;
41890});
41891enifed('ember-runtime/copy', ['exports', 'ember-metal/debug', 'ember-runtime/system/object', 'ember-runtime/mixins/copyable'], function (exports, _emberMetalDebug, _emberRuntimeSystemObject, _emberRuntimeMixinsCopyable) {
41892  'use strict';
41893
41894  exports.default = copy;
41895
41896  function _copy(obj, deep, seen, copies) {
41897    var ret, loc, key;
41898
41899    // primitive data types are immutable, just return them.
41900    if (typeof obj !== 'object' || obj === null) {
41901      return obj;
41902    }
41903
41904    // avoid cyclical loops
41905    if (deep && (loc = seen.indexOf(obj)) >= 0) {
41906      return copies[loc];
41907    }
41908
41909    _emberMetalDebug.assert('Cannot clone an Ember.Object that does not implement Ember.Copyable', !(obj instanceof _emberRuntimeSystemObject.default) || _emberRuntimeMixinsCopyable.default && _emberRuntimeMixinsCopyable.default.detect(obj));
41910
41911    // IMPORTANT: this specific test will detect a native array only. Any other
41912    // object will need to implement Copyable.
41913    if (Array.isArray(obj)) {
41914      ret = obj.slice();
41915
41916      if (deep) {
41917        loc = ret.length;
41918
41919        while (--loc >= 0) {
41920          ret[loc] = _copy(ret[loc], deep, seen, copies);
41921        }
41922      }
41923    } else if (_emberRuntimeMixinsCopyable.default && _emberRuntimeMixinsCopyable.default.detect(obj)) {
41924      ret = obj.copy(deep, seen, copies);
41925    } else if (obj instanceof Date) {
41926      ret = new Date(obj.getTime());
41927    } else {
41928      ret = {};
41929
41930      for (key in obj) {
41931        // support Null prototype
41932        if (!Object.prototype.hasOwnProperty.call(obj, key)) {
41933          continue;
41934        }
41935
41936        // Prevents browsers that don't respect non-enumerability from
41937        // copying internal Ember properties
41938        if (key.substring(0, 2) === '__') {
41939          continue;
41940        }
41941
41942        ret[key] = deep ? _copy(obj[key], deep, seen, copies) : obj[key];
41943      }
41944    }
41945
41946    if (deep) {
41947      seen.push(obj);
41948      copies.push(ret);
41949    }
41950
41951    return ret;
41952  }
41953
41954  /**
41955    Creates a shallow copy of the passed object. A deep copy of the object is
41956    returned if the optional `deep` argument is `true`.
41957  
41958    If the passed object implements the `Ember.Copyable` interface, then this
41959    function will delegate to the object's `copy()` method and return the
41960    result. See `Ember.Copyable` for further details.
41961  
41962    For primitive values (which are immutable in JavaScript), the passed object
41963    is simply returned.
41964  
41965    @method copy
41966    @for Ember
41967    @param {Object} obj The object to clone
41968    @param {Boolean} [deep=false] If true, a deep copy of the object is made.
41969    @return {Object} The copied object
41970    @public
41971  */
41972
41973  function copy(obj, deep) {
41974    // fast paths
41975    if ('object' !== typeof obj || obj === null) {
41976      return obj; // can't copy primitives
41977    }
41978
41979    if (_emberRuntimeMixinsCopyable.default && _emberRuntimeMixinsCopyable.default.detect(obj)) {
41980      return obj.copy(deep);
41981    }
41982
41983    return _copy(obj, deep, deep ? [] : null, deep ? [] : null);
41984  }
41985});
41986enifed("ember-runtime/core", ["exports"], function (exports) {
41987  "use strict";
41988});
41989/**
41990@module ember
41991@submodule ember-runtime
41992*/
41993enifed('ember-runtime/ext/function', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/computed', 'ember-metal/mixin'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalComputed, _emberMetalMixin) {
41994  /**
41995  @module ember
41996  @submodule ember-runtime
41997  */
41998
41999  'use strict';
42000
42001  var a_slice = Array.prototype.slice;
42002  var FunctionPrototype = Function.prototype;
42003
42004  if (_emberMetalCore.default.EXTEND_PROTOTYPES === true || _emberMetalCore.default.EXTEND_PROTOTYPES.Function) {
42005    /**
42006      The `property` extension of Javascript's Function prototype is available
42007      when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
42008      `true`, which is the default.
42009       Computed properties allow you to treat a function like a property:
42010       ```javascript
42011      MyApp.President = Ember.Object.extend({
42012        firstName: '',
42013        lastName:  '',
42014         fullName: function() {
42015          return this.get('firstName') + ' ' + this.get('lastName');
42016        }.property() // Call this flag to mark the function as a property
42017      });
42018       var president = MyApp.President.create({
42019        firstName: 'Barack',
42020        lastName: 'Obama'
42021      });
42022       president.get('fullName'); // 'Barack Obama'
42023      ```
42024       Treating a function like a property is useful because they can work with
42025      bindings, just like any other property.
42026       Many computed properties have dependencies on other properties. For
42027      example, in the above example, the `fullName` property depends on
42028      `firstName` and `lastName` to determine its value. You can tell Ember
42029      about these dependencies like this:
42030       ```javascript
42031      MyApp.President = Ember.Object.extend({
42032        firstName: '',
42033        lastName:  '',
42034         fullName: function() {
42035          return this.get('firstName') + ' ' + this.get('lastName');
42036           // Tell Ember.js that this computed property depends on firstName
42037          // and lastName
42038        }.property('firstName', 'lastName')
42039      });
42040      ```
42041       Make sure you list these dependencies so Ember knows when to update
42042      bindings that connect to a computed property. Changing a dependency
42043      will not immediately trigger an update of the computed property, but
42044      will instead clear the cache so that it is updated when the next `get`
42045      is called on the property.
42046       See [Ember.ComputedProperty](/api/classes/Ember.ComputedProperty.html), [Ember.computed](/api/#method_computed).
42047       @method property
42048      @for Function
42049      @public
42050    */
42051    FunctionPrototype.property = function () {
42052      var ret = _emberMetalComputed.computed(this);
42053      // ComputedProperty.prototype.property expands properties; no need for us to
42054      // do so here.
42055      return ret.property.apply(ret, arguments);
42056    };
42057
42058    /**
42059      The `observes` extension of Javascript's Function prototype is available
42060      when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
42061      true, which is the default.
42062       You can observe property changes simply by adding the `observes`
42063      call to the end of your method declarations in classes that you write.
42064      For example:
42065       ```javascript
42066      Ember.Object.extend({
42067        valueObserver: function() {
42068          // Executes whenever the "value" property changes
42069        }.observes('value')
42070      });
42071      ```
42072       In the future this method may become asynchronous.
42073       See `Ember.observer`.
42074       @method observes
42075      @for Function
42076      @public
42077    */
42078    FunctionPrototype.observes = function () {
42079      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
42080        args[_key] = arguments[_key];
42081      }
42082
42083      args.push(this);
42084      return _emberMetalMixin.observer.apply(this, args);
42085    };
42086
42087    FunctionPrototype._observesImmediately = function () {
42088      _emberMetalDebug.assert('Immediate observers must observe internal properties only, ' + 'not properties on other objects.', function checkIsInternalProperty() {
42089        for (var i = 0, l = arguments.length; i < l; i++) {
42090          if (arguments[i].indexOf('.') !== -1) {
42091            return false;
42092          }
42093        }
42094        return true;
42095      });
42096
42097      // observes handles property expansion
42098      return this.observes.apply(this, arguments);
42099    };
42100    /**
42101      The `observesImmediately` extension of Javascript's Function prototype is
42102      available when `Ember.EXTEND_PROTOTYPES` or
42103      `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.
42104       You can observe property changes simply by adding the `observesImmediately`
42105      call to the end of your method declarations in classes that you write.
42106      For example:
42107       ```javascript
42108      Ember.Object.extend({
42109        valueObserver: function() {
42110          // Executes immediately after the "value" property changes
42111        }.observesImmediately('value')
42112      });
42113      ```
42114       In the future, `observes` may become asynchronous. In this event,
42115      `observesImmediately` will maintain the synchronous behavior.
42116       See `Ember.immediateObserver`.
42117       @method observesImmediately
42118      @for Function
42119      @deprecated
42120      @private
42121    */
42122    FunctionPrototype.observesImmediately = _emberMetalDebug.deprecateFunc('Function#observesImmediately is deprecated. Use Function#observes instead', { id: 'ember-runtime.ext-function', until: '3.0.0' }, FunctionPrototype._observesImmediately);
42123
42124    /**
42125      The `on` extension of Javascript's Function prototype is available
42126      when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
42127      true, which is the default.
42128       You can listen for events simply by adding the `on` call to the end of
42129      your method declarations in classes or mixins that you write. For example:
42130       ```javascript
42131      Ember.Mixin.create({
42132        doSomethingWithElement: function() {
42133          // Executes whenever the "didInsertElement" event fires
42134        }.on('didInsertElement')
42135      });
42136      ```
42137       See `Ember.on`.
42138       @method on
42139      @for Function
42140      @public
42141    */
42142    FunctionPrototype.on = function () {
42143      var events = a_slice.call(arguments);
42144      this.__ember_listens__ = events;
42145
42146      return this;
42147    };
42148  }
42149});
42150// Ember.EXTEND_PROTOTYPES
42151enifed('ember-runtime/ext/rsvp', ['exports', 'ember-metal/core', 'require', 'ember-metal/debug', 'ember-metal/logger', 'ember-metal/run_loop', 'rsvp'], function (exports, _emberMetalCore, _require, _emberMetalDebug, _emberMetalLogger, _emberMetalRun_loop, _rsvp) {
42152  'use strict';
42153
42154  exports.onerrorDefault = onerrorDefault;
42155  exports.after = after;
42156
42157  var testModuleName = 'ember-testing/test';
42158  var Test;
42159
42160  var asyncStart = function () {
42161    if (_emberMetalCore.default.Test && _emberMetalCore.default.Test.adapter) {
42162      _emberMetalCore.default.Test.adapter.asyncStart();
42163    }
42164  };
42165
42166  var asyncEnd = function () {
42167    if (_emberMetalCore.default.Test && _emberMetalCore.default.Test.adapter) {
42168      _emberMetalCore.default.Test.adapter.asyncEnd();
42169    }
42170  };
42171
42172  _rsvp.configure('async', function (callback, promise) {
42173    var async = !_emberMetalRun_loop.default.currentRunLoop;
42174
42175    if (_emberMetalCore.default.testing && async) {
42176      asyncStart();
42177    }
42178
42179    _emberMetalRun_loop.default.backburner.schedule('actions', function () {
42180      if (_emberMetalCore.default.testing && async) {
42181        asyncEnd();
42182      }
42183      callback(promise);
42184    });
42185  });
42186
42187  function onerrorDefault(reason) {
42188    var error;
42189
42190    if (reason && reason.errorThrown) {
42191      // jqXHR provides this
42192      error = reason.errorThrown;
42193      if (typeof error === 'string') {
42194        error = new Error(error);
42195      }
42196      Object.defineProperty(error, '__reason_with_error_thrown__', {
42197        value: reason,
42198        enumerable: false
42199      });
42200    } else {
42201      error = reason;
42202    }
42203
42204    if (error && error.name === "UnrecognizedURLError") {
42205      _emberMetalDebug.assert("The URL '" + error.message + "' did not match any routes in your application", false);
42206      return;
42207    }
42208
42209    if (error && error.name !== 'TransitionAborted') {
42210      if (_emberMetalCore.default.testing) {
42211        // ES6TODO: remove when possible
42212        if (!Test && _require.has(testModuleName)) {
42213          Test = _require.default(testModuleName)['default'];
42214        }
42215
42216        if (Test && Test.adapter) {
42217          Test.adapter.exception(error);
42218          _emberMetalLogger.default.error(error.stack);
42219        } else {
42220          throw error;
42221        }
42222      } else if (_emberMetalCore.default.onerror) {
42223        _emberMetalCore.default.onerror(error);
42224      } else {
42225        _emberMetalLogger.default.error(error.stack);
42226      }
42227    }
42228  }
42229
42230  function after(cb) {
42231    _emberMetalRun_loop.default.schedule(_emberMetalRun_loop.default.queues[_emberMetalRun_loop.default.queues.length - 1], cb);
42232  }
42233
42234  _rsvp.on('error', onerrorDefault);
42235  _rsvp.configure('after', after);
42236
42237  exports.default = _rsvp;
42238});
42239enifed('ember-runtime/ext/string', ['exports', 'ember-metal/core', 'ember-runtime/system/string'], function (exports, _emberMetalCore, _emberRuntimeSystemString) {
42240  /**
42241  @module ember
42242  @submodule ember-runtime
42243  */
42244
42245  'use strict';
42246
42247  var StringPrototype = String.prototype;
42248
42249  if (_emberMetalCore.default.EXTEND_PROTOTYPES === true || _emberMetalCore.default.EXTEND_PROTOTYPES.String) {
42250    /**
42251      See [Ember.String.fmt](/api/classes/Ember.String.html#method_fmt).
42252       @method fmt
42253      @for String
42254      @private
42255      @deprecated
42256    */
42257    StringPrototype.fmt = function () {
42258      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
42259        args[_key] = arguments[_key];
42260      }
42261
42262      return _emberRuntimeSystemString.fmt(this, args);
42263    };
42264
42265    /**
42266      See [Ember.String.w](/api/classes/Ember.String.html#method_w).
42267       @method w
42268      @for String
42269      @private
42270    */
42271    StringPrototype.w = function () {
42272      return _emberRuntimeSystemString.w(this);
42273    };
42274
42275    /**
42276      See [Ember.String.loc](/api/classes/Ember.String.html#method_loc).
42277       @method loc
42278      @for String
42279      @private
42280    */
42281    StringPrototype.loc = function () {
42282      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
42283        args[_key2] = arguments[_key2];
42284      }
42285
42286      return _emberRuntimeSystemString.loc(this, args);
42287    };
42288
42289    /**
42290      See [Ember.String.camelize](/api/classes/Ember.String.html#method_camelize).
42291       @method camelize
42292      @for String
42293      @private
42294    */
42295    StringPrototype.camelize = function () {
42296      return _emberRuntimeSystemString.camelize(this);
42297    };
42298
42299    /**
42300      See [Ember.String.decamelize](/api/classes/Ember.String.html#method_decamelize).
42301       @method decamelize
42302      @for String
42303      @private
42304    */
42305    StringPrototype.decamelize = function () {
42306      return _emberRuntimeSystemString.decamelize(this);
42307    };
42308
42309    /**
42310      See [Ember.String.dasherize](/api/classes/Ember.String.html#method_dasherize).
42311       @method dasherize
42312      @for String
42313      @private
42314    */
42315    StringPrototype.dasherize = function () {
42316      return _emberRuntimeSystemString.dasherize(this);
42317    };
42318
42319    /**
42320      See [Ember.String.underscore](/api/classes/Ember.String.html#method_underscore).
42321       @method underscore
42322      @for String
42323      @private
42324    */
42325    StringPrototype.underscore = function () {
42326      return _emberRuntimeSystemString.underscore(this);
42327    };
42328
42329    /**
42330      See [Ember.String.classify](/api/classes/Ember.String.html#method_classify).
42331       @method classify
42332      @for String
42333      @private
42334    */
42335    StringPrototype.classify = function () {
42336      return _emberRuntimeSystemString.classify(this);
42337    };
42338
42339    /**
42340      See [Ember.String.capitalize](/api/classes/Ember.String.html#method_capitalize).
42341       @method capitalize
42342      @for String
42343      @private
42344    */
42345    StringPrototype.capitalize = function () {
42346      return _emberRuntimeSystemString.capitalize(this);
42347    };
42348  }
42349});
42350// Ember.EXTEND_PROTOTYPES
42351enifed('ember-runtime/index', ['exports', 'ember-metal', 'ember-runtime/is-equal', 'ember-runtime/compare', 'ember-runtime/copy', 'ember-runtime/inject', 'ember-runtime/system/namespace', 'ember-runtime/system/object', 'ember-runtime/system/container', 'ember-runtime/system/array_proxy', 'ember-runtime/system/object_proxy', 'ember-runtime/system/core_object', 'ember-runtime/system/native_array', 'ember-runtime/system/string', 'ember-runtime/system/lazy_load', 'ember-runtime/mixins/array', 'ember-runtime/mixins/comparable', 'ember-runtime/mixins/copyable', 'ember-runtime/mixins/enumerable', 'ember-runtime/mixins/freezable', 'ember-runtime/mixins/-proxy', 'ember-runtime/mixins/observable', 'ember-runtime/mixins/action_handler', 'ember-runtime/mixins/mutable_enumerable', 'ember-runtime/mixins/mutable_array', 'ember-runtime/mixins/target_action_support', 'ember-runtime/mixins/evented', 'ember-runtime/mixins/promise_proxy', 'ember-runtime/computed/reduce_computed_macros', 'ember-runtime/controllers/controller', 'ember-runtime/mixins/controller', 'ember-runtime/system/service', 'ember-runtime/ext/rsvp', 'ember-runtime/ext/string', 'ember-runtime/ext/function', 'ember-runtime/utils', 'ember-metal/features', 'ember-runtime/mixins/registry_proxy', 'ember-runtime/mixins/container_proxy', 'ember-runtime/string_registry'], function (exports, _emberMetal, _emberRuntimeIsEqual, _emberRuntimeCompare, _emberRuntimeCopy, _emberRuntimeInject, _emberRuntimeSystemNamespace, _emberRuntimeSystemObject, _emberRuntimeSystemContainer, _emberRuntimeSystemArray_proxy, _emberRuntimeSystemObject_proxy, _emberRuntimeSystemCore_object, _emberRuntimeSystemNative_array, _emberRuntimeSystemString, _emberRuntimeSystemLazy_load, _emberRuntimeMixinsArray, _emberRuntimeMixinsComparable, _emberRuntimeMixinsCopyable, _emberRuntimeMixinsEnumerable, _emberRuntimeMixinsFreezable, _emberRuntimeMixinsProxy, _emberRuntimeMixinsObservable, _emberRuntimeMixinsAction_handler, _emberRuntimeMixinsMutable_enumerable, _emberRuntimeMixinsMutable_array, _emberRuntimeMixinsTarget_action_support, _emberRuntimeMixinsEvented, _emberRuntimeMixinsPromise_proxy, _emberRuntimeComputedReduce_computed_macros, _emberRuntimeControllersController, _emberRuntimeMixinsController, _emberRuntimeSystemService, _emberRuntimeExtRsvp, _emberRuntimeExtString, _emberRuntimeExtFunction, _emberRuntimeUtils, _emberMetalFeatures, _emberRuntimeMixinsReg
42351istry_proxy, _emberRuntimeMixinsContainer_proxy, _emberRuntimeString_registry) {
42352  /**
42353  @module ember
42354  @submodule ember-runtime
42355  */
42356
42357  // BEGIN IMPORTS
42358  'use strict';
42359
42360  // END IMPORTS
42361
42362  // BEGIN EXPORTS
42363  _emberMetal.default.compare = _emberRuntimeCompare.default;
42364  _emberMetal.default.copy = _emberRuntimeCopy.default;
42365  _emberMetal.default.isEqual = _emberRuntimeIsEqual.default;
42366
42367  _emberMetal.default.inject = _emberRuntimeInject.default;
42368
42369  _emberMetal.default.Array = _emberRuntimeMixinsArray.default;
42370
42371  _emberMetal.default.Comparable = _emberRuntimeMixinsComparable.default;
42372  _emberMetal.default.Copyable = _emberRuntimeMixinsCopyable.default;
42373
42374  _emberMetal.default.Freezable = _emberRuntimeMixinsFreezable.Freezable;
42375  _emberMetal.default.FROZEN_ERROR = _emberRuntimeMixinsFreezable.FROZEN_ERROR;
42376
42377  _emberMetal.default.MutableEnumerable = _emberRuntimeMixinsMutable_enumerable.default;
42378  _emberMetal.default.MutableArray = _emberRuntimeMixinsMutable_array.default;
42379
42380  _emberMetal.default.TargetActionSupport = _emberRuntimeMixinsTarget_action_support.default;
42381  _emberMetal.default.Evented = _emberRuntimeMixinsEvented.default;
42382
42383  _emberMetal.default.PromiseProxyMixin = _emberRuntimeMixinsPromise_proxy.default;
42384
42385  _emberMetal.default.Observable = _emberRuntimeMixinsObservable.default;
42386
42387  _emberMetal.default.typeOf = _emberRuntimeUtils.typeOf;
42388  _emberMetal.default.isArray = _emberRuntimeUtils.isArray;
42389
42390  // ES6TODO: this seems a less than ideal way/place to add properties to Ember.computed
42391  var EmComputed = _emberMetal.default.computed;
42392
42393  EmComputed.sum = _emberRuntimeComputedReduce_computed_macros.sum;
42394  EmComputed.min = _emberRuntimeComputedReduce_computed_macros.min;
42395  EmComputed.max = _emberRuntimeComputedReduce_computed_macros.max;
42396  EmComputed.map = _emberRuntimeComputedReduce_computed_macros.map;
42397  EmComputed.sort = _emberRuntimeComputedReduce_computed_macros.sort;
42398  EmComputed.setDiff = _emberRuntimeComputedReduce_computed_macros.setDiff;
42399  EmComputed.mapBy = _emberRuntimeComputedReduce_computed_macros.mapBy;
42400  EmComputed.filter = _emberRuntimeComputedReduce_computed_macros.filter;
42401  EmComputed.filterBy = _emberRuntimeComputedReduce_computed_macros.filterBy;
42402  EmComputed.uniq = _emberRuntimeComputedReduce_computed_macros.uniq;
42403  EmComputed.union = _emberRuntimeComputedReduce_computed_macros.union;
42404  EmComputed.intersect = _emberRuntimeComputedReduce_computed_macros.intersect;
42405  EmComputed.collect = _emberRuntimeComputedReduce_computed_macros.collect;
42406
42407  _emberMetal.default.String = _emberRuntimeSystemString.default;
42408  _emberMetal.default.Object = _emberRuntimeSystemObject.default;
42409  _emberMetal.default.Container = _emberRuntimeSystemContainer.Container;
42410  _emberMetal.default.Registry = _emberRuntimeSystemContainer.Registry;
42411
42412  _emberMetal.default.getOwner = _emberRuntimeSystemContainer.getOwner;
42413  _emberMetal.default.setOwner = _emberRuntimeSystemContainer.setOwner;
42414
42415  _emberMetal.default._RegistryProxyMixin = _emberRuntimeMixinsRegistry_proxy.default;
42416  _emberMetal.default._ContainerProxyMixin = _emberRuntimeMixinsContainer_proxy.default;
42417
42418  _emberMetal.default.Namespace = _emberRuntimeSystemNamespace.default;
42419  _emberMetal.default.Enumerable = _emberRuntimeMixinsEnumerable.default;
42420  _emberMetal.default.ArrayProxy = _emberRuntimeSystemArray_proxy.default;
42421  _emberMetal.default.ObjectProxy = _emberRuntimeSystemObject_proxy.default;
42422  _emberMetal.default.ActionHandler = _emberRuntimeMixinsAction_handler.default;
42423  _emberMetal.default.CoreObject = _emberRuntimeSystemCore_object.default;
42424  _emberMetal.default.NativeArray = _emberRuntimeSystemNative_array.default;
42425  // ES6TODO: Currently we must rely on the global from ember-metal/core to avoid circular deps
42426  // Ember.A = A;
42427  _emberMetal.default.onLoad = _emberRuntimeSystemLazy_load.onLoad;
42428  _emberMetal.default.runLoadHooks = _emberRuntimeSystemLazy_load.runLoadHooks;
42429
42430  _emberMetal.default.Controller = _emberRuntimeControllersController.default;
42431  _emberMetal.default.ControllerMixin = _emberRuntimeMixinsController.default;
42432
42433  _emberMetal.default.Service = _emberRuntimeSystemService.default;
42434
42435  _emberMetal.default._ProxyMixin = _emberRuntimeMixinsProxy.default;
42436
42437  _emberMetal.default.RSVP = _emberRuntimeExtRsvp.default;
42438  // END EXPORTS
42439
42440  /**
42441    Defines the hash of localized strings for the current language. Used by
42442    the `Ember.String.loc()` helper. To localize, add string values to this
42443    hash.
42444  
42445    @property STRINGS
42446    @for Ember
42447    @type Object
42448    @private
42449  */
42450  Object.defineProperty(_emberMetal.default, 'STRINGS', {
42451    configurable: false,
42452    get: _emberRuntimeString_registry.getStrings,
42453    set: _emberRuntimeString_registry.setStrings
42454  });
42455
42456  exports.default = _emberMetal.default;
42457});
42458// just for side effect of extending Ember.RSVP
42459// just for side effect of extending String.prototype
42460// just for side effect of extending Function.prototype
42461enifed('ember-runtime/inject', ['exports', 'ember-metal/debug', 'ember-metal/injected_property'], function (exports, _emberMetalDebug, _emberMetalInjected_property) {
42462  'use strict';
42463
42464  exports.default = inject;
42465  exports.createInjectionHelper = createInjectionHelper;
42466  exports.validatePropertyInjections = validatePropertyInjections;
42467
42468  /**
42469    Namespace for injection helper methods.
42470  
42471    @class inject
42472    @namespace Ember
42473    @static
42474    @public
42475  */
42476
42477  function inject() {
42478    _emberMetalDebug.assert('Injected properties must be created through helpers, see \'' + Object.keys(inject).join('"', '"') + '\'');
42479  }
42480
42481  // Dictionary of injection validations by type, added to by `createInjectionHelper`
42482  var typeValidators = {};
42483
42484  /**
42485    This method allows other Ember modules to register injection helpers for a
42486    given container type. Helpers are exported to the `inject` namespace as the
42487    container type itself.
42488  
42489    @private
42490    @method createInjectionHelper
42491    @since 1.10.0
42492    @for Ember
42493    @param {String} type The container type the helper will inject
42494    @param {Function} validator A validation callback that is executed at mixin-time
42495  */
42496
42497  function createInjectionHelper(type, validator) {
42498    typeValidators[type] = validator;
42499
42500    inject[type] = function (name) {
42501      return new _emberMetalInjected_property.default(type, name);
42502    };
42503  }
42504
42505  /**
42506    Validation function that runs per-type validation functions once for each
42507    injected type encountered.
42508  
42509    @private
42510    @method validatePropertyInjections
42511    @since 1.10.0
42512    @for Ember
42513    @param {Object} factory The factory object
42514  */
42515
42516  function validatePropertyInjections(factory) {
42517    var proto = factory.proto();
42518    var types = [];
42519    var key, desc, validator, i, l;
42520
42521    for (key in proto) {
42522      desc = proto[key];
42523      if (desc instanceof _emberMetalInjected_property.default && types.indexOf(desc.type) === -1) {
42524        types.push(desc.type);
42525      }
42526    }
42527
42528    if (types.length) {
42529      for (i = 0, l = types.length; i < l; i++) {
42530        validator = typeValidators[types[i]];
42531
42532        if (typeof validator === 'function') {
42533          validator(factory);
42534        }
42535      }
42536    }
42537
42538    return true;
42539  }
42540});
42541enifed('ember-runtime/is-equal', ['exports'], function (exports) {
42542  /**
42543    Compares two objects, returning true if they are equal.
42544  
42545    ```javascript
42546    Ember.isEqual('hello', 'hello');                   // true
42547    Ember.isEqual(1, 2);                               // false
42548    ```
42549  
42550    `isEqual` is a more specific comparison than a triple equal comparison.
42551    It will call the `isEqual` instance method on the objects being
42552    compared, allowing finer control over when objects should be considered
42553    equal to each other.
42554  
42555    ```javascript
42556    let Person = Ember.Object.extend({
42557      isEqual(other) { return this.ssn == other.ssn; }
42558    });
42559  
42560    let personA = Person.create({name: 'Muhammad Ali', ssn: '123-45-6789'});
42561    let personB = Person.create({name: 'Cassius Clay', ssn: '123-45-6789'});
42562  
42563    Ember.isEqual(personA, personB); // true
42564    ```
42565  
42566    Due to the expense of array comparisons, collections will never be equal to
42567    each other even if each of their items are equal to each other.
42568  
42569    ```javascript
42570    Ember.isEqual([4, 2], [4, 2]);                     // false
42571    ```
42572  
42573    @method isEqual
42574    @for Ember
42575    @param {Object} a first object to compare
42576    @param {Object} b second object to compare
42577    @return {Boolean}
42578    @public
42579  */
42580  'use strict';
42581
42582  exports.default = isEqual;
42583
42584  function isEqual(a, b) {
42585    if (a && typeof a.isEqual === 'function') {
42586      return a.isEqual(b);
42587    }
42588
42589    if (a instanceof Date && b instanceof Date) {
42590      return a.getTime() === b.getTime();
42591    }
42592
42593    return a === b;
42594  }
42595});
42596enifed('ember-runtime/mixins/-proxy', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/meta', 'ember-metal/observer', 'ember-metal/property_events', 'ember-metal/computed', 'ember-metal/properties', 'ember-metal/mixin'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalMeta, _emberMetalObserver, _emberMetalProperty_events, _emberMetalComputed, _emberMetalProperties, _emberMetalMixin) {
42597  /**
42598  @module ember
42599  @submodule ember-runtime
42600  */
42601
42602  'use strict';
42603
42604  function contentPropertyWillChange(content, contentKey) {
42605    var key = contentKey.slice(8); // remove "content."
42606    if (key in this) {
42607      return;
42608    } // if shadowed in proxy
42609    _emberMetalProperty_events.propertyWillChange(this, key);
42610  }
42611
42612  function contentPropertyDidChange(content, contentKey) {
42613    var key = contentKey.slice(8); // remove "content."
42614    if (key in this) {
42615      return;
42616    } // if shadowed in proxy
42617    _emberMetalProperty_events.propertyDidChange(this, key);
42618  }
42619
42620  /**
42621    `Ember.ProxyMixin` forwards all properties not defined by the proxy itself
42622    to a proxied `content` object.  See Ember.ObjectProxy for more details.
42623  
42624    @class ProxyMixin
42625    @namespace Ember
42626    @private
42627  */
42628  exports.default = _emberMetalMixin.Mixin.create({
42629    /**
42630      The object whose properties will be forwarded.
42631       @property content
42632      @type Ember.Object
42633      @default null
42634      @private
42635    */
42636    content: null,
42637    _contentDidChange: _emberMetalMixin.observer('content', function () {
42638      _emberMetalDebug.assert('Can\'t set Proxy\'s content to itself', _emberMetalProperty_get.get(this, 'content') !== this);
42639    }),
42640
42641    isTruthy: _emberMetalComputed.computed.bool('content'),
42642
42643    _debugContainerKey: null,
42644
42645    willWatchProperty: function (key) {
42646      var contentKey = 'content.' + key;
42647      _emberMetalObserver._addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
42648      _emberMetalObserver.addObserver(this, contentKey, null, contentPropertyDidChange);
42649    },
42650
42651    didUnwatchProperty: function (key) {
42652      var contentKey = 'content.' + key;
42653      _emberMetalObserver._removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
42654      _emberMetalObserver.removeObserver(this, contentKey, null, contentPropertyDidChange);
42655    },
42656
42657    unknownProperty: function (key) {
42658      var content = _emberMetalProperty_get.get(this, 'content');
42659      if (content) {
42660        _emberMetalDebug.deprecate('You attempted to access `' + key + '` from `' + this + '`, but object proxying is deprecated. Please use `model.' + key + '` instead.', !this.isController, { id: 'ember-runtime.controller-proxy', until: '3.0.0' });
42661        return _emberMetalProperty_get.get(content, key);
42662      }
42663    },
42664
42665    setUnknownProperty: function (key, value) {
42666      var m = _emberMetalMeta.meta(this);
42667      if (m.proto === this) {
42668        // if marked as prototype then just defineProperty
42669        // rather than delegate
42670        _emberMetalProperties.defineProperty(this, key, null, value);
42671        return value;
42672      }
42673
42674      var content = _emberMetalProperty_get.get(this, 'content');
42675      _emberMetalDebug.assert('Cannot delegate set(\'' + key + '\', ' + value + ') to the \'content\' property of object proxy ' + this + ': its \'content\' is undefined.', content);
42676
42677      _emberMetalDebug.deprecate('You attempted to set `' + key + '` from `' + this + '`, but object proxying is deprecated. Please use `model.' + key + '` instead.', !this.isController, { id: 'ember-runtime.controller-proxy', until: '3.0.0' });
42678      return _emberMetalProperty_set.set(content, key, value);
42679    }
42680
42681  });
42682});
42683enifed('ember-runtime/mixins/action_handler', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-metal/property_get'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberMetalProperty_get) {
42684  /**
42685  @module ember
42686  @submodule ember-runtime
42687  */
42688
42689  'use strict';
42690
42691  exports.deprecateUnderscoreActions = deprecateUnderscoreActions;
42692
42693  /**
42694    `Ember.ActionHandler` is available on some familiar classes including
42695    `Ember.Route`, `Ember.View`, `Ember.Component`, and `Ember.Controller`.
42696    (Internally the mixin is used by `Ember.CoreView`, `Ember.ControllerMixin`,
42697    and `Ember.Route` and available to the above classes through
42698    inheritance.)
42699  
42700    @class ActionHandler
42701    @namespace Ember
42702    @private
42703  */
42704  var ActionHandler = _emberMetalMixin.Mixin.create({
42705    mergedProperties: ['actions'],
42706
42707    /**
42708      The collection of functions, keyed by name, available on this
42709      `ActionHandler` as action targets.
42710       These functions will be invoked when a matching `{{action}}` is triggered
42711      from within a template and the application's current route is this route.
42712       Actions can also be invoked from other parts of your application
42713      via `ActionHandler#send`.
42714       The `actions` hash will inherit action handlers from
42715      the `actions` hash defined on extended parent classes
42716      or mixins rather than just replace the entire hash, e.g.:
42717       ```js
42718      App.CanDisplayBanner = Ember.Mixin.create({
42719        actions: {
42720          displayBanner: function(msg) {
42721            // ...
42722          }
42723        }
42724      });
42725       App.WelcomeRoute = Ember.Route.extend(App.CanDisplayBanner, {
42726        actions: {
42727          playMusic: function() {
42728            // ...
42729          }
42730        }
42731      });
42732       // `WelcomeRoute`, when active, will be able to respond
42733      // to both actions, since the actions hash is merged rather
42734      // then replaced when extending mixins / parent classes.
42735      this.send('displayBanner');
42736      this.send('playMusic');
42737      ```
42738       Within a Controller, Route, View or Component's action handler,
42739      the value of the `this` context is the Controller, Route, View or
42740      Component object:
42741       ```js
42742      App.SongRoute = Ember.Route.extend({
42743        actions: {
42744          myAction: function() {
42745            this.controllerFor("song");
42746            this.transitionTo("other.route");
42747            ...
42748          }
42749        }
42750      });
42751      ```
42752       It is also possible to call `this._super(...arguments)` from within an
42753      action handler if it overrides a handler defined on a parent
42754      class or mixin:
42755       Take for example the following routes:
42756       ```js
42757      App.DebugRoute = Ember.Mixin.create({
42758        actions: {
42759          debugRouteInformation: function() {
42760            console.debug("trololo");
42761          }
42762        }
42763      });
42764       App.AnnoyingDebugRoute = Ember.Route.extend(App.DebugRoute, {
42765        actions: {
42766          debugRouteInformation: function() {
42767            // also call the debugRouteInformation of mixed in App.DebugRoute
42768            this._super(...arguments);
42769             // show additional annoyance
42770            window.alert(...);
42771          }
42772        }
42773      });
42774      ```
42775       ## Bubbling
42776       By default, an action will stop bubbling once a handler defined
42777      on the `actions` hash handles it. To continue bubbling the action,
42778      you must return `true` from the handler:
42779       ```js
42780      App.Router.map(function() {
42781        this.route("album", function() {
42782          this.route("song");
42783        });
42784      });
42785       App.AlbumRoute = Ember.Route.extend({
42786        actions: {
42787          startPlaying: function() {
42788          }
42789        }
42790      });
42791       App.AlbumSongRoute = Ember.Route.extend({
42792        actions: {
42793          startPlaying: function() {
42794            // ...
42795             if (actionShouldAlsoBeTriggeredOnParentRoute) {
42796              return true;
42797            }
42798          }
42799        }
42800      });
42801      ```
42802       @property actions
42803      @type Object
42804      @default null
42805      @public
42806    */
42807
42808    /**
42809      Triggers a named action on the `ActionHandler`. Any parameters
42810      supplied after the `actionName` string will be passed as arguments
42811      to the action target function.
42812       If the `ActionHandler` has its `target` property set, actions may
42813      bubble to the `target`. Bubbling happens when an `actionName` can
42814      not be found in the `ActionHandler`'s `actions` hash or if the
42815      action target function returns `true`.
42816       Example
42817       ```js
42818      App.WelcomeRoute = Ember.Route.extend({
42819        actions: {
42820          playTheme: function() {
42821             this.send('playMusic', 'theme.mp3');
42822          },
42823          playMusic: function(track) {
42824            // ...
42825          }
42826        }
42827      });
42828      ```
42829       @method send
42830      @param {String} actionName The action to trigger
42831      @param {*} context a context to send with the action
42832      @public
42833    */
42834    send: function (actionName) {
42835      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
42836        args[_key - 1] = arguments[_key];
42837      }
42838
42839      var target;
42840
42841      if (this.actions && this.actions[actionName]) {
42842        var shouldBubble = this.actions[actionName].apply(this, args) === true;
42843        if (!shouldBubble) {
42844          return;
42845        }
42846      }
42847
42848      if (target = _emberMetalProperty_get.get(this, 'target')) {
42849        var _target;
42850
42851        _emberMetalDebug.assert('The `target` for ' + this + ' (' + target + ') does not have a `send` method', typeof target.send === 'function');
42852        (_target = target).send.apply(_target, arguments);
42853      }
42854    },
42855
42856    willMergeMixin: function (props) {
42857      _emberMetalDebug.assert('Specifying `_actions` and `actions` in the same mixin is not supported.', !props.actions || !props._actions);
42858
42859      if (props._actions) {
42860        _emberMetalDebug.deprecate('Specifying actions in `_actions` is deprecated, please use `actions` instead.', false, { id: 'ember-runtime.action-handler-_actions', until: '3.0.0' });
42861
42862        props.actions = props._actions;
42863        delete props._actions;
42864      }
42865    }
42866  });
42867
42868  exports.default = ActionHandler;
42869
42870  function deprecateUnderscoreActions(factory) {
42871    Object.defineProperty(factory.prototype, '_actions', {
42872      configurable: true,
42873      enumerable: false,
42874      set: function (value) {
42875        _emberMetalDebug.assert('You cannot set `_actions` on ' + this + ', please use `actions` instead.');
42876      },
42877      get: function () {
42878        _emberMetalDebug.deprecate('Usage of `_actions` is deprecated, use `actions` instead.', false, { id: 'ember-runtime.action-handler-_actions', until: '3.0.0' });
42879        return _emberMetalProperty_get.get(this, 'actions');
42880      }
42881    });
42882  }
42883});
42884enifed('ember-runtime/mixins/array', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/computed', 'ember-metal/is_none', 'ember-runtime/mixins/enumerable', 'ember-metal/mixin', 'ember-metal/property_events', 'ember-metal/events', 'ember-runtime/system/each_proxy'], function (exports, _emberMetalCore, _emberMetalProperty_get, _emberMetalComputed, _emberMetalIs_none, _emberRuntimeMixinsEnumerable, _emberMetalMixin, _emberMetalProperty_events, _emberMetalEvents, _emberRuntimeSystemEach_proxy) {
42885  /**
42886  @module ember
42887  @submodule ember-runtime
42888  */
42889
42890  // ..........................................................
42891  // HELPERS
42892  //
42893  'use strict';
42894
42895  exports.addArrayObserver = addArrayObserver;
42896  exports.removeArrayObserver = removeArrayObserver;
42897  exports.objectAt = objectAt;
42898
42899  function arrayObserversHelper(obj, target, opts, operation, notify) {
42900    var willChange = opts && opts.willChange || 'arrayWillChange';
42901    var didChange = opts && opts.didChange || 'arrayDidChange';
42902    var hasObservers = _em
42902berMetalProperty_get.get(obj, 'hasArrayObservers');
42903
42904    if (hasObservers === notify) {
42905      _emberMetalProperty_events.propertyWillChange(obj, 'hasArrayObservers');
42906    }
42907
42908    operation(obj, '@array:before', target, willChange);
42909    operation(obj, '@array:change', target, didChange);
42910
42911    if (hasObservers === notify) {
42912      _emberMetalProperty_events.propertyDidChange(obj, 'hasArrayObservers');
42913    }
42914
42915    return obj;
42916  }
42917
42918  function addArrayObserver(array, target, opts) {
42919    return arrayObserversHelper(array, target, opts, _emberMetalEvents.addListener, false);
42920  }
42921
42922  function removeArrayObserver(array, target, opts) {
42923    return arrayObserversHelper(array, target, opts, _emberMetalEvents.removeListener, true);
42924  }
42925
42926  function objectAt(content, idx) {
42927    if (content.objectAt) {
42928      return content.objectAt(idx);
42929    }
42930
42931    return content[idx];
42932  }
42933
42934  // ..........................................................
42935  // ARRAY
42936  //
42937  /**
42938    This mixin implements Observer-friendly Array-like behavior. It is not a
42939    concrete implementation, but it can be used up by other classes that want
42940    to appear like arrays.
42941  
42942    For example, ArrayProxy is a concrete classes that can
42943    be instantiated to implement array-like behavior. Both of these classes use
42944    the Array Mixin by way of the MutableArray mixin, which allows observable
42945    changes to be made to the underlying array.
42946  
42947    Unlike `Ember.Enumerable,` this mixin defines methods specifically for
42948    collections that provide index-ordered access to their contents. When you
42949    are designing code that needs to accept any kind of Array-like object, you
42950    should use these methods instead of Array primitives because these will
42951    properly notify observers of changes to the array.
42952  
42953    Although these methods are efficient, they do add a layer of indirection to
42954    your application so it is a good idea to use them only when you need the
42955    flexibility of using both true JavaScript arrays and "virtual" arrays such
42956    as controllers and collections.
42957  
42958    You can use the methods defined in this module to access and modify array
42959    contents in a KVO-friendly way. You can also be notified whenever the
42960    membership of an array changes by using `.observes('myArray.[]')`.
42961  
42962    To support `Ember.Array` in your own class, you must override two
42963    primitives to use it: `length()` and `objectAt()`.
42964  
42965    Note that the Ember.Array mixin also incorporates the `Ember.Enumerable`
42966    mixin. All `Ember.Array`-like objects are also enumerable.
42967  
42968    @class Array
42969    @namespace Ember
42970    @uses Ember.Enumerable
42971    @since Ember 0.9.0
42972    @public
42973  */
42974  exports.default = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsEnumerable.default, {
42975
42976    /**
42977      __Required.__ You must implement this method to apply this mixin.
42978       Your array must support the `length` property. Your replace methods should
42979      set this property whenever it changes.
42980       @property {Number} length
42981      @public
42982    */
42983    length: null,
42984
42985    /**
42986      Returns the object at the given `index`. If the given `index` is negative
42987      or is greater or equal than the array length, returns `undefined`.
42988       This is one of the primitives you must implement to support `Ember.Array`.
42989      If your object supports retrieving the value of an array item using `get()`
42990      (i.e. `myArray.get(0)`), then you do not need to implement this method
42991      yourself.
42992       ```javascript
42993      var arr = ['a', 'b', 'c', 'd'];
42994       arr.objectAt(0);   // 'a'
42995      arr.objectAt(3);   // 'd'
42996      arr.objectAt(-1);  // undefined
42997      arr.objectAt(4);   // undefined
42998      arr.objectAt(5);   // undefined
42999      ```
43000       @method objectAt
43001      @param {Number} idx The index of the item to return.
43002      @return {*} item at index or undefined
43003      @public
43004    */
43005    objectAt: function (idx) {
43006      if (idx < 0 || idx >= _emberMetalProperty_get.get(this, 'length')) {
43007        return undefined;
43008      }
43009
43010      return _emberMetalProperty_get.get(this, idx);
43011    },
43012
43013    /**
43014      This returns the objects at the specified indexes, using `objectAt`.
43015       ```javascript
43016      var arr = ['a', 'b', 'c', 'd'];
43017       arr.objectsAt([0, 1, 2]);  // ['a', 'b', 'c']
43018      arr.objectsAt([2, 3, 4]);  // ['c', 'd', undefined]
43019      ```
43020       @method objectsAt
43021      @param {Array} indexes An array of indexes of items to return.
43022      @return {Array}
43023      @public
43024     */
43025    objectsAt: function (indexes) {
43026      var _this = this;
43027
43028      return indexes.map(function (idx) {
43029        return objectAt(_this, idx);
43030      });
43031    },
43032
43033    // overrides Ember.Enumerable version
43034    nextObject: function (idx) {
43035      return objectAt(this, idx);
43036    },
43037
43038    /**
43039      This is the handler for the special array content property. If you get
43040      this property, it will return this. If you set this property to a new
43041      array, it will replace the current content.
43042       This property overrides the default property defined in `Ember.Enumerable`.
43043       @property []
43044      @return this
43045      @public
43046    */
43047    '[]': _emberMetalComputed.computed({
43048      get: function (key) {
43049        return this;
43050      },
43051      set: function (key, value) {
43052        this.replace(0, _emberMetalProperty_get.get(this, 'length'), value);
43053        return this;
43054      }
43055    }),
43056
43057    firstObject: _emberMetalComputed.computed(function () {
43058      return objectAt(this, 0);
43059    }),
43060
43061    lastObject: _emberMetalComputed.computed(function () {
43062      return objectAt(this, _emberMetalProperty_get.get(this, 'length') - 1);
43063    }),
43064
43065    // optimized version from Enumerable
43066    contains: function (obj) {
43067      return this.indexOf(obj) >= 0;
43068    },
43069
43070    // Add any extra methods to Ember.Array that are native to the built-in Array.
43071    /**
43072      Returns a new array that is a slice of the receiver. This implementation
43073      uses the observable array methods to retrieve the objects for the new
43074      slice.
43075       ```javascript
43076      var arr = ['red', 'green', 'blue'];
43077       arr.slice(0);       // ['red', 'green', 'blue']
43078      arr.slice(0, 2);    // ['red', 'green']
43079      arr.slice(1, 100);  // ['green', 'blue']
43080      ```
43081       @method slice
43082      @param {Number} beginIndex (Optional) index to begin slicing from.
43083      @param {Number} endIndex (Optional) index to end the slice at (but not included).
43084      @return {Array} New array with specified slice
43085      @public
43086    */
43087    slice: function (beginIndex, endIndex) {
43088      var ret = _emberMetalCore.default.A();
43089      var length = _emberMetalProperty_get.get(this, 'length');
43090
43091      if (_emberMetalIs_none.default(beginIndex)) {
43092        beginIndex = 0;
43093      }
43094
43095      if (_emberMetalIs_none.default(endIndex) || endIndex > length) {
43096        endIndex = length;
43097      }
43098
43099      if (beginIndex < 0) {
43100        beginIndex = length + beginIndex;
43101      }
43102
43103      if (endIndex < 0) {
43104        endIndex = length + endIndex;
43105      }
43106
43107      while (beginIndex < endIndex) {
43108        ret[ret.length] = objectAt(this, beginIndex++);
43109      }
43110
43111      return ret;
43112    },
43113
43114    /**
43115      Returns the index of the given object's first occurrence.
43116      If no `startAt` argument is given, the starting location to
43117      search is 0. If it's negative, will count backward from
43118      the end of the array. Returns -1 if no match is found.
43119       ```javascript
43120      var arr = ['a', 'b', 'c', 'd', 'a'];
43121       arr.indexOf('a');       //  0
43122      arr.indexOf('z');       // -1
43123      arr.indexOf('a', 2);    //  4
43124      arr.indexOf('a', -1);   //  4
43125      arr.indexOf('b', 3);    // -1
43126      arr.indexOf('a', 100);  // -1
43127      ```
43128       @method indexOf
43129      @param {Object} object the item to search for
43130      @param {Number} startAt optional starting location to search, default 0
43131      @return {Number} index or -1 if not found
43132      @public
43133    */
43134    indexOf: function (object, startAt) {
43135      var len = _emberMetalProperty_get.get(this, 'length');
43136      var idx;
43137
43138      if (startAt === undefined) {
43139        startAt = 0;
43140      }
43141
43142      if (startAt < 0) {
43143        startAt += len;
43144      }
43145
43146      for (idx = startAt; idx < len; idx++) {
43147        if (objectAt(this, idx) === object) {
43148          return idx;
43149        }
43150      }
43151
43152      return -1;
43153    },
43154
43155    /**
43156      Returns the index of the given object's last occurrence.
43157      If no `startAt` argument is given, the search starts from
43158      the last position. If it's negative, will count backward
43159      from the end of the array. Returns -1 if no match is found.
43160       ```javascript
43161      var arr = ['a', 'b', 'c', 'd', 'a'];
43162       arr.lastIndexOf('a');       //  4
43163      arr.lastIndexOf('z');       // -1
43164      arr.lastIndexOf('a', 2);    //  0
43165      arr.lastIndexOf('a', -1);   //  4
43166      arr.lastIndexOf('b', 3);    //  1
43167      arr.lastIndexOf('a', 100);  //  4
43168      ```
43169       @method lastIndexOf
43170      @param {Object} object the item to search for
43171      @param {Number} startAt optional starting location to search, default 0
43172      @return {Number} index or -1 if not found
43173      @public
43174    */
43175    lastIndexOf: function (object, startAt) {
43176      var len = _emberMetalProperty_get.get(this, 'length');
43177      var idx;
43178
43179      if (startAt === undefined || startAt >= len) {
43180        startAt = len - 1;
43181      }
43182
43183      if (startAt < 0) {
43184        startAt += len;
43185      }
43186
43187      for (idx = startAt; idx >= 0; idx--) {
43188        if (objectAt(this, idx) === object) {
43189          return idx;
43190        }
43191      }
43192
43193      return -1;
43194    },
43195
43196    // ..........................................................
43197    // ARRAY OBSERVERS
43198    //
43199
43200    /**
43201      Adds an array observer to the receiving array. The array observer object
43202      normally must implement two methods:
43203       * `arrayWillChange(observedObj, start, removeCount, addCount)` - This method will be
43204        called just before the array is modified.
43205      * `arrayDidChange(observedObj, start, removeCount, addCount)` - This method will be
43206        called just after the array is modified.
43207       Both callbacks will be passed the observed object, starting index of the
43208      change as well as a count of the items to be removed and added. You can use
43209      these callbacks to optionally inspect the array during the change, clear
43210      caches, or do any other bookkeeping necessary.
43211       In addition to passing a target, you can also include an options hash
43212      which you can use to override the method names that will be invoked on the
43213      target.
43214       @method addArrayObserver
43215      @param {Object} target The observer object.
43216      @param {Object} opts Optional hash of configuration options including
43217        `willChange` and `didChange` option.
43218      @return {Ember.Array} receiver
43219      @public
43220    */
43221
43222    addArrayObserver: function (target, opts) {
43223      return addArrayObserver(this, target, opts);
43224    },
43225
43226    /**
43227      Removes an array observer from the object if the observer is current
43228      registered. Calling this method multiple times with the same object will
43229      have no effect.
43230       @method removeArrayObserver
43231      @param {Object} target The object observing the array.
43232      @param {Object} opts Optional hash of configuration options including
43233        `willChange` and `didChange` option.
43234      @return {Ember.Array} receiver
43235      @public
43236    */
43237    removeArrayObserver: function (target, opts) {
43238      return removeArrayObserver(this, target, opts);
43239    },
43240
43241    /**
43242      Becomes true whenever the array currently has observers watching changes
43243      on the array.
43244       @property {Boolean} hasArrayObservers
43245      @public
43246    */
43247    hasArrayObservers: _emberMetalComputed.computed(function () {
43248      return _emberMetalEvents.hasListeners(this, '@array:change') || _emberMetalEvents.hasListeners(this, '@array:before');
43249    }),
43250
43251    /**
43252      If you are implementing an object that supports `Ember.Array`, call this
43253      method just before the array content changes to notify any observers and
43254      invalidate any related properties. Pass the starting index of the change
43255      as well as a delta of the amounts to change.
43256       @method arrayContentWillChange
43257      @param {Number} startIdx The starting index in the array that will change.
43258      @param {Number} removeAmt The number of items that will be removed. If you
43259        pass `null` assumes 0
43260      @param {Number} addAmt The number of items that will be added. If you
43261        pass `null` assumes 0.
43262      @return {Ember.Array} receiver
43263      @public
43264    */
43265    arrayContentWillChange: function (startIdx, removeAmt, addAmt) {
43266      var removing, lim;
43267
43268      // if no args are passed assume everything changes
43269      if (startIdx === undefined) {
43270        startIdx = 0;
43271        removeAmt = addAmt = -1;
43272      } else {
43273        if (removeAmt === undefined) {
43274          removeAmt = -1;
43275        }
43276
43277        if (addAmt === undefined) {
43278          addAmt = -1;
43279        }
43280      }
43281
43282      if (this.__each) {
43283        this.__each.arrayWillChange(this, startIdx, removeAmt, addAmt);
43284      }
43285
43286      _emberMetalEvents.sendEvent(this, '@array:before', [this, startIdx, removeAmt, addAmt]);
43287
43288      if (startIdx >= 0 && removeAmt >= 0 && _emberMetalProperty_get.get(this, 'hasEnumerableObservers')) {
43289        removing = [];
43290        lim = startIdx + removeAmt;
43291
43292        for (var idx = startIdx; idx < lim; idx++) {
43293          removing.push(objectAt(this, idx));
43294        }
43295      } else {
43296        removing = removeAmt;
43297      }
43298
43299      this.enumerableContentWillChange(removing, addAmt);
43300
43301      return this;
43302    },
43303
43304    /**
43305      If you are implementing an object that supports `Ember.Array`, call this
43306      method just after the array content changes to notify any observers and
43307      invalidate any related properties. Pass the starting index of the change
43308      as well as a delta of the amounts to change.
43309       @method arrayContentDidChange
43310      @param {Number} startIdx The starting index in the array that did change.
43311      @param {Number} removeAmt The number of items that were removed. If you
43312        pass `null` assumes 0
43313      @param {Number} addAmt The number of items that were added. If you
43314        pass `null` assumes 0.
43315      @return {Ember.Array} receiver
43316      @public
43317    */
43318    arrayContentDidChange: function (startIdx, removeAmt, addAmt) {
43319      var adding, lim;
43320
43321      // if no args are passed assume everything changes
43322      if (startIdx === undefined) {
43323        startIdx = 0;
43324        removeAmt = addAmt = -1;
43325      } else {
43326        if (removeAmt === undefined) {
43327          removeAmt = -1;
43328        }
43329
43330        if (addAmt === undefined) {
43331          addAmt = -1;
43332        }
43333      }
43334
43335      if (startIdx >= 0 && addAmt >= 0 && _emberMetalProperty_get.get(this, 'hasEnumerableObservers')) {
43336        adding = [];
43337        lim = startIdx + addAmt;
43338
43339        for (var idx = startIdx; idx < lim; idx++) {
43340          adding.push(objectAt(this, idx));
43341        }
43342      } else {
43343        adding = addAmt;
43344      }
43345
43346      this.enumerableContentDidChange(removeAmt, adding);
43347
43348      if (this.__each) {
43349        this.__each.arrayDidChange(this, startIdx, removeAmt, addAmt);
43350      }
43351
43352      _emberMetalEvents.sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]);
43353
43354      var length = _emberMetalProperty_get.get(this, 'length');
43355      var cachedFirst = _emberMetalComputed.cacheFor(this, 'firstObject');
43356      var cachedLast = _emberMetalComputed.cacheFor(this, 'lastObject');
43357
43358      if (objectAt(this, 0) !== cachedFirst) {
43359        _emberMetalProperty_events.propertyWillChange(this, 'firstObject');
43360        _emberMetalProperty_events.propertyDidChange(this, 'firstObject');
43361      }
43362
43363      if (objectAt(this, length - 1) !== cachedLast) {
43364        _emberMetalProperty_events.propertyWillChange(this, 'lastObject');
43365        _emberMetalProperty_events.propertyDidChange(this, 'lastObject');
43366      }
43367
43368      return this;
43369    },
43370
43371    /**
43372      Returns a special object that can be used to observe individual properties
43373      on the array. Just get an equivalent property on this object and it will
43374      return an enumerable that maps automatically to the named key on the
43375      member objects.
43376       `@each` should only be used in a non-terminal context. Example:
43377       ```javascript
43378      myMethod: computed('[email protected]', function(){
43379        ...
43380      });
43381      ```
43382       If you merely want to watch for the array being changed, like an object being
43383      replaced, added or removed, use `[]` instead of `@each`.
43384       ```javascript
43385      myMethod: computed('posts.[]', function(){
43386        ...
43387      });
43388      ```
43389       @property @each
43390      @public
43391    */
43392    '@each': _emberMetalComputed.computed(function () {
43393      // TODO use Symbol or add to meta
43394      if (!this.__each) {
43395        this.__each = new _emberRuntimeSystemEach_proxy.default(this);
43396      }
43397
43398      return this.__each;
43399    }).volatile()
43400  });
43401});
43402// ES6TODO: Ember.A
43403enifed('ember-runtime/mixins/comparable', ['exports', 'ember-metal/mixin'], function (exports, _emberMetalMixin) {
43404  'use strict';
43405
43406  /**
43407  @module ember
43408  @submodule ember-runtime
43409  */
43410
43411  /**
43412    Implements some standard methods for comparing objects. Add this mixin to
43413    any class you create that can compare its instances.
43414  
43415    You should implement the `compare()` method.
43416  
43417    @class Comparable
43418    @namespace Ember
43419    @since Ember 0.9
43420    @private
43421  */
43422  exports.default = _emberMetalMixin.Mixin.create({
43423
43424    /**
43425      __Required.__ You must implement this method to apply this mixin.
43426       Override to return the result of the comparison of the two parameters. The
43427      compare method should return:
43428       - `-1` if `a < b`
43429      - `0` if `a == b`
43430      - `1` if `a > b`
43431       Default implementation raises an exception.
43432       @method compare
43433      @param a {Object} the first object to compare
43434      @param b {Object} the second object to compare
43435      @return {Number} the result of the comparison
43436      @private
43437    */
43438    compare: null
43439  });
43440});
43441enifed('ember-runtime/mixins/container_proxy', ['exports', 'ember-metal/run_loop', 'ember-metal/debug', 'ember-metal/mixin'], function (exports, _emberMetalRun_loop, _emberMetalDebug, _emberMetalMixin) {
43442  /**
43443  @module ember
43444  @submodule ember-runtime
43445  */
43446  'use strict';
43447
43448  exports.buildFakeContainerWithDeprecations = buildFakeContainerWithDeprecations;
43449
43450  /**
43451    ContainerProxyMixin is used to provide public access to specific
43452    container functionality.
43453  
43454    @class ContainerProxyMixin
43455    @private
43456  */
43457  exports.default = _emberMetalMixin.Mixin.create({
43458    /**
43459     The container stores state.
43460      @private
43461     @property {Ember.Container} __container__
43462     */
43463    __container__: null,
43464
43465    /**
43466     Returns an object that can be used to provide an owner to a
43467     manually created instance.
43468      Example:
43469      ```
43470     let owner = Ember.getOwner(this);
43471      User.create(
43472       owner.ownerInjection(),
43473       { username: 'rwjblue' }
43474     )
43475     ```
43476      @public
43477     @method ownerInjection
43478     @return {Object}
43479    */
43480    ownerInjection: containerAlias('ownerInjection'),
43481
43482    /**
43483     Given a fullName return a corresponding instance.
43484      The default behaviour is for lookup to return a singleton instance.
43485     The singleton is scoped to the container, allowing multiple containers
43486     to all have their own locally scoped singletons.
43487      ```javascript
43488     var registry = new Registry();
43489     var container = registry.container();
43490      registry.register('api:twitter', Twitter);
43491      var twitter = container.lookup('api:twitter');
43492      twitter instanceof Twitter; // => true
43493      // by default the container will return singletons
43494     var twitter2 = container.lookup('api:twitter');
43495     twitter2 instanceof Twitter; // => true
43496      twitter === twitter2; //=> true
43497     ```
43498      If singletons are not wanted an optional flag can be provided at lookup.
43499      ```javascript
43500     var registry = new Registry();
43501     var container = registry.container();
43502      registry.register('api:twitter', Twitter);
43503      var twitter = container.lookup('api:twitter', { singleton: false });
43504     var twitter2 = container.lookup('api:twitter', { singleton: false });
43505      twitter === twitter2; //=> false
43506     ```
43507      @public
43508     @method lookup
43509     @param {String} fullName
43510     @param {Object} options
43511     @return {any}
43512     */
43513    lookup: containerAlias('lookup'),
43514
43515    /**
43516     Given a fullName return the corresponding factory.
43517      @private
43518     @method _lookupFactory
43519     @param {String} fullName
43520     @return {any}
43521     */
43522    _lookupFactory: containerAlias('lookupFactory'),
43523
43524    /**
43525     @private
43526     */
43527    willDestroy: function () {
43528      this._super.apply(this, arguments);
43529
43530      if (this.__container__) {
43531        _emberMetalRun_loop.default(this.__container__, 'destroy');
43532      }
43533    }
43534  });
43535
43536  function containerAlias(name) {
43537    return function () {
43538      var _container__;
43539
43540      return (_container__ = this.__container__)[name].apply(_container__, arguments);
43541    };
43542  }
43543
43544  function buildFakeContainerWithDeprecations(container) {
43545    var fakeContainer = {};
43546    var propertyMappings = {
43547      lookup: 'lookup',
43548      lookupFactory: '_lookupFactory'
43549    };
43550
43551    for (var containerProperty in propertyMappings) {
43552      fakeContainer[containerProperty] = buildFakeContainerFunction(container, containerProperty, propertyMappings[containerProperty]);
43553    }
43554
43555    return fakeContainer;
43556  }
43557
43558  function buildFakeContainerFunction(container, containerProperty, ownerProperty) {
43559    return function () {
43560      _emberMetalDebug.deprecate('Using the injected `container` is deprecated. Please use the `getOwner` helper to access the owner of this object and then call `' + ownerProperty + '` instead.', false, {
43561        id: 'ember-application.injected-container',
43562        until: '3.0.0',
43563        url: 'http://emberjs.com/deprecations/v2.x#toc_injected-container-access'
43564      });
43565      return container[containerProperty].apply(container, arguments);
43566    };
43567  }
43568});
43569enifed('ember-runtime/mixins/controller', ['exports', 'ember-metal/mixin', 'ember-metal/alias', 'ember-runtime/mixins/action_handler', 'ember-runtime/mixins/controller_content_model_alias_deprecation'], function (exports, _emberMetalMixin, _emberMetalAlias, _emberRuntimeMixinsAction_handler, _emberRuntimeMixinsController_content_model_alias_deprecation) {
43570  'use strict';
43571
43572  /**
43573    @class ControllerMixin
43574    @namespace Ember
43575    @uses Ember.ActionHandler
43576    @private
43577  */
43578  exports.default = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsAction_handler.default, _emberRuntimeMixinsController_content_model_alias_deprecation.default, {
43579    /* ducktype as a controller */
43580    isController: true,
43581
43582    /**
43583      The object to which actions from the view should be sent.
43584       For example, when a Handlebars template uses the `{{action}}` helper,
43585      it will attempt to send the action to the view's controller's `target`.
43586       By default, the value of the target property is set to the router, and
43587      is injected when a controller is instantiated. This injection is applied
43588      as part of the application's initialization process. In most cases the
43589      `target` property will automatically be set to the logical consumer of
43590      actions for the controller.
43591       @property target
43592      @default null
43593      @public
43594    */
43595    target: null,
43596
43597    parentController: null,
43598
43599    store: null,
43600
43601    /**
43602      The controller's current model. When retrieving or modifying a controller's
43603      model, this property should be used instead of the `content` property.
43604       @property model
43605      @public
43606     */
43607    model: null,
43608
43609    /**
43610      @private
43611    */
43612    content: _emberMetalAlias.default('model')
43613
43614  });
43615});
43616enifed('ember-runtime/mixins/controller_content_model_alias_deprecation', ['exports', 'ember-metal/debug', 'ember-metal/mixin'], function (exports, _emberMetalDebug, _emberMetalMixin) {
43617  'use strict';
43618
43619  /*
43620    The ControllerContentModelAliasDeprecation mixin is used to provide a useful
43621    deprecation warning when specifying `content` directly on a `Ember.Controller`
43622    (without also specifying `model`).
43623  
43624    Ember versions prior to 1.7 used `model` as an alias of `content`, but due to
43625    much confusion this alias was reversed (so `content` is now an alias of `model).
43626  
43627    This change reduces many caveats with model/content, and also sets a
43628    simple ground rule: Never set a controllers content, rather always set
43629    its model and ember will do the right thing.
43630  
43631    Used internally by Ember in `Ember.Controller`.
43632  */
43633  exports.default = _emberMetalMixin.Mixin.create({
43634    /**
43635      @private
43636       Moves `content` to `model`  at extend time if a `model` is not also specified.
43637       Note that this currently modifies the mixin themselves, which is technically
43638      dubious but is practically of little consequence. This may change in the
43639      future.
43640       @method willMergeMixin
43641      @since 1.4.0
43642    */
43643    willMergeMixin: function (props) {
43644      // Calling super is only OK here since we KNOW that
43645      // there is another Mixin loaded first.
43646      this._super.apply(this, arguments);
43647
43648      var modelSpecified = !!props.model;
43649
43650      if (props.content && !modelSpecified) {
43651        props.model = props.content;
43652        delete props['content'];
43653
43654        _emberMetalDebug.deprecate('Do not specify `content` on a Controller, use `model` instead.', false, { id: 'ember-runtime.will-merge-mixin', until: '3.0.0' });
43655      }
43656    }
43657  });
43658});
43659enifed('ember-runtime/mixins/copyable', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/mixin', 'ember-runtime/mixins/freezable', 'ember-metal/error'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalMixin, _emberRuntimeMixinsFreezable, _emberMetalError) {
43660  /**
43661  @module ember
43662  @submodule ember-runtime
43663  */
43664
43665  'use strict';
43666
43667  /**
43668    Implements some standard methods for copying an object. Add this mixin to
43669    any object you create that can create a copy of itself. This mixin is
43670    added automatically to the built-in array.
43671  
43672    You should generally implement the `copy()` method to return a copy of the
43673    receiver.
43674  
43675    Note that `frozenCopy()` will only work if you also implement
43676    `Ember.Freezable`.
43677  
43678    @class Copyable
43679    @namespace Ember
43680    @since Ember 0.9
43681    @private
43682  */
43683  exports.default = _emberMetalMixin.Mixin.create({
43684    /**
43685      __Required.__ You must implement this method to apply this mixin.
43686       Override to return a copy of the receiver. Default implementation raises
43687      an exception.
43688       @method copy
43689      @param {Boolean} deep if `true`, a deep copy of the object should be made
43690      @return {Object} copy of receiver
43691      @private
43692    */
43693    copy: null,
43694
43695    /**
43696      If the object implements `Ember.Freezable`, then this will return a new
43697      copy if the object is not frozen and the receiver if the object is frozen.
43698       Raises an exception if you try to call this method on a object that does
43699      not support freezing.
43700       You should use this method whenever you want a copy of a freezable object
43701      since a freezable object can simply return itself without actually
43702      consuming more memory.
43703       @method frozenCopy
43704      @return {Object} copy of receiver or receiver
43705      @deprecated Use `Object.freeze` instead.
43706      @private
43707    */
43708    frozenCopy: function () {
43709      _emberMetalDebug.deprecate('`frozenCopy` is deprecated, use `Object.freeze` instead.', false, { id: 'ember-runtime.frozen-copy', until: '3.0.0' });
43710      if (_emberRuntimeMixinsFreezable.Freezable && _emberRuntimeMixinsFreezable.Freezable.detect(this)) {
43711        return _emberMetalProperty_get.get(this, 'isFrozen') ? this : this.copy().freeze();
43712      } else {
43713        throw new _emberMetalError.default(this + ' does not support freezing');
43714      }
43715    }
43716  });
43717});
43718enifed('ember-runtime/mixins/enumerable', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/mixin', 'ember-metal/computed', 'ember-metal/property_events', 'ember-metal/events', 'ember-runtime/compare', 'require'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalMixin, _emberMetalComputed, _emberMetalProperty_events, _emberMetalEvents, _emberRuntimeCompare, _require) {
43719  /**
43720  @module ember
43721  @submodule ember-runtime
43722  */
43723
43724  // ..........................................................
43725  // HELPERS
43726  //
43727
43728  'use strict';
43729
43730  var _emberA = undefined;
43731
43732  function emberA() {
43733    return (_emberA || (_emberA = _require.default('ember-runtime/system/native_array').A))();
43734  }
43735
43736  var contexts = [];
43737
43738  function popCtx() {
43739    return contexts.length === 0 ? {} : contexts.pop();
43740  }
43741
43742  function pushCtx(ctx) {
43743    contexts.push(ctx);
43744    return null;
43745  }
43746
43747  function iter(key, value) {
43748    var valueProvided = arguments.length === 2;
43749
43750    function i(item) {
43751      var cur = _emberMetalProperty_get.get(item, key);
43752      return valueProvided ? value === cur : !!cur;
43753    }
43754
43755    return i;
43756  }
43757
43758  /**
43759    This mixin defines the common interface implemented by enumerable objects
43760    in Ember. Most of these methods follow the standard Array iteration
43761    API defined up to JavaScript 1.8 (excluding language-specific features that
43762    cannot be emulated in older versions of JavaScript).
43763  
43764    This mixin is applied automatically to the Array class on page load, so you
43765    can use any of these methods on simple arrays. If Array already implements
43766    one of these methods, the mixin will not override them.
43767  
43768    ## Writing Your Own Enumerable
43769  
43770    To make your own custom class enumerable, you need two items:
43771  
43772    1. You must have a length property. This property should change whenever
43773       the number of items in your enumerable object changes. If you use this
43774       with an `Ember.Object` subclass, you should be sure to change the length
43775       property using `set().`
43776  
43777    2. You must implement `nextObject().` See documentation.
43778  
43779    Once you have these two methods implemented, apply the `Ember.Enumerable` mixin
43780    to your class and you will be able to enumerate the contents of your object
43781    like any other collection.
43782  
43783    ## Using Ember Enumeration with Other Libraries
43784  
43785    Many other libraries provide some kind of iterator or enumeration like
43786    facility. This is often where the most common API conflicts occur.
43787    Ember's API is designed to be as friendly as possible with other
43788    libraries by implementing only methods that mostly correspond to the
43789    JavaScript 1.8 API.
43790  
43791    @class Enumerable
43792    @namespace Ember
43793    @since Ember 0.9
43794    @private
43795  */
43796  exports.default = _emberMetalMixin.Mixin.create({
43797
43798    /**
43799      __Required.__ You must implement this method to apply this mixin.
43800       Implement this method to make your class enumerable.
43801       This method will be called repeatedly during enumeration. The index value
43802      will always begin with 0 and increment monotonically. You don't have to
43803      rely on the index value to determine what object to return, but you should
43804      always check the value and start from the beginning when you see the
43805      requested index is 0.
43806       The `previousObject` is the object that was returned from the last call
43807      to `nextObject` for the current iteration. This is a useful way to
43808      manage iteration if you are tracing a linked list, for example.
43809       Finally the context parameter will always contain a hash you can use as
43810      a "scratchpad" to maintain any other state you need in order to iterate
43811      properly. The context object is reused and is not reset between
43812      iterations so make sure you setup the context with a fresh state whenever
43813      the index parameter is 0.
43814       Generally iterators will continue to call `nextObject` until the index
43815      reaches the current length-1. If you run out of data before this
43816      time for some reason, you should simply return undefined.
43817       The default implementation of this method simply looks up the index.
43818      This works great on any Array-like objects.
43819       @method nextObject
43820      @param {Number} index the current index of the iteration
43821      @param {Object} previousObject the value returned by the last call to
43822        `nextObject`.
43823      @param {Object} context a context object you can use to maintain state.
43824      @return {Object} the next object in the iteration or undefined
43825      @private
43826    */
43827    nextObject: null,
43828
43829    /**
43830      Helper method returns the first object from a collection. This is usually
43831      used by bindings and other parts of the framework to extract a single
43832      object if the enumerable contains only one item.
43833       If you override this method, you should implement it so that it will
43834      always return the same value each time it is called. If your enumerable
43835      contains only one object, this method should always return that object.
43836      If your enumerable is empty, this method should return `undefined`.
43837       ```javascript
43838      var arr = ['a', 'b', 'c'];
43839      arr.get('firstObject');  // 'a'
43840       var arr = [];
43841      arr.get('firstObject');  // undefined
43842      ```
43843       @property firstObject
43844      @return {Object} the object or undefined
43845      @readOnly
43846      @public
43847    */
43848    firstObject: _emberMetalComputed.computed('[]', function () {
43849      if (_emberMetalProperty_get.get(this, 'length') === 0) {
43850        return undefined;
43851      }
43852
43853      // handle generic enumerables
43854      var context = popCtx();
43855      var ret = this.nextObject(0, null, context);
43856
43857      pushCtx(context);
43858
43859      return ret;
43860    }),
43861
43862    /**
43863      Helper method returns the last object from a collection. If your enumerable
43864      contains only one object, this method should always return that object.
43865      If your enumerable is empty, this method should return `undefined`.
43866       ```javascript
43867      var arr = ['a', 'b', 'c'];
43868      arr.get('lastObject');  // 'c'
43869       var arr = [];
43870      arr.get('lastObject');  // undefined
43871      ```
43872       @property lastObject
43873      @return {Object} the last object or undefined
43874      @readOnly
43875      @public
43876    */
43877    lastObject: _emberMetalComputed.computed('[]', function () {
43878      var len = _emberMetalProperty_get.get(this, 'length');
43879
43880      if (len === 0) {
43881        return undefined;
43882      }
43883
43884      var context = popCtx();
43885      var idx = 0;
43886      var last = null;
43887      var cur;
43888
43889      do {
43890        last = cur;
43891        cur = this.nextObject(idx++, last, context);
43892      } while (cur !== undefined);
43893
43894      pushCtx(context);
43895
43896      return last;
43897    }),
43898
43899    /**
43900      Returns `true` if the passed object can be found in the receiver. The
43901      default version will iterate through the enumerable until the object
43902      is found. You may want to override this with a more efficient version.
43903       ```javascript
43904      var arr = ['a', 'b', 'c'];
43905       arr.contains('a'); // true
43906      arr.contains('z'); // false
43907      ```
43908       @method contains
43909      @param {Object} obj The object to search for.
43910      @return {Boolean} `true` if object is found in enumerable.
43911      @public
43912    */
43913    contains: function (obj) {
43914      var found = this.find(function (item) {
43915        return item === obj;
43916      });
43917
43918      return found !== undefined;
43919    },
43920
43921    /**
43922      Iterates through the enumerable, calling the passed function on each
43923      item. This method corresponds to the `forEach()` method defined in
43924      JavaScript 1.6.
43925       The callback method you provide should have the following signature (all
43926      parameters are optional):
43927       ```javascript
43928      function(item, index, enumerable);
43929      ```
43930       - `item` is the current item in the iteration.
43931      - `index` is the current index in the iteration.
43932      - `enumerable` is the enumerable object itself.
43933       Note that in addition to a callback, you can also pass an optional target
43934      object that will be set as `this` on the context. This is a good way
43935      to give your iterator function access to the current object.
43936       @method forEach
43937      @param {Function} callback The callback to execute
43938      @param {Object} [target] The target object to use
43939      @return {Object} receiver
43940      @public
43941    */
43942    forEach: function (callback, target) {
43943      if (typeof callback !== 'function') {
43944        throw new TypeError();
43945      }
43946
43947      var context = popCtx();
43948      var len = _emberMetalProperty_get.get(this, 'length');
43949      var last = null;
43950
43951      if (target === undefined) {
43952        target = null;
43953      }
43954
43955      for (var idx = 0; idx < len; idx++) {
43956        var next = this.nextObject(idx, last, context);
43957        callback.call(target, next, idx, this);
43958        last = next;
43959      }
43960
43961      last = null;
43962      context = pushCtx(context);
43963
43964      return this;
43965    },
43966
43967    /**
43968      Alias for `mapBy`
43969       @method getEach
43970      @param {String} key name of the property
43971      @return {Array} The mapped array.
43972      @public
43973    */
43974    getEach: _emberMetalMixin.aliasMethod('mapBy'),
43975
43976    /**
43977      Sets the value on the named property for each member. This is more
43978      efficient than using other methods defined on this helper. If the object
43979      implements Ember.Observable, the value will be changed to `set(),` otherwise
43980      it will be set directly. `null` objects are skipped.
43981       @method setEach
43982      @param {String} key The key to set
43983      @param {Object} value The object to set
43984      @return {Object} receiver
43985      @public
43986    */
43987    setEach: function (key, value) {
43988      return this.forEach(function (item) {
43989        _emberMetalProperty_set.set(item, key, value);
43990      });
43991    },
43992
43993    /**
43994      Maps all of the items in the enumeration to another value, returning
43995      a new array. This method corresponds to `map()` defined in JavaScript 1.6.
43996       The callback method you provide should have the following signature (all
43997      parameters are optional):
43998       ```javascript
43999      function(item, index, enumerable);
44000      ```
44001       - `item` is the current item in the iteration.
44002      - `index` is the current index in the iteration.
44003      - `enumerable` is the enumerable object itself.
44004       It should return the mapped value.
44005       Note that in addition to a callback, you can also pass an optional target
44006      object that will be set as `this` on the context. This is a good way
44007      to give your iterator function access to the current object.
44008       @method map
44009      @param {Function} callback The callback to execute
44010      @param {Object} [target] The target object to use
44011      @return {Array} The mapped array.
44012      @public
44013    */
44014    map: function (callback, target) {
44015      var ret = emberA();
44016
44017      this.forEach(function (x, idx, i) {
44018        ret[idx] = callback.call(target, x, idx, i);
44019      });
44020
44021      return ret;
44022    },
44023
44024    /**
44025      Similar to map, this specialized function returns the value of the named
44026      property on all items in the enumeration.
44027       @method mapBy
44028      @param {String} key name of the property
44029      @return {Array} The mapped array.
44030      @public
44031    */
44032    mapBy: function (key) {
44033      return this.map(function (next) {
44034        return _emberMetalProperty_get.get(next, key);
44035      });
44036    },
44037
44038    /**
44039      Returns an array with all of the items in the enumeration that the passed
44040      function returns true for. This method corresponds to `filter()` defined in
44041      JavaScript 1.6.
44042       The callback method you provide should have the following signature (all
44043      parameters are optional):
44044       ```javascript
44045      function(item, index, enumerable);
44046      ```
44047       - `item` is the current item in the iteration.
44048      - `index` is the current index in the iteration.
44049      - `enumerable` is the enumerable object itself.
44050       It should return `true` to include the item in the results, `false`
44051      otherwise.
44052       Note that in addition to a callback, you can also pass an optional target
44053      object that will be set as `this` on the context. This is a good way
44054      to give your iterator function access to the current object.
44055       @method filter
44056      @param {Function} callback The callback to execute
44057      @param {Object} [target] The target object to use
44058      @return {Array} A filtered array.
44059      @public
44060    */
44061    filter: function (callback, target) {
44062      var ret = emberA();
44063
44064      this.forEach(function (x, idx, i) {
44065        if (callback.call(target, x, idx, i)) {
44066          ret.push(x);
44067        }
44068      });
44069
44070      return ret;
44071    },
44072
44073    /**
44074      Returns an array with all of the items in the enumeration where the passed
44075      function returns false. This method is the inverse of filter().
44076       The callback method you provide should have the following signature (all
44077      parameters are optional):
44078       ```javascript
44079      function(item, index, enumerable);
44080      ```
44081       - *item* is the current item in the iteration.
44082      - *index* is the current index in the iteration
44083      - *enumerable* is the enumerable object itself.
44084       It should return a falsey value to include the item in the results.
44085       Note that in addition to a callback, you can also pass an optional target
44086      object that will be set as "this" on the context. This is a good way
44087      to give your iterator function access to the current object.
44088       @method reject
44089      @param {Function} callback The callback to execute
44090      @param {Object} [target] The target object to use
44091      @return {Array} A rejected array.
44092      @public
44093    */
44094    reject: function (callback, target) {
44095      return this.filter(function () {
44096        return !callback.apply(target, arguments);
44097      });
44098    },
44099
44100    /**
44101      Returns an array with just the items with the matched property. You
44102      can pass an optional second argument with the target value. Otherwise
44103      this will match any property that evaluates to `true`.
44104       @method filterBy
44105      @param {String} key the property to test
44106      @param {*} [value] optional value to test against.
44107      @return {Array} filtered array
44108      @public
44109    */
44110    filterBy: function (key, value) {
44111      return this.filter(iter.apply(this, arguments));
44112    },
44113
44114    /**
44115      Returns an array with the items that do not have truthy values for
44116      key.  You can pass an optional second argument with the target value.  Otherwise
44117      this will match any property that evaluates to false.
44118       @method rejectBy
44119      @param {String} key the property to test
44120      @param {String} [value] optional value to test against.
44121      @return {Array} rejected array
44122      @public
44123    */
44124    rejectBy: function (key, value) {
44125      var exactValue = function (item) {
44126        return _emberMetalProperty_get.get(item, key) === value;
44127      };
44128
44129      var hasValue = function (item) {
44130        return !!_emberMetalProperty_get.get(item, key);
44131      };
44132
44133      var use = arguments.length === 2 ? exactValue : hasValue;
44134
44135      return this.reject(use);
44136    },
44137
44138    /**
44139      Returns the first item in the array for which the callback returns true.
44140      This method works similar to the `filter()` method defined in JavaScript 1.6
44141      except that it will stop working on the array once a match is found.
44142       The callback method you provide should have the following signature (all
44143      parameters are optional):
44144       ```javascript
44145      function(item, index, enumerable);
44146      ```
44147       - `item` is the current item in the iteration.
44148      - `index` is the current index in the iteration.
44149      - `enumerable` is the enumerable object itself.
44150       It should return the `true` to include the item in the results, `false`
44151      otherwise.
44152       Note that in addition to a callback, you can also pass an optional target
44153      object that will be set as `this` on the context. This is a good way
44154      to give your iterator function access to the current object.
44155       @method find
44156      @param {Function} callback The callback to execute
44157      @param {Object} [target] The target object to use
44158      @return {Object} Found item or `undefined`.
44159      @public
44160    */
44161    find: function (callback, target) {
44162      var len = _emberMetalProperty_get.get(this, 'length');
44163
44164      if (target === undefined) {
44165        target = null;
44166      }
44167
44168      var context = popCtx();
44169      var found = false;
44170      var last = null;
44171      var next, ret;
44172
44173      for (var idx = 0; idx < len && !found; idx++) {
44174        next = this.nextObject(idx, last, context);
44175
44176        if (found = callback.call(target, next, idx, this)) {
44177          ret = next;
44178        }
44179
44180        last = next;
44181      }
44182
44183      next = last = null;
44184      context = pushCtx(context);
44185
44186      return ret;
44187    },
44188
44189    /**
44190      Returns the first item with a property matching the passed value. You
44191      can pass an optional second argument with the target value. Otherwise
44192      this will match any property that evaluates to `true`.
44193       This method works much like the more generic `find()` method.
44194       @method findBy
44195      @param {String} key the property to test
44196      @param {String} [value] optional value to test against.
44197      @return {Object} found item or `undefined`
44198      @public
44199    */
44200    findBy: function (key, value) {
44201      return this.find(iter.apply(this, arguments));
44202    },
44203
44204    /**
44205      Returns `true` if the passed function returns true for every item in the
44206      enumeration. This corresponds with the `every()` method in JavaScript 1.6.
44207       The callback method you provide should have the following signature (all
44208      parameters are optional):
44209       ```javascript
44210      function(item, index, enumerable);
44211      ```
44212       - `item` is the current item in the iteration.
44213      - `index` is the current index in the iteration.
44214      - `enumerable` is the enumerable object itself.
44215       It should return the `true` or `false`.
44216       Note that in addition to a callback, you can also pass an optional target
44217      object that will be set as `this` on the context. This is a good way
44218      to give your iterator function access to the current object.
44219       Example Usage:
44220       ```javascript
44221      if (people.every(isEngineer)) {
44222        Paychecks.addBigBonus();
44223      }
44224      ```
44225       @method every
44226      @param {Function} callback The callback to execute
44227      @param {Object} [target] The target object to use
44228      @return {Boolean}
44229      @public
44230    */
44231    every: function (callback, target) {
44232      return !this.find(function (x, idx, i) {
44233        return !callback.call(target, x, idx, i);
44234      });
44235    },
44236
44237    /**
44238      Returns `true` if the passed property resolves to the value of the second
44239      argument for all items in the enumerable. This method is often simpler/faster
44240      than using a callback.
44241       @method isEvery
44242      @param {String} key the property to test
44243      @param {String} [value] optional value to test against. Defaults to `true`
44244      @return {Boolean}
44245      @since 1.3.0
44246      @public
44247    */
44248    isEvery: function (key, value) {
44249      return this.every(iter.apply(this, arguments));
44250    },
44251
44252    /**
44253      Returns `true` if the passed function returns true for any item in the
44254      enumeration. This corresponds with the `some()` method in JavaScript 1.6.
44255       The callback method you provide should have the following signature (all
44256      parameters are optional):
44257       ```javascript
44258      function(item, index, enumerable);
44259      ```
44260       - `item` is the current item in the iteration.
44261      - `index` is the current index in the iteration.
44262      - `enumerable` is the enumerable object itself.
44263       It should return the `true` to include the item in the results, `false`
44264      otherwise.
44265       Note that in addition to a callback, you can also pass an optional target
44266      object that will be set as `this` on the context. This is a good way
44267      to give your iterator function access to the current object.
44268       Usage Example:
44269       ```javascript
44270      if (people.any(isManager)) {
44271        Paychecks.addBiggerBonus();
44272      }
44273      ```
44274       @method any
44275      @param {Function} callback The callback to execute
44276      @param {Object} [target] The target object to use
44277      @return {Boolean} `true` if the passed function returns `true` for any item
44278      @public
44279    */
44280    any: function (callback, target) {
44281      var len = _emberMetalProperty_get.get(this, 'length');
44282      var context = popCtx();
44283      var found = false;
44284      var last = null;
44285      var next, idx;
44286
44287      if (target === undefined) {
44288        target = null;
44289      }
44290
44291      for (idx = 0; idx < len && !found; idx++) {
44292        next = this.nextObject(idx, last, context);
44293        found = callback.call(target, next, idx, this);
44294        last = next;
44295      }
44296
44297      next = last = null;
44298      context = pushCtx(context);
44299      return found;
44300    },
44301
44302    /**
44303      Returns `true` if the passed property resolves to the value of the second
44304      argument for any item in the enumerable. This method is often simpler/faster
44305      than using a callback.
44306       @method isAny
44307      @param {String} key the property to test
44308      @param {String} [value] optional value to test against. Defaults to `true`
44309      @return {Boolean}
44310      @since 1.3.0
44311      @public
44312    */
44313    isAny: function (key, value) {
44314      return this.any(iter.apply(this, arguments));
44315    },
44316
44317    /**
44318      This will combine the values of the enumerator into a single value. It
44319      is a useful way to collect a summary value from an enumeration. This
44320      corresponds to the `reduce()` method defined in JavaScript 1.8.
44321       The callback method you provide should have the following signature (all
44322      parameters are optional):
44323       ```javascript
44324      function(previousValue, item, index, enumerable);
44325      ```
44326       - `previousValue` is the value returned by the last call to the iterator.
44327      - `item` is the current item in the iteration.
44328      - `index` is the current index in the iteration.
44329      - `enumerable` is the enumerable object itself.
44330       Return the new cumulative value.
44331       In addition to the callback you can also pass an `initialValue`. An error
44332      will be raised if you do not pass an initial value and the enumerator is
44333      empty.
44334       Note that unlike the other methods, this method does not allow you to
44335      pass a target object to set as this for the callback. It's part of the
44336      spec. Sorry.
44337       @method reduce
44338      @param {Function} callback The callback to execute
44339      @param {Object} initialValue Initial value for the reduce
44340      @param {String} reducerProperty internal use only.
44341      @return {Object} The reduced value.
44342      @public
44343    */
44344    reduce: function (callback, initialValue, reducerProperty) {
44345      if (typeof callback !== 'function') {
44346        throw new TypeError();
44347      }
44348
44349      var ret = initialValue;
44350
44351      this.forEach(function (item, i) {
44352        ret = callback(ret, item, i, this, reducerProperty);
44353      }, this);
44354
44355      return ret;
44356    },
44357
44358    /**
44359      Invokes the named method on every object in the receiver that
44360      implements it. This method corresponds to the implementation in
44361      Prototype 1.6.
44362       @method invoke
44363      @param {String} methodName the name of the method
44364      @param {Object...} args optional arguments to pass as well.
44365      @return {Array} return values from calling invoke.
44366      @public
44367    */
44368    invoke: function (methodName) {
44369      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
44370        args[_key - 1] = arguments[_key];
44371      }
44372
44373      var ret = emberA();
44374
44375      this.forEach(function (x, idx) {
44376        var method = x && x[methodName];
44377
44378        if ('function' === typeof method) {
44379          ret[idx] = args ? method.apply(x, args) : x[methodName]();
44380        }
44381      }, this);
44382
44383      return ret;
44384    },
44385
44386    /**
44387      Simply converts the enumerable into a genuine array. The order is not
44388      guaranteed. Corresponds to the method implemented by Prototype.
44389       @method toArray
44390      @return {Array} the enumerable as an array.
44391      @public
44392    */
44393    toArray: function () {
44394      var ret = emberA();
44395
44396      this.forEach(function (o, idx) {
44397        ret[idx] = o;
44398      });
44399
44400      return ret;
44401    },
44402
44403    /**
44404      Returns a copy of the array with all `null` and `undefined` elements removed.
44405       ```javascript
44406      var arr = ['a', null, 'c', undefined];
44407      arr.compact();  // ['a', 'c']
44408      ```
44409       @method compact
44410      @return {Array} the array without null and undefined elements.
44411      @public
44412    */
44413    compact: function () {
44414      return this.filter(function (value) {
44415        return value != null;
44416      });
44417    },
44418
44419    /**
44420      Returns a new enumerable that excludes the passed value. The default
44421      implementation returns an array regardless of the receiver type unless
44422      the receiver does not contain the value.
44423       ```javascript
44424      var arr = ['a', 'b', 'a', 'c'];
44425      arr.without('a');  // ['b', 'c']
44426      ```
44427       @method without
44428      @param {Object} value
44429      @return {Ember.Enumerable}
44430      @public
44431    */
44432    without: function (value) {
44433      if (!this.contains(value)) {
44434        return this; // nothing to do
44435      }
44436
44437      var ret = emberA();
44438
44439      this.forEach(function (k) {
44440        if (k !== value) {
44441          ret[ret.length] = k;
44442        }
44443      });
44444
44445      return ret;
44446    },
44447
44448    /**
44449      Returns a new enumerable that contains only unique values. The default
44450      implementation returns an array regardless of the receiver type.
44451       ```javascript
44452      var arr = ['a', 'a', 'b', 'b'];
44453      arr.uniq();  // ['a', 'b']
44454      ```
44455       This only works on primitive data types, e.g. Strings, Numbers, etc.
44456       @method uniq
44457      @return {Ember.Enumerable}
44458      @public
44459    */
44460    uniq: function () {
44461      var ret = emberA();
44462
44463      this.forEach(function (k) {
44464        if (ret.indexOf(k) < 0) {
44465          ret.push(k);
44466        }
44467      });
44468
44469      return ret;
44470    },
44471
44472    /**
44473      This property will trigger anytime the enumerable's content changes.
44474      You can observe this property to be notified of changes to the enumerable's
44475      content.
44476       For plain enumerables, this property is read only. `Array` overrides
44477      this method.
44478       @property []
44479      @type Array
44480      @return this
44481      @private
44482    */
44483    '[]': _emberMetalComputed.computed({
44484      get: function (key) {
44485        return this;
44486      }
44487    }),
44488
44489    // ..........................................................
44490    // ENUMERABLE OBSERVERS
44491    //
44492
44493    /**
44494      Registers an enumerable observer. Must implement `Ember.EnumerableObserver`
44495      mixin.
44496       @method addEnumerableObserver
44497      @param {Object} target
44498      @param {Object} [opts]
44499      @return this
44500      @private
44501    */
44502    addEnumerableObserver: function (target, opts) {
44503      var willChange = opts && opts.willChange || 'enumerableWillChange';
44504      var didChange = opts && opts.didChange || 'enumerableDidChange';
44505      var hasObservers = _emberMetalProperty_get.get(this, 'hasEnumerableObservers');
44506
44507      if (!hasObservers) {
44508        _emberMetalProperty_events.propertyWillChange(this, 'hasEnumerableObservers');
44509      }
44510
44511      _emberMetalEvents.addListener(this, '@enumerable:before', target, willChange);
44512      _emberMetalEvents.addListener(this, '@enumerable:change', target, didChange);
44513
44514      if (!hasObservers) {
44515        _emberMetalProperty_events.propertyDidChange(this, 'hasEnumerableObservers');
44516      }
44517
44518      return this;
44519    },
44520
44521    /**
44522      Removes a registered enumerable observer.
44523       @method removeEnumerableObserver
44524      @param {Object} target
44525      @param {Object} [opts]
44526      @return this
44527      @private
44528    */
44529    removeEnumerableObserver: function (target, opts) {
44530      var willChange = opts && opts.willChange || 'enumerableWillChange';
44531      var didChange = opts && opts.didChange || 'enumerableDidChange';
44532      var hasObservers = _emberMetalProperty_get.get(this, 'hasEnumerableObservers');
44533
44534      if (hasObservers) {
44535        _emberMetalProperty_events.propertyWillChange(this, 'hasEnumerableObservers');
44536      }
44537
44538      _emberMetalEvents.removeListener(this, '@enumerable:before', target, willChange);
44539      _emberMetalEvents.removeListener(this, '@enumerable:change', target, didChange);
44540
44541      if (hasObservers) {
44542        _emberMetalProperty_events.propertyDidChange(this, 'hasEnumerableObservers');
44543      }
44544
44545      return this;
44546    },
44547
44548    /**
44549      Becomes true whenever the array currently has observers watching changes
44550      on the array.
44551       @property hasEnumerableObservers
44552      @type Boolean
44553      @private
44554    */
44555    hasEnumerableObservers: _emberMetalComputed.computed(function () {
44556      return _emberMetalEvents.hasListeners(this, '@enumerable:change') || _emberMetalEvents.hasListeners(this, '@enumerable:before');
44557    }),
44558
44559    /**
44560      Invoke this method just before the contents of your enumerable will
44561      change. You can either omit the parameters completely or pass the objects
44562      to be removed or added if available or just a count.
44563       @method enumerableContentWillChange
44564      @param {Ember.Enumerable|Number} removing An enumerable of the objects to
44565        be removed or the number of items to be removed.
44566      @param {Ember.Enumerable|Number} adding An enumerable of the objects to be
44567        added or the number of items to be added.
44568      @chainable
44569      @private
44570    */
44571    enumerableContentWillChange: function (removing, adding) {
44572      var removeCnt, addCnt, hasDelta;
44573
44574      if ('number' === typeof removing) {
44575        removeCnt = removing;
44576      } else if (removing) {
44577        removeCnt = _emberMetalProperty_get.get(removing, 'length');
44578      } else {
44579        removeCnt = removing = -1;
44580      }
44581
44582      if ('number' === typeof adding) {
44583        addCnt = adding;
44584      } else if (adding) {
44585        addCnt = _emberMetalProperty_get.get(adding, 'length');
44586      } else {
44587        addCnt = adding = -1;
44588      }
44589
44590      hasDelta = addCnt < 0 || removeCnt < 0 || addCnt - removeCnt !== 0;
44591
44592      if (removing === -1) {
44593        removing = null;
44594      }
44595
44596      if (adding === -1) {
44597        adding = null;
44598      }
44599
44600      _emberMetalProperty_events.propertyWillChange(this, '[]');
44601
44602      if (hasDelta) {
44603        _emberMetalProperty_events.propertyWillChange(this, 'length');
44604      }
44605
44606      _emberMetalEvents.sendEvent(this, '@enumerable:before', [this, removing, adding]);
44607
44608      return this;
44609    },
44610
44611    /**
44612      Invoke this method when the contents of your enumerable has changed.
44613      This will notify any observers watching for content changes. If you are
44614      implementing an ordered enumerable (such as an array), also pass the
44615      start and end values where the content changed so that it can be used to
44616      notify range observers.
44617       @method enumerableContentDidChange
44618      @param {Ember.Enumerable|Number} removing An enumerable of the objects to
44619        be removed or the number of items to be removed.
44620      @param {Ember.Enumerable|Number} adding  An enumerable of the objects to
44621        be added or the number of items to be added.
44622      @chainable
44623      @private
44624    */
44625    enumerableContentDidChange: function (removing, adding) {
44626      var removeCnt, addCnt, hasDelta;
44627
44628      if ('number' === typeof removing) {
44629        removeCnt = removing;
44630      } else if (removing) {
44631        removeCnt = _emberMetalProperty_get.get(removing, 'length');
44632      } else {
44633        removeCnt = removing = -1;
44634      }
44635
44636      if ('number' === typeof adding) {
44637        addCnt = adding;
44638      } else if (adding) {
44639        addCnt = _emberMetalProperty_get.get(adding, 'length');
44640      } else {
44641        addCnt = adding = -1;
44642      }
44643
44644      hasDelta = addCnt < 0 || removeCnt < 0 || addCnt - removeCnt !== 0;
44645
44646      if (removing === -1) {
44647        removing = null;
44648      }
44649
44650      if (adding === -1) {
44651        adding = null;
44652      }
44653
44654      _emberMetalEvents.sendEvent(this, '@enumerable:change', [this, removing, adding]);
44655
44656      if (hasDelta) {
44657        _emberMetalProperty_events.propertyDidChange(this, 'length');
44658      }
44659
44660      _emberMetalProperty_events.propertyDidChange(this, '[]');
44661
44662      return this;
44663    },
44664
44665    /**
44666      Converts the enumerable into an array and sorts by the keys
44667      specified in the argument.
44668       You may provide multiple arguments to sort by multiple properties.
44669       @method sortBy
44670      @param {String} property name(s) to sort on
44671      @return {Array} The sorted array.
44672      @since 1.2.0
44673      @public
44674    */
44675    sortBy: function () {
44676      var sortKeys = arguments;
44677
44678      return this.toArray().sort(function (a, b) {
44679        for (var i = 0; i < sortKeys.length; i++) {
44680          var key = sortKeys[i];
44681          var propA = _emberMetalProperty_get.get(a, key);
44682          var propB = _emberMetalProperty_get.get(b, key);
44683          // return 1 or -1 else continue to the next sortKey
44684          var compareValue = _emberRuntimeCompare.default(propA, propB);
44685
44686          if (compareValue) {
44687            return compareValue;
44688          }
44689        }
44690        return 0;
44691      });
44692    }
44693  });
44694});
44695enifed('ember-runtime/mixins/evented', ['exports', 'ember-metal/mixin', 'ember-metal/events'], function (exports, _emberMetalMixin, _emberMetalEvents) {
44696  'use strict';
44697
44698  /**
44699  @module ember
44700  @submodule ember-runtime
44701  */
44702
44703  /**
44704    This mixin allows for Ember objects to subscribe to and emit events.
44705  
44706    ```javascript
44707    App.Person = Ember.Object.extend(Ember.Evented, {
44708      greet: function() {
44709        // ...
44710        this.trigger('greet');
44711      }
44712    });
44713  
44714    var person = App.Person.create();
44715  
44716    person.on('greet', function() {
44717      console.log('Our person has greeted');
44718    });
44719  
44720    person.greet();
44721  
44722    // outputs: 'Our person has greeted'
44723    ```
44724  
44725    You can also chain multiple event subscriptions:
44726  
44727    ```javascript
44728    person.on('greet', function() {
44729      console.log('Our person has greeted');
44730    }).one('greet', function() {
44731      console.log('Offer one-time special');
44732    }).off('event', this, forgetThis);
44733    ```
44734  
44735    @class Evented
44736    @namespace Ember
44737    @public
44738   */
44739  exports.default = _emberMetalMixin.Mixin.create({
44740
44741    /**
44742     Subscribes to a named event with given function.
44743      ```javascript
44744     person.on('didLoad', function() {
44745       // fired once the person has loaded
44746     });
44747     ```
44748      An optional target can be passed in as the 2nd argument that will
44749     be set as the "this" for the callback. This is a good way to give your
44750     function access to the object triggering the event. When the target
44751     parameter is used the callback becomes the third argument.
44752      @method on
44753     @param {String} name The name of the event
44754     @param {Object} [target] The "this" binding for the callback
44755     @param {Function} method The callback to execute
44756     @return this
44757     @public
44758    */
44759    on: function (name, target, method) {
44760      _emberMetalEvents.addListener(this, name, target, method);
44761      return this;
44762    },
44763
44764    /**
44765      Subscribes a function to a named event and then cancels the subscription
44766      after the first time the event is triggered. It is good to use ``one`` when
44767      you only care about the first time an event has taken place.
44768       This function takes an optional 2nd argument that will become the "this"
44769      value for the callback. If this argument is passed then the 3rd argument
44770      becomes the function.
44771       @method one
44772      @param {String} name The name of the event
44773      @param {Object} [target] The "this" binding for the callback
44774      @param {Function} method The callback to execute
44775      @return this
44776      @public
44777    */
44778    one: function (name, target, method) {
44779      if (!method) {
44780        method = target;
44781        target = null;
44782      }
44783
44784      _emberMetalEvents.addListener(this, name, target, method, true);
44785      return this;
44786    },
44787
44788    /**
44789      Triggers a named event for the object. Any additional arguments
44790      will be passed as parameters to the functions that are subscribed to the
44791      event.
44792       ```javascript
44793      person.on('didEat', function(food) {
44794        console.log('person ate some ' + food);
44795      });
44796       person.trigger('didEat', 'broccoli');
44797       // outputs: person ate some broccoli
44798      ```
44799      @method trigger
44800      @param {String} name The name of the event
44801      @param {Object...} args Optional arguments to pass on
44802      @public
44803    */
44804    trigger: function (name) {
44805      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
44806        args[_key - 1] = arguments[_key];
44807      }
44808
44809      _emberMetalEvents.sendEvent(this, name, args);
44810    },
44811
44812    /**
44813      Cancels subscription for given name, target, and method.
44814       @method off
44815      @param {String} name The name of the event
44816      @param {Object} target The target of the subscription
44817      @param {Function} method The function of the subscription
44818      @return this
44819      @public
44820    */
44821    off: function (name, target, method) {
44822      _emberMetalEvents.removeListener(this, name, target, method);
44823      return this;
44824    },
44825
44826    /**
44827      Checks to see if object has any subscriptions for named event.
44828       @method has
44829      @param {String} name The name of the event
44830      @return {Boolean} does the object have a subscription for event
44831      @public
44832     */
44833    has: function (name) {
44834      return _emberMetalEvents.hasListeners(this, name);
44835    }
44836  });
44837});
44838enifed('ember-runtime/mixins/freezable', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/property_set'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberMetalProperty_get, _emberMetalProperty_set) {
44839  /**
44840  @module ember
44841  @submodule ember-runtime
44842  */
44843
44844  'use strict';
44845
44846  /**
44847    The `Ember.Freezable` mixin implements some basic methods for marking an
44848    object as frozen. Once an object is frozen it should be read only. No changes
44849    may be made the internal state of the object.
44850  
44851    ## Enforcement
44852  
44853    To fully support freezing in your subclass, you must include this mixin and
44854    override any method that might alter any property on the object to instead
44855    raise an exception. You can check the state of an object by checking the
44856    `isFrozen` property.
44857  
44858    Although future versions of JavaScript may support language-level freezing
44859    object objects, that is not the case today. Even if an object is freezable,
44860    it is still technically possible to modify the object, even though it could
44861    break other parts of your application that do not expect a frozen object to
44862    change. It is, therefore, very important that you always respect the
44863    `isFrozen` property on all freezable objects.
44864  
44865    ## Example Usage
44866  
44867    The example below shows a simple object that implement the `Ember.Freezable`
44868    protocol.
44869  
44870    ```javascript
44871    Contact = Ember.Object.extend(Ember.Freezable, {
44872      firstName: null,
44873      lastName: null,
44874  
44875      // swaps the names
44876      swapNames: function() {
44877        if (this.get('isFrozen')) throw Ember.FROZEN_ERROR;
44878        var tmp = this.get('firstName');
44879        this.set('firstName', this.get('lastName'));
44880        this.set('lastName', tmp);
44881        return this;
44882      }
44883  
44884    });
44885  
44886    c = Contact.create({ firstName: "John", lastName: "Doe" });
44887    c.swapNames();  // returns c
44888    c.freeze();
44889    c.swapNames();  // EXCEPTION
44890    ```
44891  
44892    ## Copying
44893  
44894    Usually the `Ember.Freezable` protocol is implemented in cooperation with the
44895    `Ember.Copyable` protocol, which defines a `frozenCopy()` method that will
44896    return a frozen object, if the object implements this method as well.
44897  
44898    @class Freezable
44899    @namespace Ember
44900    @since Ember 0.9
44901    @deprecated Use `Object.freeze` instead.
44902    @private
44903  */
44904  var Freezable = _emberMetalMixin.Mixin.create({
44905
44906    init: function () {
44907      _emberMetalDebug.deprecate('`Ember.Freezable` is deprecated, use `Object.freeze` instead.', false, { id: 'ember-runtime.freezable-init', until: '3.0.0' });
44908      this._super.apply(this, arguments);
44909    },
44910
44911    /**
44912      Set to `true` when the object is frozen. Use this property to detect
44913      whether your object is frozen or not.
44914       @property isFrozen
44915      @type Boolean
44916      @private
44917    */
44918    isFrozen: false,
44919
44920    /**
44921      Freezes the object. Once this method has been called the object should
44922      no longer allow any properties to be edited.
44923       @method freeze
44924      @return {Object} receiver
44925      @private
44926    */
44927    freeze: function () {
44928      if (_emberMetalProperty_get.get(this, 'isFrozen')) {
44929        return this;
44930      }
44931
44932      _emberMetalProperty_set.set(this, 'isFrozen', true);
44933      return this;
44934    }
44935
44936  });
44937
44938  exports.Freezable = Freezable;
44939  var FROZEN_ERROR = 'Frozen object cannot be modified.';
44940  exports.FROZEN_ERROR = FROZEN_ERROR;
44941});
44942enifed('ember-runtime/mixins/mutable_array', ['exports', 'ember-metal/property_get', 'ember-metal/error', 'ember-metal/mixin', 'ember-runtime/mixins/array', 'ember-runtime/mixins/mutable_enumerable', 'ember-runtime/mixins/enumerable'], function (exports, _emberMetalProperty_get, _emberMetalError, _emberMetalMixin, _emberRuntimeMixinsArray, _emberRuntimeMixinsMutable_enumerable, _emberRuntimeMixinsEnumerable) {
44943  /**
44944  @module ember
44945  @submodule ember-runtime
44946  */
44947
44948  // require('ember-runtime/mixins/array');
44949  // require('ember-runtime/mixins/mutable_enumerable');
44950
44951  // ..........................................................
44952  // CONSTANTS
44953  //
44954
44955  'use strict';
44956
44957  var OUT_OF_RANGE_EXCEPTION = 'Index out of range';
44958  var EMPTY = [];
44959
44960  // ..........................................................
44961  // HELPERS
44962  //
44963
44964  /**
44965    This mixin defines the API for modifying array-like objects. These methods
44966    can be applied only to a collection that keeps its items in an ordered set.
44967    It builds upon the Array mixin and adds methods to modify the array.
44968    One concrete implementations of this class include ArrayProxy.
44969  
44970    It is important to use the methods in this class to modify arrays so that
44971    changes are observable. This allows the binding system in Ember to function
44972    correctly.
44973  
44974  
44975    Note that an Array can change even if it does not implement this mixin.
44976    For example, one might implement a SparseArray that cannot be directly
44977    modified, but if its underlying enumerable changes, it will change also.
44978  
44979    @class MutableArray
44980    @namespace Ember
44981    @uses Ember.Array
44982    @uses Ember.MutableEnumerable
44983    @public
44984  */
44985  exports.default = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsArray.default, _emberRuntimeMixinsMutable_enumerable.default, {
44986
44987    /**
44988      __Required.__ You must implement this method to apply this mixin.
44989       This is one of the primitives you must implement to support `Ember.Array`.
44990      You should replace amt objects started at idx with the objects in the
44991      passed array. You should also call `this.enumerableContentDidChange()`
44992       @method replace
44993      @param {Number} idx Starting index in the array to replace. If
44994        idx >= length, then append to the end of the array.
44995      @param {Number} amt Number of elements that should be removed from
44996        the array, starting at *idx*.
44997      @param {Array} objects An array of zero or more objects that should be
44998        inserted into the array at *idx*
44999      @public
45000    */
45001    replace: null,
45002
45003    /**
45004      Remove all elements from the array. This is useful if you
45005      want to reuse an existing array without having to recreate it.
45006       ```javascript
45007      var colors = ['red', 'green', 'blue'];
45008       color.length();   //  3
45009      colors.clear();   //  []
45010      colors.length();  //  0
45011      ```
45012       @method clear
45013      @return {Ember.Array} An empty Array.
45014      @public
45015    */
45016    clear: function () {
45017      var len = _emberMetalProperty_get.get(this, 'length');
45018      if (len === 0) {
45019        return this;
45020      }
45021
45022      this.replace(0, len, EMPTY);
45023      return this;
45024    },
45025
45026    /**
45027      This will use the primitive `replace()` method to insert an object at the
45028      specified index.
45029       ```javascript
45030      var colors = ['red', 'green', 'blue'];
45031       colors.insertAt(2, 'yellow');  // ['red', 'green', 'yellow', 'blue']
45032      colors.insertAt(5, 'orange');  // Error: Index out of range
45033      ```
45034       @method insertAt
45035      @param {Number} idx index of insert the object at.
45036      @param {Object} object object to insert
45037      @return {Ember.Array} receiver
45038      @public
45039    */
45040    insertAt: function (idx, object) {
45041      if (idx > _emberMetalProperty_get.get(this, 'length')) {
45042        throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION);
45043      }
45044
45045      this.replace(idx, 0, [object]);
45046      return this;
45047    },
45048
45049    /**
45050      Remove an object at the specified index using the `replace()` primitive
45051      method. You can pass either a single index, or a start and a length.
45052       If you pass a start and length that is beyond the
45053      length this method will throw an `OUT_OF_RANGE_EXCEPTION`.
45054       ```javascript
45055      var colors = ['red', 'green', 'blue', 'yellow', 'orange'];
45056       colors.removeAt(0);     // ['green', 'blue', 'yellow', 'orange']
45057      colors.removeAt(2, 2);  // ['green', 'blue']
45058      colors.removeAt(4, 2);  // Error: Index out of range
45059      ```
45060       @method removeAt
45061      @param {Number} start index, start of range
45062      @param {Number} len length of passing range
45063      @return {Ember.Array} receiver
45064      @public
45065    */
45066    removeAt: function (start, len) {
45067      if ('number' === typeof start) {
45068        if (start < 0 || start >= _emberMetalProperty_get.get(this, 'length')) {
45069          throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION);
45070        }
45071
45072        // fast case
45073        if (len === undefined) {
45074          len = 1;
45075        }
45076
45077        this.replace(start, len, EMPTY);
45078      }
45079
45080      return this;
45081    },
45082
45083    /**
45084      Push the object onto the end of the array. Works just like `push()` but it
45085      is KVO-compliant.
45086       ```javascript
45087      var colors = ['red', 'green'];
45088       colors.pushObject('black');     // ['red', 'green', 'black']
45089      colors.pushObject(['yellow']);  // ['red', 'green', ['yellow']]
45090      ```
45091       @method pushObject
45092      @param {*} obj object to push
45093      @return object same object passed as a param
45094      @public
45095    */
45096    pushObject: function (obj) {
45097      this.insertAt(_emberMetalProperty_get.get(this, 'length'), obj);
45098      return obj;
45099    },
45100
45101    /**
45102      Add the objects in the passed numerable to the end of the array. Defers
45103      notifying observers of the change until all objects are added.
45104       ```javascript
45105      var colors = ['red'];
45106       colors.pushObjects(['yellow', 'orange']);  // ['red', 'yellow', 'orange']
45107      ```
45108       @method pushObjects
45109      @param {Ember.Enumerable} objects the objects to add
45110      @return {Ember.Array} receiver
45111      @public
45112    */
45113    pushObjects: function (objects) {
45114      if (!(_emberRuntimeMixinsEnumerable.default.detect(objects) || Array.isArray(objects))) {
45115        throw new TypeError('Must pass Ember.Enumerable to Ember.MutableArray#pushObjects');
45116      }
45117      this.replace(_emberMetalProperty_get.get(this, 'length'), 0, objects);
45118      return this;
45119    },
45120
45121    /**
45122      Pop object from array or nil if none are left. Works just like `pop()` but
45123      it is KVO-compliant.
45124       ```javascript
45125      var colors = ['red', 'green', 'blue'];
45126       colors.popObject();   // 'blue'
45127      console.log(colors);  // ['red', 'green']
45128      ```
45129       @method popObject
45130      @return object
45131      @public
45132    */
45133    popObject: function () {
45134      var len = _emberMetalProperty_get.get(this, 'length');
45135      if (len === 0) {
45136        return null;
45137      }
45138
45139      var ret = _emberRuntimeMixinsArray.objectAt(this, len - 1);
45140      this.removeAt(len - 1, 1);
45141      return ret;
45142    },
45143
45144    /**
45145      Shift an object from start of array or nil if none are left. Works just
45146      like `shift()` but it is KVO-compliant.
45147       ```javascript
45148      var colors = ['red', 'green', 'blue'];
45149       colors.shiftObject();  // 'red'
45150      console.log(colors);   // ['green', 'blue']
45151      ```
45152       @method shiftObject
45153      @return object
45154      @public
45155    */
45156    shiftObject: function () {
45157      if (_emberMetalProperty_get.get(this, 'length') === 0) {
45158        return null;
45159      }
45160
45161      var ret = _emberRuntimeMixinsArray.objectAt(this, 0);
45162      this.removeAt(0);
45163      return ret;
45164    },
45165
45166    /**
45167      Unshift an object to start of array. Works just like `unshift()` but it is
45168      KVO-compliant.
45169       ```javascript
45170      var colors = ['red'];
45171       colors.unshiftObject('yellow');    // ['yellow', 'red']
45172      colors.unshiftObject(['black']);   // [['black'], 'yellow', 'red']
45173      ```
45174       @method unshiftObject
45175      @param {*} obj object to unshift
45176      @return object same object passed as a param
45177      @public
45178    */
45179    unshiftObject: function (obj) {
45180      this.insertAt(0, obj);
45181      return obj;
45182    },
45183
45184    /**
45185      Adds the named objects to the beginning of the array. Defers notifying
45186      observers until all objects have been added.
45187       ```javascript
45188      var colors = ['red'];
45189       colors.unshiftObjects(['black', 'white']);   // ['black', 'white', 'red']
45190      colors.unshiftObjects('yellow'); // Type Error: 'undefined' is not a function
45191      ```
45192       @method unshiftObjects
45193      @param {Ember.Enumerable} objects the objects to add
45194      @return {Ember.Array} receiver
45195      @public
45196    */
45197    unshiftObjects: function (objects) {
45198      this.replace(0, 0, objects);
45199      return this;
45200    },
45201
45202    /**
45203      Reverse objects in the array. Works just like `reverse()` but it is
45204      KVO-compliant.
45205       @method reverseObjects
45206      @return {Ember.Array} receiver
45207       @public
45208    */
45209    reverseObjects: function () {
45210      var len = _emberMetalProperty_get.get(this, 'length');
45211      if (len === 0) {
45212        return this;
45213      }
45214
45215      var objects = this.toArray().reverse();
45216      this.replace(0, len, objects);
45217      return this;
45218    },
45219
45220    /**
45221      Replace all the receiver's content with content of the argument.
45222      If argument is an empty array receiver will be cleared.
45223       ```javascript
45224      var colors = ['red', 'green', 'blue'];
45225       colors.setObjects(['black', 'white']);  // ['black', 'white']
45226      colors.setObjects([]);                  // []
45227      ```
45228       @method setObjects
45229      @param {Ember.Array} objects array whose content will be used for replacing
45230          the content of the receiver
45231      @return {Ember.Array} receiver with the new content
45232      @public
45233    */
45234    setObjects: function (objects) {
45235      if (objects.length === 0) {
45236        return this.clear();
45237      }
45238
45239      var len = _emberMetalProperty_get.get(this, 'length');
45240      this.replace(0, len, objects);
45241      return this;
45242    },
45243
45244    // ..........................................................
45245    // IMPLEMENT Ember.MutableEnumerable
45246    //
45247
45248    /**
45249      Remove all occurrences of an object in the array.
45250       ```javascript
45251      var cities = ['Chicago', 'Berlin', 'Lima', 'Chicago'];
45252       cities.removeObject('Chicago');  // ['Berlin', 'Lima']
45253      cities.removeObject('Lima');     // ['Berlin']
45254      cities.removeObject('Tokyo')     // ['Berlin']
45255      ```
45256       @method removeObject
45257      @param {*} obj object to remove
45258      @return {Ember.Array} receiver
45259      @public
45260    */
45261    removeObject: function (obj) {
45262      var loc = _emberMetalProperty_get.get(this, 'length') || 0;
45263      while (--loc >= 0) {
45264        var curObject = _emberRuntimeMixinsArray.objectAt(this, loc);
45265
45266        if (curObject === obj) {
45267          this.removeAt(loc);
45268        }
45269      }
45270      return this;
45271    },
45272
45273    /**
45274      Push the object onto the end of the array if it is not already
45275      present in the array.
45276       ```javascript
45277      var cities = ['Chicago', 'Berlin'];
45278       cities.addObject('Lima');    // ['Chicago', 'Berlin', 'Lima']
45279      cities.addObject('Berlin');  // ['Chicago', 'Berlin', 'Lima']
45280      ```
45281       @method addObject
45282      @param {*} obj object to add, if not already present
45283      @return {Ember.Array} receiver
45284      @public
45285    */
45286    addObject: function (obj) {
45287      if (!this.contains(obj)) {
45288        this.pushObject(obj);
45289      }
45290
45291      return this;
45292    }
45293  });
45294});
45295enifed('ember-runtime/mixins/mutable_enumerable', ['exports', 'ember-runtime/mixins/enumerable', 'ember-metal/mixin', 'ember-metal/property_events'], function (exports, _emberRuntimeMixinsEnumerable, _emberMetalMixin, _emberMetalProperty_events) {
45296  'use strict';
45297
45298  /**
45299  @module ember
45300  @submodule ember-runtime
45301  */
45302
45303  /**
45304    This mixin defines the API for modifying generic enumerables. These methods
45305    can be applied to an object regardless of whether it is ordered or
45306    unordered.
45307  
45308    Note that an Enumerable can change even if it does not implement this mixin.
45309    For example, a MappedEnumerable cannot be directly modified but if its
45310    underlying enumerable changes, it will change also.
45311  
45312    ## Adding Objects
45313  
45314    To add an object to an enumerable, use the `addObject()` method. This
45315    method will only add the object to the enumerable if the object is not
45316    already present and is of a type supported by the enumerable.
45317  
45318    ```javascript
45319    set.addObject(contact);
45320    ```
45321  
45322    ## Removing Objects
45323  
45324    To remove an object from an enumerable, use the `removeObject()` method. This
45325    will only remove the object if it is present in the enumerable, otherwise
45326    this method has no effect.
45327  
45328    ```javascript
45329    set.removeObject(contact);
45330    ```
45331  
45332    ## Implementing In Your Own Code
45333  
45334    If you are implementing an object and want to support this API, just include
45335    this mixin in your class and implement the required methods. In your unit
45336    tests, be sure to apply the Ember.MutableEnumerableTests to your object.
45337  
45338    @class MutableEnumerable
45339    @namespace Ember
45340    @uses Ember.Enumerable
45341    @public
45342  */
45343  exports.default = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsEnumerable.default, {
45344
45345    /**
45346      __Required.__ You must implement this method to apply this mixin.
45347       Attempts to add the passed object to the receiver if the object is not
45348      already present in the collection. If the object is present, this method
45349      has no effect.
45350       If the passed object is of a type not supported by the receiver,
45351      then this method should raise an exception.
45352       @method addObject
45353      @param {Object} object The object to add to the enumerable.
45354      @return {Object} the passed object
45355      @public
45356    */
45357    addObject: null,
45358
45359    /**
45360      Adds each object in the passed enumerable to the receiver.
45361       @method addObjects
45362      @param {Ember.Enumerable} objects the objects to add.
45363      @return {Object} receiver
45364      @public
45365    */
45366    addObjects: function (objects) {
45367      var _this = this;
45368
45369      _emberMetalProperty_events.beginPropertyChanges(this);
45370      objects.forEach(function (obj) {
45371        return _this.addObject(obj);
45372      });
45373      _emberMetalProperty_events.endPropertyChanges(this);
45374      return this;
45375    },
45376
45377    /**
45378      __Required.__ You must implement this method to apply this mixin.
45379       Attempts to remove the passed object from the receiver collection if the
45380      object is present in the collection. If the object is not present,
45381      this method has no effect.
45382       If the passed object is of a type not supported by the receiver,
45383      then this method should raise an exception.
45384       @method removeObject
45385      @param {Object} object The object to remove from the enumerable.
45386      @return {Object} the passed object
45387      @public
45388    */
45389    removeObject: null,
45390
45391    /**
45392      Removes each object in the passed enumerable from the receiver.
45393       @method removeObjects
45394      @param {Ember.Enumerable} objects the objects to remove
45395      @return {Object} receiver
45396      @public
45397    */
45398    removeObjects: function (objects) {
45399      _emberMetalProperty_events.beginPropertyChanges(this);
45400      for (var i = objects.length - 1; i >= 0; i--) {
45401        this.removeObject(objects[i]);
45402      }
45403      _emberMetalProperty_events.endPropertyChanges(this);
45404      return this;
45405    }
45406  });
45407});
45408enifed('ember-runtime/mixins/observable', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/get_properties', 'ember-metal/set_properties', 'ember-metal/mixin', 'ember-metal/events', 'ember-metal/property_events', 'ember-metal/observer', 'ember-metal/computed', 'ember-metal/is_none'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalGet_properties, _emberMetalSet_properties, _emberMetalMixin, _emberMetalEvents, _emberMetalProperty_events, _emberMetalObserver, _emberMetalComputed, _emberMetalIs_none) {
45409  /**
45410  @module ember
45411  @submodule ember-runtime
45412  */
45413
45414  'use strict';
45415
45416  /**
45417    ## Overview
45418  
45419    This mixin provides properties and property observing functionality, core
45420    features of the Ember object model.
45421  
45422    Properties and observers allow one object to observe changes to a
45423    property on another object. This is one of the fundamental ways that
45424    models, controllers and views communicate with each other in an Ember
45425    application.
45426  
45427    Any object that has this mixin applied can be used in observer
45428    operations. That includes `Ember.Object` and most objects you will
45429    interact with as you write your Ember application.
45430  
45431    Note that you will not generally apply this mixin to classes yourself,
45432    but you will use the features provided by this module frequently, so it
45433    is important to understand how to use it.
45434  
45435    ## Using `get()` and `set()`
45436  
45437    Because of Ember's support for bindings and observers, you will always
45438    access properties using the get method, and set properties using the
45439    set method. This allows the observing objects to be notified and
45440    computed properties to be handled properly.
45441  
45442    More documentation about `get` and `set` are below.
45443  
45444    ## Observing Property Changes
45445  
45446    You typically observe property changes simply by using the `Ember.observer`
45447    function in classes that you write.
45448  
45449    For example:
45450  
45451    ```javascript
45452    Ember.Object.extend({
45453      valueObserver: Ember.observer('value', function(sender, key, value, rev) {
45454        // Executes whenever the "value" property changes
45455        // See the addObserver method for more information about the callback arguments
45456      })
45457    });
45458    ```
45459  
45460    Although this is the most common way to add an observer, this capability
45461    is actually built into the `Ember.Object` class on top of two methods
45462    defined in this mixin: `addObserver` and `removeObserver`. You can use
45463    these two methods to add and remove observers yourself if you need to
45464    do so at runtime.
45465  
45466    To add an observer for a property, call:
45467  
45468    ```javascript
45469    object.addObserver('propertyKey', targetObject, targetAction)
45470    ```
45471  
45472    This will call the `targetAction` method on the `targetObject` whenever
45473    the value of the `propertyKey` changes.
45474  
45475    Note that if `propertyKey` is a computed property, the observer will be
45476    called when any of the property dependencies are changed, even if the
45477    resulting value of the computed property is unchanged. This is necessary
45478    because computed properties are not computed until `get` is called.
45479  
45480    @class Observable
45481    @namespace Ember
45482    @public
45483  */
45484  exports.default = _emberMetalMixin.Mixin.create({
45485
45486    /**
45487      Retrieves the value of a property from the object.
45488       This method is usually similar to using `object[keyName]` or `object.keyName`,
45489      however it supports both computed properties and the unknownProperty
45490      handler.
45491       Because `get` unifies the syntax for accessing all these kinds
45492      of properties, it can make many refactorings easier, such as replacing a
45493      simple property with a computed property, or vice versa.
45494       ### Computed Properties
45495       Computed properties are methods defined with the `property` modifier
45496      declared at the end, such as:
45497       ```javascript
45498      fullName: function() {
45499        return this.get('firstName') + ' ' + this.get('lastName');
45500      }.property('firstName', 'lastName')
45501      ```
45502       When you call `get` on a computed property, the function will be
45503      called and the return value will be returned instead of the function
45504      itself.
45505       ### Unknown Properties
45506       Likewise, if you try to call `get` on a property whose value is
45507      `undefined`, the `unknownProperty()` method will be called on the object.
45508      If this method returns any value other than `undefined`, it will be returned
45509      instead. This allows you to implement "virtual" properties that are
45510      not defined upfront.
45511       @method get
45512      @param {String} keyName The property to retrieve
45513      @return {Object} The property value or undefined.
45514      @public
45515    */
45516    get: function (keyName) {
45517      return _emberMetalProperty_get.get(this, keyName);
45518    },
45519
45520    /**
45521      To get the values of multiple properties at once, call `getProperties`
45522      with a list of strings or an array:
45523       ```javascript
45524      record.getProperties('firstName', 'lastName', 'zipCode');
45525      // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
45526      ```
45527       is equivalent to:
45528       ```javascript
45529      record.getProperties(['firstName', 'lastName', 'zipCode']);
45530      // { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
45531      ```
45532       @method getProperties
45533      @param {String...|Array} list of keys to get
45534      @return {Object}
45535      @public
45536    */
45537    getProperties: function () {
45538      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
45539        args[_key] = arguments[_key];
45540      }
45541
45542      return _emberMetalGet_properties.default.apply(null, [this].concat(args));
45543    },
45544
45545    /**
45546      Sets the provided key or path to the value.
45547       This method is generally very similar to calling `object[key] = value` or
45548      `object.key = value`, except that it provides support for computed
45549      properties, the `setUnknownProperty()` method and property observers.
45550       ### Computed Properties
45551       If you try to set a value on a key that has a computed property handler
45552      defined (see the `get()` method for an example), then `set()` will call
45553      that method, passing both the value and key instead of simply changing
45554      the value itself. This is useful for those times when you need to
45555      implement a property that is composed of one or more member
45556      properties.
45557       ### Unknown Properties
45558       If you try to set a value on a key that is undefined in the target
45559      object, then the `setUnknownProperty()` handler will be called instead. This
45560      gives you an opportunity to implement complex "virtual" properties that
45561      are not predefined on the object. If `setUnknownProperty()` returns
45562      undefined, then `set()` will simply set the value on the object.
45563       ### Property Observers
45564       In addition to changing the property, `set()` will also register a property
45565      change with the object. Unless you have placed this call inside of a
45566      `beginPropertyChanges()` and `endPropertyChanges(),` any "local" observers
45567      (i.e. observer methods declared on the same object), will be called
45568      immediately. Any "remote" observers (i.e. observer methods declared on
45569      another object) will be placed in a queue and called at a later time in a
45570      coalesced manner.
45571       @method set
45572      @param {String} keyName The property to set
45573      @param {Object} value The value to set or `null`.
45574      @return {Object} The passed value
45575      @public
45576    */
45577    set: function (keyName, value) {
45578      return _emberMetalProperty_set.set(this, keyName, value);
45579    },
45580
45581    /**
45582      Sets a list of properties at once. These properties are set inside
45583      a single `beginPropertyChanges` and `endPropertyChanges` batch, so
45584      observers will be buffered.
45585       ```javascript
45586      record.setProperties({ firstName: 'Charles', lastName: 'Jolley' });
45587      ```
45588       @method setProperties
45589      @param {Object} hash the hash of keys and values to set
45590      @return {Object} The passed in hash
45591      @public
45592    */
45593    setProperties: function (hash) {
45594      return _emberMetalSet_properties.default(this, hash);
45595    },
45596
45597    /**
45598      Begins a grouping of property changes.
45599       You can use this method to group property changes so that notifications
45600      will not be sent until the changes are finished. If you plan to make a
45601      large number of changes to an object at one time, you should call this
45602      method at the beginning of the changes to begin deferring change
45603      notifications. When you are done making changes, call
45604      `endPropertyChanges()` to deliver the deferred change notifications and end
45605      deferring.
45606       @method beginPropertyChanges
45607      @return {Ember.Observable}
45608      @private
45609    */
45610    beginPropertyChanges: function () {
45611      _emberMetalProperty_events.beginPropertyChanges();
45612      return this;
45613    },
45614
45615    /**
45616      Ends a grouping of property changes.
45617       You can use this method to group property changes so that notifications
45618      will not be sent until the changes are finished. If you plan to make a
45619      large number of changes to an object at one time, you should call
45620      `beginPropertyChanges()` at the beginning of the changes to defer change
45621      notifications. When you are done making changes, call this method to
45622      deliver the deferred change notifications and end deferring.
45623       @method endPropertyChanges
45624      @return {Ember.Observable}
45625      @private
45626    */
45627    endPropertyChanges: function () {
45628      _emberMetalProperty_events.endPropertyChanges();
45629      return this;
45630    },
45631
45632    /**
45633      Notify the observer system that a property is about to change.
45634       Sometimes you need to change a value directly or indirectly without
45635      actually calling `get()` or `set()` on it. In this case, you can use this
45636      method and `propertyDidChange()` instead. Calling these two methods
45637      together will notify all observers that the property has potentially
45638      changed value.
45639       Note that you must always call `propertyWillChange` and `propertyDidChange`
45640      as a pair. If you do not, it may get the property change groups out of
45641      order and cause notifications to be delivered more often than you would
45642      like.
45643       @method propertyWillChange
45644      @param {String} keyName The property key that is about to change.
45645      @return {Ember.Observable}
45646      @private
45647    */
45648    propertyWillChange: function (keyName) {
45649      _emberMetalProperty_events.propertyWillChange(this, keyName);
45650      return this;
45651    },
45652
45653    /**
45654      Notify the observer system that a property has just changed.
45655       Sometimes you need to change a value directly or indirectly without
45656      actually calling `get()` or `set()` on it. In this case, you can use this
45657      method and `propertyWillChange()` instead. Calling these two methods
45658      together will notify all observers that the property has potentially
45659      changed value.
45660       Note that you must always call `propertyWillChange` and `propertyDidChange`
45661      as a pair. If you do not, it may get the property change groups out of
45662      order and cause notifications to be delivered more often than you would
45663      like.
45664       @method propertyDidChange
45665      @param {String} keyName The property key that has just changed.
45666      @return {Ember.Observable}
45667      @private
45668    */
45669    propertyDidChange: function (keyName) {
45670      _emberMetalProperty_events.propertyDidChange(this, keyName);
45671      return this;
45672    },
45673
45674    /**
45675      Convenience method to call `propertyWillChange` and `propertyDidChange` in
45676      succession.
45677       @method notifyPropertyChange
45678      @param {String} keyName The property key to be notified about.
45679      @return {Ember.Observable}
45680      @public
45681    */
45682    notifyPropertyChange: function (keyName) {
45683      this.propertyWillChange(keyName);
45684      this.propertyDidChange(keyName);
45685      return this;
45686    },
45687
45688    /**
45689      Adds an observer on a property.
45690       This is the core method used to register an observer for a property.
45691       Once you call this method, any time the key's value is set, your observer
45692      will be notified. Note that the observers are triggered any time the
45693      value is set, regardless of whether it has actually changed. Your
45694      observer should be prepared to handle that.
45695       You can also pass an optional context parameter to this method. The
45696      context will be passed to your observer method whenever it is triggered.
45697      Note that if you add the same target/method pair on a key multiple times
45698      with different context parameters, your observer will only be called once
45699      with the last context you passed.
45700       ### Observer Methods
45701       Observer methods you pass should generally have the following signature if
45702      you do not pass a `context` parameter:
45703       ```javascript
45704      fooDidChange: function(sender, key, value, rev) { };
45705      ```
45706       The sender is the object that changed. The key is the property that
45707      changes. The value property is currently reserved and unused. The rev
45708      is the last property revision of the object when it changed, which you can
45709      use to detect if the key value has really changed or not.
45710       If you pass a `context` parameter, the context will be passed before the
45711      revision like so:
45712       ```javascript
45713      fooDidChange: function(sender, key, value, context, rev) { };
45714      ```
45715       Usually you will not need the value, context or revision parameters at
45716      the end. In this case, it is common to write observer methods that take
45717      only a sender and key value as parameters or, if you aren't interested in
45718      any of these values, to write an observer that has no parameters at all.
45719       @method addObserver
45720      @param {String} key The key to observer
45721      @param {Object} target The target object to invoke
45722      @param {String|Function} method The method to invoke.
45723      @public
45724    */
45725    addObserver: function (key, target, method) {
45726      _emberMetalObserver.addObserver(this, key, target, method);
45727    },
45728
45729    /**
45730      Remove an observer you have previously registered on this object. Pass
45731      the same key, target, and method you passed to `addObserver()` and your
45732      target will no longer receive notifications.
45733       @method removeObserver
45734      @param {String} key The key to observer
45735      @param {Object} target The target object to invoke
45736      @param {String|Function} method The method to invoke.
45737      @public
45738    */
45739    removeObserver: function (key, target, method) {
45740      _emberMetalObserver.removeObserver(this, key, target, method);
45741    },
45742
45743    /**
45744      Returns `true` if the object currently has observers registered for a
45745      particular key. You can use this method to potentially defer performing
45746      an expensive action until someone begins observing a particular property
45747      on the object.
45748       @method hasObserverFor
45749      @param {String} key Key to check
45750      @return {Boolean}
45751      @private
45752    */
45753    hasObserverFor: function (key) {
45754      return _emberMetalEvents.hasListeners(this, key + ':change');
45755    },
45756
45757    /**
45758      Retrieves the value of a property, or a default value in the case that the
45759      property returns `undefined`.
45760       ```javascript
45761      person.getWithDefault('lastName', 'Doe');
45762      ```
45763       @method getWithDefault
45764      @param {String} keyName The name of the property to retrieve
45765      @param {Object} defaultValue The value to return if the property value is undefined
45766      @return {Object} The property value or the defaultValue.
45767      @public
45768    */
45769    getWithDefault: function (keyName, defaultValue) {
45770      return _emberMetalProperty_get.getWithDefault(this, keyName, defaultValue);
45771    },
45772
45773    /**
45774      Set the value of a property to the current value plus some amount.
45775       ```javascript
45776      person.incrementProperty('age');
45777      team.incrementProperty('score', 2);
45778      ```
45779       @method incrementProperty
45780      @param {String} keyName The name of the property to increment
45781      @param {Number} increment The amount to increment by. Defaults to 1
45782      @return {Number} The new property value
45783      @public
45784    */
45785    incrementProperty: function (keyName, increment) {
45786      if (_emberMetalIs_none.default(increment)) {
45787        increment = 1;
45788      }
45789      _emberMetalDebug.assert('Must pass a numeric value to incrementProperty', !isNaN(parseFloat(increment)) && isFinite(increment));
45790      return _emberMetalProperty_set.set(this, keyName, (parseFloat(_emberMetalProperty_get.get(this, keyName)) || 0) + increment);
45791    },
45792
45793    /**
45794      Set the value of a property to the current value minus some amount.
45795       ```javascript
45796      player.decrementProperty('lives');
45797      orc.decrementProperty('health', 5);
45798      ```
45799       @method decrementProperty
45800      @param {String} keyName The name of the property to decrement
45801      @param {Number} decrement The amount to decrement by. Defaults to 1
45802      @return {Number} The new property value
45803      @public
45804    */
45805    decrementProperty: function (keyName, decrement) {
45806      if (_emberMetalIs_none.default(decrement)) {
45807        decrement = 1;
45808      }
45809      _emberMetalDebug.assert('Must pass a numeric value to decrementProperty', !isNaN(parseFloat(decrement)) && isFinite(decrement));
45810      return _emberMetalProperty_set.set(this, keyName, (_emberMetalProperty_get.get(this, keyName) || 0) - decrement);
45811    },
45812
45813    /**
45814      Set the value of a boolean property to the opposite of its
45815      current value.
45816       ```javascript
45817      starship.toggleProperty('warpDriveEngaged');
45818      ```
45819       @method toggleProperty
45820      @param {String} keyName The name of the property to toggle
45821      @return {Boolean} The new property value
45822      @public
45823    */
45824    toggleProperty: function (keyName) {
45825      return _emberMetalProperty_set.set(this, keyName, !_emberMetalProperty_get.get(this, keyName));
45826    },
45827
45828    /**
45829      Returns the cached value of a computed property, if it exists.
45830      This allows you to inspect the value of a computed property
45831      without accidentally invoking it if it is intended to be
45832      generated lazily.
45833       @method cacheFor
45834      @param {String} keyName
45835      @return {Object} The cached value of the computed property, if any
45836      @public
45837    */
45838    cacheFor: function (keyName) {
45839      return _emberMetalComputed.cacheFor(this, keyName);
45840    },
45841
45842    // intended for debugging purposes
45843    observersForKey: function (keyName) {
45844      return _emberMetalObserver.observersFor(this, keyName);
45845    }
45846  });
45847});
45848enifed('ember-runtime/mixins/promise_proxy', ['exports', 'ember-metal/property_get', 'ember-metal/set_properties', 'ember-metal/computed', 'ember-metal/mixin', 'ember-metal/error'], function (exports, _emberMetalProperty_get, _emberMetalSet_properties, _emberMetalComputed, _emberMetalMixin, _emberMetalError) {
45849  'use strict';
45850
45851  var not = _emberMetalComputed.computed.not;
45852  var or = _emberMetalComputed.computed.or;
45853
45854  /**
45855    @module ember
45856    @submodule ember-runtime
45857  */
45858
45859  function tap(proxy, promise) {
45860    _emberMetalSet_properties.default(proxy, {
45861      isFulfilled: false,
45862      isRejected: false
45863    });
45864
45865    return promise.then(function (value) {
45866      _emberMetalSet_properties.default(proxy, {
45867        content: value,
45868        isFulfilled: true
45869      });
45870      return value;
45871    }, function (reason) {
45872      _emberMetalSet_properties.default(proxy, {
45873        reason: reason,
45874        isRejected: true
45875      });
45876      throw reason;
45877    }, 'Ember: PromiseProxy');
45878  }
45879
45880  /**
45881    A low level mixin making ObjectProxy promise-aware.
45882  
45883    ```javascript
45884    var ObjectPromiseProxy = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);
45885  
45886    var proxy = ObjectPromiseProxy.create({
45887      promise: $.getJSON('/some/remote/data.json')
45888    });
45889  
45890    proxy.then(function(json){
45891       // the json
45892    }, function(reason) {
45893       // the reason why you have no json
45894    });
45895    ```
45896  
45897    the proxy has bindable attributes which
45898    track the promises life cycle
45899  
45900    ```javascript
45901    proxy.get('isPending')   //=> true
45902    proxy.get('isSettled')  //=> false
45903    proxy.get('isRejected')  //=> false
45904    proxy.get('isFulfilled') //=> false
45905    ```
45906  
45907    When the $.getJSON completes, and the promise is fulfilled
45908    with json, the life cycle attributes will update accordingly.
45909  
45910    ```javascript
45911    proxy.get('isPending')   //=> false
45912    proxy.get('isSettled')   //=> true
45913    proxy.get('isRejected')  //=> false
45914    proxy.get('isFulfilled') //=> true
45915    ```
45916  
45917    As the proxy is an ObjectProxy, and the json now its content,
45918    all the json properties will be available directly from the proxy.
45919  
45920    ```javascript
45921    // Assuming the following json:
45922    {
45923      firstName: 'Stefan',
45924      lastName: 'Penner'
45925    }
45926  
45927    // both properties will accessible on the proxy
45928    proxy.get('firstName') //=> 'Stefan'
45929    proxy.get('lastName')  //=> 'Penner'
45930    ```
45931  
45932    @class Ember.PromiseProxyMixin
45933    @public
45934  */
45935  exports.default = _emberMetalMixin.Mixin.create({
45936    /**
45937      If the proxied promise is rejected this will contain the reason
45938      provided.
45939       @property reason
45940      @default null
45941      @public
45942    */
45943    reason: null,
45944
45945    /**
45946      Once the proxied promise has settled this will become `false`.
45947       @property isPending
45948      @default true
45949      @public
45950    */
45951    isPending: not('isSettled').readOnly(),
45952
45953    /**
45954      Once the proxied promise has settled this will become `true`.
45955       @property isSettled
45956      @default false
45957      @public
45958    */
45959    isSettled: or('isRejected', 'isFulfilled').readOnly(),
45960
45961    /**
45962      Will become `true` if the proxied promise is rejected.
45963       @property isRejected
45964      @default false
45965      @public
45966    */
45967    isRejected: false,
45968
45969    /**
45970      Will become `true` if the proxied promise is fulfilled.
45971       @property isFulfilled
45972      @default false
45973      @public
45974    */
45975    isFulfilled: false,
45976
45977    /**
45978      The promise whose fulfillment value is being proxied by this object.
45979       This property must be specified upon creation, and should not be
45980      changed once created.
45981       Example:
45982       ```javascript
45983      Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
45984        promise: <thenable>
45985      });
45986      ```
45987       @property promise
45988      @public
45989    */
45990    promise: _emberMetalComputed.computed({
45991      get: function () {
45992        throw new _emberMetalError.default('PromiseProxy\'s promise must be set');
45993      },
45994      set: function (key, promise) {
45995        return tap(this, promise);
45996      }
45997    }),
45998
45999    /**
46000      An alias to the proxied promise's `then`.
46001       See RSVP.Promise.then.
46002       @method then
46003      @param {Function} callback
46004      @return {RSVP.Promise}
46005      @public
46006    */
46007    then: promiseAlias('then'),
46008
46009    /**
46010      An alias to the proxied promise's `catch`.
46011       See RSVP.Promise.catch.
46012       @method catch
46013      @param {Function} callback
46014      @return {RSVP.Promise}
46015      @since 1.3.0
46016      @public
46017    */
46018    'catch': promiseAlias('catch'),
46019
46020    /**
46021      An alias to the proxied promise's `finally`.
46022       See RSVP.Promise.finally.
46023       @method finally
46024      @param {Function} callback
46025      @return {RSVP.Promise}
46026      @since 1.3.0
46027      @public
46028    */
46029    'finally': promiseAlias('finally')
46030
46031  });
46032
46033  function promiseAlias(name) {
46034    return function () {
46035      var promise = _emberMetalProperty_get.get(this, 'promise');
46036      return promise[name].apply(promise, arguments);
46037    };
46038  }
46039});
46040enifed('ember-runtime/mixins/registry_proxy', ['exports', 'ember-metal/debug', 'ember-metal/mixin'], function (exports, _emberMetalDebug, _emberMetalMixin) {
46041  /**
46042  @module ember
46043  @submodule ember-runtime
46044  */
46045
46046  'use strict';
46047
46048  exports.buildFakeRegistryWithDeprecations = buildFakeRegistryWithDeprecations;
46049
46050  /**
46051    RegistryProxyMixin is used to provide public access to specific
46052    registry functionality.
46053  
46054    @class RegistryProxyMixin
46055    @private
46056  */
46057  exports.default = _emberMetalMixin.Mixin.create({
46058    __registry__: null,
46059
46060    /**
46061     Given a fullName return the corresponding factory.
46062      @public
46063     @method resolveRegistration
46064     @param {String} fullName
46065     @return {Function} fullName's factory
46066     */
46067    resolveRegistration: registryAlias('resolve'),
46068
46069    /**
46070      Registers a factory that can be used for dependency injection (with
46071      `inject`) or for service lookup. Each factory is registered with
46072      a full name including two parts: `type:name`.
46073       A simple example:
46074       ```javascript
46075      var App = Ember.Application.create();
46076       App.Orange = Ember.Object.extend();
46077      App.register('fruit:favorite', App.Orange);
46078      ```
46079       Ember will resolve factories from the `App` namespace automatically.
46080      For example `App.CarsController` will be discovered and returned if
46081      an application requests `controller:cars`.
46082       An example of registering a controller with a non-standard name:
46083       ```javascript
46084      var App = Ember.Application.create();
46085      var Session = Ember.Controller.extend();
46086       App.register('controller:session', Session);
46087       // The Session controller can now be treated like a normal controller,
46088      // despite its non-standard name.
46089      App.ApplicationController = Ember.Controller.extend({
46090        needs: ['session']
46091      });
46092      ```
46093       Registered factories are **instantiated** by having `create`
46094      called on them. Additionally they are **singletons**, each time
46095      they are looked up they return the same instance.
46096       Some examples modifying that default behavior:
46097       ```javascript
46098      var App = Ember.Application.create();
46099       App.Person = Ember.Object.extend();
46100      App.Orange = Ember.Object.extend();
46101      App.Email = Ember.Object.extend();
46102      App.session = Ember.Object.create();
46103       App.register('model:user', App.Person, { singleton: false });
46104      App.register('fruit:favorite', App.Orange);
46105      App.register('communication:main', App.Email, { singleton: false });
46106      App.register('session', App.session, { instantiate: false });
46107      ```
46108       @method register
46109      @param  fullName {String} type:name (e.g., 'model:user')
46110      @param  factory {Function} (e.g., App.Person)
46111      @param  options {Object} (optional) disable instantiation or singleton usage
46112      @public
46113     */
46114    register: registryAlias('register'),
46115
46116    /**
46117     Unregister a factory.
46118      ```javascript
46119     var App = Ember.Application.create();
46120     var User = Ember.Object.extend();
46121     App.register('model:user', User);
46122      App.resolveRegistration('model:user').create() instanceof User //=> true
46123      App.unregister('model:user')
46124     App.resolveRegistration('model:user') === undefined //=> true
46125     ```
46126      @public
46127     @method unregister
46128     @param {String} fullName
46129     */
46130    unregister: registryAlias('unregister'),
46131
46132    /**
46133     Check if a factory is registered.
46134      @public
46135     @method hasRegistration
46136     @param {String} fullName
46137     @return {Boolean}
46138     */
46139    hasRegistration: registryAlias('has'),
46140
46141    /**
46142     Register an option for a particular factory.
46143      @public
46144     @method registerOption
46145     @param {String} fullName
46146     @param {String} optionName
46147     @param {Object} options
46148     */
46149    registerOption: registryAlias('option'),
46150
46151    /**
46152     Return a specific registered option for a particular factory.
46153      @public
46154     @method registeredOption
46155     @param  {String} fullName
46156     @param  {String} optionName
46157     @return {Object} options
46158     */
46159    registeredOption: registryAlias('getOption'),
46160
46161    /**
46162     Register options for a particular factory.
46163      @public
46164     @method registerOptions
46165     @param {String} fullName
46166     @param {Object} options
46167     */
46168    registerOptions: registryAlias('options'),
46169
46170    /**
46171     Return registered options for a particular factory.
46172      @public
46173     @method registeredOptions
46174     @param  {String} fullName
46175     @return {Object} options
46176     */
46177    registeredOptions: registryAlias('getOptions'),
46178
46179    /**
46180     Allow registering options for all factories of a type.
46181      ```javascript
46182     var App = Ember.Application.create();
46183     var appInstance = App.buildInstance();
46184      // if all of type `connection` must not be singletons
46185     appInstance.optionsForType('connection', { singleton: false });
46186      appInstance.register('connection:twitter', TwitterConnection);
46187     appInstance.register('connection:facebook', FacebookConnection);
46188      var twitter = appInstance.lookup('connection:twitter');
46189     var twitter2 = appInstance.lookup('connection:twitter');
46190      twitter === twitter2; // => false
46191      var facebook = appInstance.lookup('connection:facebook');
46192     var facebook2 = appInstance.lookup('connection:facebook');
46193      facebook === facebook2; // => false
46194     ```
46195      @public
46196     @method registerOptionsForType
46197     @param {String} type
46198     @param {Object} options
46199     */
46200    registerOptionsForType: registryAlias('optionsForType'),
46201
46202    /**
46203     Return the registered options for all factories of a type.
46204      @public
46205     @method registeredOptionsForType
46206     @param {String} type
46207     @return {Object} options
46208     */
46209    registeredOptionsForType: registryAlias('getOptionsForType'),
46210
46211    /**
46212      Define a dependency injection onto a specific factory or all factories
46213      of a type.
46214       When Ember instantiates a controller, view, or other framework component
46215      it can attach a dependency to that component. This is often used to
46216      provide services to a set of framework components.
46217       An example of providing a session object to all controllers:
46218       ```javascript
46219      var App = Ember.Application.create();
46220      var Session = Ember.Object.extend({ isAuthenticated: false });
46221       // A factory must be registered before it can be injected
46222      App.register('session:main', Session);
46223       // Inject 'session:main' onto all factories of the type 'controller'
46224      // with the name 'session'
46225      App.inject('controller', 'session', 'session:main');
46226       App.IndexController = Ember.Controller.extend({
46227        isLoggedIn: Ember.computed.alias('session.isAuthenticated')
46228      });
46229      ```
46230       Injections can also be performed on specific factories.
46231       ```javascript
46232      App.inject(<full_name or type>, <property name>, <full_name>)
46233      App.inject('route', 'source', 'source:main')
46234      App.inject('route:application', 'email', 'model:email')
46235      ```
46236       It is important to note that injections can only be performed on
46237      classes that are instantiated by Ember itself. Instantiating a class
46238      directly (via `create` or `new`) bypasses the dependency injection
46239      system.
46240       **Note:** Ember-Data instantiates its models in a unique manner, and consequently
46241      injections onto models (or all models) will not work as expected. Injections
46242      on models can be enabled by setting `Ember.MODEL_FACTORY_INJECTIONS`
46243      to `true`.
46244       @public
46245      @method inject
46246      @param  factoryNameOrType {String}
46247      @param  property {String}
46248      @param  injectionName {String}
46249    **/
46250    inject: registryAlias('injection')
46251  });
46252
46253  function registryAlias(name) {
46254    return function () {
46255      var _registry__;
46256
46257      return (_registry__ = this.__registry__)[name].apply(_registry__, arguments);
46258    };
46259  }
46260
46261  function buildFakeRegistryWithDeprecations(instance, typeForMessage) {
46262    var fakeRegistry = {};
46263    var registryProps = {
46264      resolve: 'resolveRegistration',
46265      register: 'register',
46266      unregister: 'unregister',
46267      has: 'hasRegistration',
46268      option: 'registerOption',
46269      options: 'registerOptions',
46270      getOptions: 'registeredOptions',
46271      optionsForType: 'registerOptionsForType',
46272      getOptionsForType: 'registeredOptionsForType',
46273      injection: 'inject'
46274    };
46275
46276    for (var deprecatedProperty in registryProps) {
46277      fakeRegistry[deprecatedProperty] = buildFakeRegistryFunction(instance, typeForMessage, deprecatedProperty, registryProps[deprecatedProperty]);
46278    }
46279
46280    return fakeRegistry;
46281  }
46282
46283  function buildFakeRegistryFunction(instance, typeForMessage, deprecatedProperty, nonDeprecatedProperty) {
46284    return function () {
46285      _emberMetalDebug.deprecate('Using `' + typeForMessage + '.registry.' + deprecatedProperty + '` is deprecated. Please use `' + typeForMessage + '.' + nonDeprecatedProperty + '` instead.', false, {
46286        id: 'ember-application.app-instance-registry',
46287        until: '3.0.0',
46288        url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-application-registry-ember-applicationinstance-registry'
46289      });
46290      return instance[nonDeprecatedProperty].apply(instance, arguments);
46291    };
46292  }
46293});
46294enifed('ember-runtime/mixins/target_action_support', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/mixin', 'ember-metal/computed'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalProperty_get, _emberMetalMixin, _emberMetalComputed) {
46295  /**
46296  @module ember
46297  @submodule ember-runtime
46298  */
46299
46300  'use strict';
46301
46302  /**
46303  `Ember.TargetActionSupport` is a mixin that can be included in a class
46304  to add a `triggerAction` method with semantics similar to the Handlebars
46305  `{{action}}` helper. In normal Ember usage, the `{{action}}` helper is
46306  usually the best choice. This mixin is most often useful when you are
46307  doing more complex event handling in View objects.
46308  
46309  See also `Ember.ViewTargetActionSupport`, which has
46310  view-aware defaults for target and actionContext.
46311  
46312  @class TargetActionSupport
46313  @namespace Ember
46314  @extends Ember.Mixin
46315  @private
46316  */
46317  var TargetActionSupport = _emberMetalMixin.Mixin.create({
46318    target: null,
46319    action: null,
46320    actionContext: null,
46321
46322    targetObject: _emberMetalComputed.computed('target', function () {
46323      if (this._targetObject) {
46324        return this._targetObject;
46325      }
46326
46327      var target = _emberMetalProperty_get.get(this, 'target');
46328
46329      if (typeof target === 'string') {
46330        var value = _emberMetalProperty_get.get(this, target);
46331        if (value === undefined) {
46332          value = _emberMetalProperty_get.get(_emberMetalCore.default.lookup, target);
46333        }
46334
46335        return value;
46336      } else {
46337        return target;
46338      }
46339    }),
46340
46341    actionContextObject: _emberMetalComputed.computed(function () {
46342      var actionContext = _emberMetalProperty_get.get(this, 'actionContext');
46343
46344      if (typeof actionContext === 'string') {
46345        var value = _emberMetalProperty_get.get(this, actionContext);
46346        if (value === undefined) {
46347          value = _emberMetalProperty_get.get(_emberMetalCore.default.lookup, actionContext);
46348        }
46349        return value;
46350      } else {
46351        return actionContext;
46352      }
46353    }).property('actionContext'),
46354
46355    /**
46356    Send an `action` with an `actionContext` to a `target`. The action, actionContext
46357    and target will be retrieved from properties of the object. For example:
46358     ```javascript
46359    App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
46360      target: Ember.computed.alias('controller'),
46361      action: 'save',
46362      actionContext: Ember.computed.alias('context'),
46363      click: function() {
46364        this.triggerAction(); // Sends the `save` action, along with the current context
46365                              // to the current controller
46366      }
46367    });
46368    ```
46369     The `target`, `action`, and `actionContext` can be provided as properties of
46370    an optional object argument to `triggerAction` as well.
46371     ```javascript
46372    App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
46373      click: function() {
46374        this.triggerAction({
46375          action: 'save',
46376          target: this.get('controller'),
46377          actionContext: this.get('context')
46378        }); // Sends the `save` action, along with the current context
46379            // to the current controller
46380      }
46381    });
46382    ```
46383     The `actionContext` defaults to the object you are mixing `TargetActionSupport` into.
46384    But `target` and `action` must be specified either as properties or with the argument
46385    to `triggerAction`, or a combination:
46386     ```javascript
46387    App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
46388      target: Ember.computed.alias('controller'),
46389      click: function() {
46390        this.triggerAction({
46391          action: 'save'
46392        }); // Sends the `save` action, along with a reference to `this`,
46393            // to the current controller
46394      }
46395    });
46396    ```
46397     @method triggerAction
46398    @param opts {Object} (optional, with the optional keys action, target and/or actionContext)
46399    @return {Boolean} true if the action was sent successfully and did not return false
46400    @private
46401    */
46402    triggerAction: function () {
46403      var opts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
46404
46405      var action = opts.action || _emberMetalProperty_get.get(this, 'action');
46406      var target = opts.target || _emberMetalProperty_get.get(this, 'targetObject');
46407      var actionContext = opts.actionContext;
46408
46409      function args(options, actionName) {
46410        var ret = [];
46411        if (actionName) {
46412          ret.push(actionName);
46413        }
46414
46415        return ret.concat(options);
46416      }
46417
46418      if (typeof actionContext === 'undefined') {
46419        actionContext = _emberMetalProperty_get.get(this, 'actionContextObject') || this;
46420      }
46421
46422      if (target && action) {
46423        var ret;
46424
46425        if (target.send) {
46426          ret = target.send.apply(target, args(actionContext, action));
46427        } else {
46428          _emberMetalDebug.assert('The action \'' + action + '\' did not exist on ' + target, typeof target[action] === 'function');
46429          ret = target[action].apply(target, args(actionContext));
46430        }
46431
46432        if (ret !== false) {
46433          ret = true;
46434        }
46435
46436        return ret;
46437      } else {
46438        return false;
46439      }
46440    }
46441  });
46442
46443  exports.default = TargetActionSupport;
46444});
46445// Ember.lookup
46446enifed("ember-runtime/string_registry", ["exports"], function (exports) {
46447  // STATE within a module is frowned apon, this exists
46448  // to support Ember.STRINGS but shield ember internals from this legacy global
46449  // API.
46450  "use strict";
46451
46452  exports.setStrings = setStrings;
46453  exports.getStrings = getStrings;
46454  exports.get = get;
46455  var STRINGS = {};
46456
46457  function setStrings(strings) {
46458    STRINGS = strings;
46459  }
46460
46461  function getStrings() {
46462    return STRINGS;
46463  }
46464
46465  function get(name) {
46466    return STRINGS[name];
46467  }
46468});
46469enifed('ember-runtime/system/application', ['exports', 'ember-runtime/system/namespace'], function (exports, _emberRuntimeSystemNamespace) {
46470  'use strict';
46471
46472  exports.default = _emberRuntimeSystemNamespace.default.extend();
46473});
46474enifed('ember-runtime/system/array_proxy', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-runtime/utils', 'ember-metal/computed', 'ember-metal/mixin', 'ember-metal/property_events', 'ember-metal/error', 'ember-runtime/system/object', 'ember-runtime/mixins/mutable_array', 'ember-runtime/mixins/enumerable', 'ember-metal/alias', 'ember-runtime/mixins/array'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberRuntimeUtils, _emberMetalComputed, _emberMetalMixin, _emberMetalProperty_events, _emberMetalError, _emberRuntimeSystemObject, _emberRuntimeMixinsMutable_array, _emberRuntimeMixinsEnumerable, _emberMetalAlias, _emberRuntimeMixinsArray) {
46475  'use strict';
46476
46477  /**
46478  @module ember
46479  @submodule ember-runtime
46480  */
46481
46482  var OUT_OF_RANGE_EXCEPTION = 'Index out of range';
46483  var EMPTY = [];
46484
46485  function K() {
46486    return this;
46487  }
46488
46489  /**
46490    An ArrayProxy wraps any other object that implements `Ember.Array` and/or
46491    `Ember.MutableArray,` forwarding all requests. This makes it very useful for
46492    a number of binding use cases or other cases where being able to swap
46493    out the underlying array is useful.
46494  
46495    A simple example of usage:
46496  
46497    ```javascript
46498    var pets = ['dog', 'cat', 'fish'];
46499    var ap = Ember.ArrayProxy.create({ content: Ember.A(pets) });
46500  
46501    ap.get('firstObject');                        // 'dog'
46502    ap.set('content', ['amoeba', 'paramecium']);
46503    ap.get('firstObject');                        // 'amoeba'
46504    ```
46505  
46506    This class can also be useful as a layer to transform the contents of
46507    an array, as they are accessed. This can be done by overriding
46508    `objectAtContent`:
46509  
46510    ```javascript
46511    var pets = ['dog', 'cat', 'fish'];
46512    var ap = Ember.ArrayProxy.create({
46513        content: Ember.A(pets),
46514        objectAtContent: function(idx) {
46515            return this.get('content').objectAt(idx).toUpperCase();
46516        }
46517    });
46518  
46519    ap.get('firstObject'); // . 'DOG'
46520    ```
46521  
46522    @class ArrayProxy
46523    @namespace Ember
46524    @extends Ember.Object
46525    @uses Ember.MutableArray
46526    @public
46527  */
46528  var ArrayProxy = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsMutable_array.default, {
46529
46530    /**
46531      The content array. Must be an object that implements `Ember.Array` and/or
46532      `Ember.MutableArray.`
46533       @property content
46534      @type Ember.Array
46535      @private
46536    */
46537    content: null,
46538
46539    /**
46540     The array that the proxy pretends to be. In the default `ArrayProxy`
46541     implementation, this and `content` are the same. Subclasses of `ArrayProxy`
46542     can override this property to provide things like sorting and filtering.
46543      @property arrangedContent
46544     @private
46545    */
46546    arrangedContent: _emberMetalAlias.default('content'),
46547
46548    /**
46549      Should actually retrieve the object at the specified index from the
46550      content. You can override this method in subclasses to transform the
46551      content item to something new.
46552       This method will only be called if content is non-`null`.
46553       @method objectAtContent
46554      @param {Number} idx The index to retrieve.
46555      @return {Object} the value or undefined if none found
46556      @private
46557    */
46558    objectAtContent: function (idx) {
46559      return _emberRuntimeMixinsArray.objectAt(_emberMetalProperty_get.get(this, 'arrangedContent'), idx);
46560    },
46561
46562    /**
46563      Should actually replace the specified objects on the content array.
46564      You can override this method in subclasses to transform the content item
46565      into something new.
46566       This method will only be called if content is non-`null`.
46567       @method replaceContent
46568      @param {Number} idx The starting index
46569      @param {Number} amt The number of items to remove from the content.
46570      @param {Array} objects Optional array of objects to insert or null if no
46571        objects.
46572      @return {void}
46573      @private
46574    */
46575    replaceContent: function (idx, amt, objects) {
46576      _emberMetalProperty_get.get(this, 'content').replace(idx, amt, objects);
46577    },
46578
46579    /**
46580      Invoked when the content property is about to change. Notifies observers that the
46581      entire array content will change.
46582       @private
46583      @method _contentWillChange
46584    */
46585    _contentWillChange: _emberMetalMixin._beforeObserver('content', function () {
46586      this._teardownContent();
46587    }),
46588
46589    _teardownContent: function () {
46590      var content = _emberMetalProperty_get.get(this, 'content');
46591
46592      if (content) {
46593        _emberRuntimeMixinsArray.removeArrayObserver(content, this, {
46594          willChange: 'contentArrayWillChange',
46595          didChange: 'contentArrayDidChange'
46596        });
46597      }
46598    },
46599
46600    /**
46601      Override to implement content array `willChange` observer.
46602       @method contentArrayWillChange
46603       @param {Ember.Array} contentArray the content array
46604      @param {Number} start starting index of the change
46605      @param {Number} removeCount count of items removed
46606      @param {Number} addCount count of items added
46607      @private
46608    */
46609    contentArrayWillChange: K,
46610    /**
46611      Override to implement content array `didChange` observer.
46612       @method contentArrayDidChange
46613       @param {Ember.Array} contentArray the content array
46614      @param {Number} start starting index of the change
46615      @param {Number} removeCount count of items removed
46616      @param {Number} addCount count of items added
46617      @private
46618    */
46619    contentArrayDidChange: K,
46620
46621    /**
46622      Invoked when the content property changes. Notifies observers that the
46623      entire array content has changed.
46624       @private
46625      @method _contentDidChange
46626    */
46627    _contentDidChange: _emberMetalMixin.observer('content', function () {
46628      var content = _emberMetalProperty_get.get(this, 'content');
46629
46630      _emberMetalDebug.assert('Can\'t set ArrayProxy\'s content to itself', content !== this);
46631
46632      this._setupContent();
46633    }),
46634
46635    _setupContent: function () {
46636      var content = _emberMetalProperty_get.get(this, 'content');
46637
46638      if (content) {
46639        _emberMetalDebug.assert('ArrayProxy expects an Array or Ember.ArrayProxy, but you passed ' + typeof content, _emberRuntimeUtils.isArray(content) || content.isDestroyed);
46640
46641        _emberRuntimeMixinsArray.addArrayObserver(content, this, {
46642          willChange: 'contentArrayWillChange',
46643          didChange: 'contentArrayDidChange'
46644        });
46645      }
46646    },
46647
46648    _arrangedContentWillChange: _emberMetalMixin._beforeObserver('arrangedContent', function () {
46649      var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent');
46650      var len = arrangedContent ? _emberMetalProperty_get.get(arrangedContent, 'length') : 0;
46651
46652      this.arrangedContentArrayWillChange(this, 0, len, undefined);
46653      this.arrangedContentWillChange(this);
46654
46655      this._teardownArrangedContent(arrangedContent);
46656    }),
46657
46658    _arrangedContentDidChange: _emberMetalMixin.observer('arrangedContent', function () {
46659      var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent');
46660      var len = arrangedContent ? _emberMetalProperty_get.get(arrangedContent, 'length') : 0;
46661
46662      _emberMetalDebug.assert('Can\'t set ArrayProxy\'s content to itself', arrangedContent !== this);
46663
46664      this._setupArrangedContent();
46665
46666      this.arrangedContentDidChange(this);
46667      this.arrangedContentArrayDidChange(this, 0, undefined, len);
46668    }),
46669
46670    _setupArrangedContent: function () {
46671      var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent');
46672
46673      if (arrangedContent) {
46674        _emberMetalDebug.assert('ArrayProxy expects an Array or Ember.ArrayProxy, but you passed ' + typeof arrangedContent, _emberRuntimeUtils.isArray(arrangedContent) || arrangedContent.isDestroyed);
46675
46676        _emberRuntimeMixinsArray.addArrayObserver(arrangedContent, this, {
46677          willChange: 'arrangedContentArrayWillChange',
46678          didChange: 'arrangedContentArrayDidChange'
46679        });
46680      }
46681    },
46682
46683    _teardownArrangedContent: function () {
46684      var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent');
46685
46686      if (arrangedContent) {
46687        _emberRuntimeMixinsArray.removeArrayObserver(arrangedContent, this, {
46688          willChange: 'arrangedContentArrayWillChange',
46689          didChange: 'arrangedContentArrayDidChange'
46690        });
46691      }
46692    },
46693
46694    arrangedContentWillChange: K,
46695    arrangedContentDidChange: K,
46696
46697    objectAt: function (idx) {
46698      return _emberMetalProperty_get.get(this, 'content') && this.objectAtContent(idx);
46699    },
46700
46701    length: _emberMetalComputed.computed(function () {
46702      var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent');
46703      return arrangedContent ? _emberMetalProperty_get.get(arrangedContent, 'length') : 0;
46704      // No dependencies since Enumerable notifies length of change
46705    }),
46706
46707    _replace: function (idx, amt, objects) {
46708      var content = _emberMetalProperty_get.get(this, 'content');
46709      _emberMetalDebug.assert('The content property of ' + this.constructor + ' should be set before modifying it', content);
46710      if (content) {
46711        this.replaceContent(idx, amt, objects);
46712      }
46713
46714      return this;
46715    },
46716
46717    replace: function () {
46718      if (_emberMetalProperty_get.get(this, 'arrangedContent') === _emberMetalProperty_get.get(this, 'content')) {
46719        this._replace.apply(this, arguments);
46720      } else {
46721        throw new _emberMetalError.default('Using replace on an arranged ArrayProxy is not allowed.');
46722      }
46723    },
46724
46725    _insertAt: function (idx, object) {
46726      if (idx > _emberMetalProperty_get.get(this, 'content.length')) {
46727        throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION);
46728      }
46729
46730      this._replace(idx, 0, [object]);
46731      return this;
46732    },
46733
46734    insertAt: function (idx, object) {
46735      if (_emberMetalProperty_get.get(this, 'arrangedContent') === _emberMetalProperty_get.get(this, 'content')) {
46736        return this._insertAt(idx, object);
46737      } else {
46738        throw new _emberMetalError.default('Using insertAt on an arranged ArrayProxy is not allowed.');
46739      }
46740    },
46741
46742    removeAt: function (start, len) {
46743      if ('number' === typeof start) {
46744        var content = _emberMetalProperty_get.get(this, 'content');
46745        var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent');
46746        var indices = [];
46747        var i;
46748
46749        if (start < 0 || start >= _emberMetalProperty_get.get(this, 'length')) {
46750          throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION);
46751        }
46752
46753        if (len === undefined) {
46754          len = 1;
46755        }
46756
46757        // Get a list of indices in original content to remove
46758        for (i = start; i < start + len; i++) {
46759          // Use arrangedContent here so we avoid confusion with objects transformed by objectAtContent
46760          indices.push(content.indexOf(_emberRuntimeMixinsArray.objectAt(arrangedContent, i)));
46761        }
46762
46763        // Replace in reverse order since indices will change
46764        indices.sort(function (a, b) {
46765          return b - a;
46766        });
46767
46768        _emberMetalProperty_events.beginPropertyChanges();
46769        for (i = 0; i < indices.length; i++) {
46770          this._replace(indices[i], 1, EMPTY);
46771        }
46772        _emberMetalProperty_events.endPropertyChanges();
46773      }
46774
46775      return this;
46776    },
46777
46778    pushObject: function (obj) {
46779      this._insertAt(_emberMetalProperty_get.get(this, 'content.length'), obj);
46780      return obj;
46781    },
46782
46783    pushObjects: function (objects) {
46784      if (!(_emberRuntimeMixinsEnumerable.default.detect(objects) || _emberRuntimeUtils.isArray(objects))) {
46785        throw new TypeError('Must pass Ember.Enumerable to Ember.MutableArray#pushObjects');
46786      }
46787      this._replace(_emberMetalProperty_get.get(this, 'length'), 0, objects);
46788      return this;
46789    },
46790
46791    setObjects: function (objects) {
46792      if (objects.length === 0) {
46793        return this.clear();
46794      }
46795
46796      var len = _emberMetalProperty_get.get(this, 'length');
46797      this._replace(0, len, objects);
46798      return this;
46799    },
46800
46801    unshiftObject: function (obj) {
46802      this._insertAt(0, obj);
46803      return obj;
46804    },
46805
46806    unshiftObjects: function (objects) {
46807      this._replace(0, 0, objects);
46808      return this;
46809    },
46810
46811    slice: function () {
46812      var arr = this.toArray();
46813      return arr.slice.apply(arr, arguments);
46814    },
46815
46816    arrangedContentArrayWillChange: function (item, idx, removedCnt, addedCnt) {
46817      this.arrayContentWillChange(idx, removedCnt, addedCnt);
46818    },
46819
46820    arrangedContentArrayDidChange: function (item, idx, removedCnt, addedCnt) {
46821      this.arrayContentDidChange(idx, removedCnt, addedCnt);
46822    },
46823
46824    init: function () {
46825      this._super.apply(this, arguments);
46826      this._setupContent();
46827      this._setupArrangedContent();
46828    },
46829
46830    willDestroy: function () {
46831      this._teardownArrangedContent();
46832      this._teardownContent();
46833    }
46834  });
46835
46836  exports.default = ArrayProxy;
46837});
46838enifed('ember-runtime/system/container', ['exports', 'ember-metal/property_set', 'container/registry', 'container/container', 'container/owner'], function (exports, _emberMetalProperty_set, _containerRegistry, _containerContainer, _containerOwner) {
46839  'use strict';
46840
46841  _containerRegistry.default.set = _emberMetalProperty_set.set;
46842  _containerContainer.default.set = _emberMetalProperty_set.set;
46843
46844  exports.Registry = _containerRegistry.default;
46845  exports.Container = _containerContainer.default;
46846  exports.getOwner = _containerOwner.getOwner;
46847  exports.setOwner = _containerOwner.setOwner;
46848});
46849enifed('ember-runtime/system/core_object', ['exports', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/assign', 'ember-metal/property_get', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/chains', 'ember-metal/events', 'ember-metal/mixin', 'ember-metal/error', 'ember-runtime/mixins/action_handler', 'ember-metal/properties', 'ember-metal/binding', 'ember-metal/computed', 'ember-metal/injected_property', 'ember-metal/run_loop', 'ember-metal/watching', 'ember-metal/core', 'ember-runtime/inject', 'ember-metal/symbol'], function (exports, _emberMetalDebug, _emberMetalFeatures, _emberMetalAssign, _emberMetalProperty_get, _emberMetalUtils, _emberMetalMeta, _emberMetalChains, _emberMetalEvents, _emberMetalMixin, _emberMetalError, _emberRuntimeMixinsAction_handler, _emberMetalProperties, _emberMetalBinding, _emberMetalComputed, _emberMetalInjected_property, _emberMetalRun_loop, _emberMetalWatching, _emberMetalCore, _emberRuntimeInject, _emberMetalSymbol) {
46850  'no use strict';
46851  // Remove "use strict"; from transpiled module until
46852  // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
46853
46854  /**
46855    @module ember
46856    @submodule ember-runtime
46857  */
46858
46859  // using ember-metal/lib/main here to ensure that ember-debug is setup
46860  // if present
46861
46862  var _Mixin$create;
46863
46864  var POST_INIT = _emberMetalSymbol.default('POST_INIT');
46865  exports.POST_INIT = POST_INIT;
46866  var schedule = _emberMetalRun_loop.default.schedule;
46867  var applyMixin = _emberMetalMixin.Mixin._apply;
46868  var finishPartial = _emberMetalMixin.Mixin.finishPartial;
46869  var reopen = _emberMetalMixin.Mixin.prototype.reopen;
46870  var hasCachedComputedProperties = false;
46871
46872  function makeCtor() {
46873    // Note: avoid accessing any properties on the object since it makes the
46874    // method a lot faster. This is glue code so we want it to be as fast as
46875    // possible.
46876
46877    var wasApplied = false;
46878    var initProperties;
46879
46880    var Class = function () {
46881      if (!wasApplied) {
46882        Class.proto(); // prepare prototype...
46883      }
46884
46885      if (arguments.length > 0) {
46886        initProperties = [arguments[0]];
46887      }
46888
46889      this.__defineNonEnumerable(_emberMetalUtils.GUID_KEY_PROPERTY);
46890      var m = _emberMetalMeta.meta(this);
46891      var proto = m.proto;
46892      m.proto = this;
46893      if (initProperties) {
46894        // capture locally so we can clear the closed over variable
46895        var props = initProperties;
46896        initProperties = null;
46897
46898        var concatenatedProperties = this.concatenatedProperties;
46899        var mergedProperties = this.mergedProperties;
46900
46901        for (var i = 0, l = props.length; i < l; i++) {
46902          var properties = props[i];
46903
46904          _emberMetalDebug.assert('Ember.Object.create no longer supports mixing in other ' + 'definitions, use .extend & .create seperately instead.', !(properties instanceof _emberMetalMixin.Mixin));
46905
46906          if (typeof properties !== 'object' && properties !== undefined) {
46907            throw new _emberMetalError.default('Ember.Object.create only accepts objects.');
46908          }
46909
46910          if (!properties) {
46911            continue;
46912          }
46913
46914          var keyNames = Object.keys(properties);
46915
46916          for (var j = 0, ll = keyNames.length; j < ll; j++) {
46917            var keyName = keyNames[j];
46918            var value = properties[keyName];
46919
46920            if (_emberMetalMixin.IS_BINDING.test(keyName)) {
46921              m.writeBindings(keyName, value);
46922            }
46923
46924            var possibleDesc = this[keyName];
46925            var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
46926
46927            _emberMetalDebug.assert('Ember.Object.create no longer supports defining computed ' + 'properties. Define computed properties using extend() or reopen() ' + 'before calling create().', !(value instanceof _emberMetalComputed.ComputedProperty));
46928            _emberMetalDebug.assert('Ember.Object.create no longer supports defining methods that call _super.', !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
46929            _emberMetalDebug.assert('`actions` must be provided at extend time, not at create time, ' + 'when Ember.ActionHandler is used (i.e. views, controllers & routes).', !(keyName === 'actions' && _emberRuntimeMixinsAction_handler.default.detect(this)));
46930
46931            if (concatenatedProperties && concatenatedProperties.length > 0 && concatenatedProperties.indexOf(keyName) >= 0) {
46932              var baseValue = this[keyName];
46933
46934              if (baseValue) {
46935                if ('function' === typeof baseValue.concat) {
46936                  value = baseValue.concat(value);
46937                } else {
46938                  value = _emberMetalUtils.makeArray(baseValue).concat(value);
46939                }
46940              } else {
46941                value = _emberMetalUtils.makeArray(value);
46942              }
46943            }
46944
46945            if (mergedProperties && mergedProperties.length && mergedProperties.indexOf(keyName) >= 0) {
46946              var originalValue = this[keyName];
46947
46948              value = _emberMetalAssign.default({}, originalValue, value);
46949            }
46950
46951            if (desc) {
46952              desc.set(this, keyName, value);
46953            } else {
46954              if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
46955                this.setUnknownProperty(keyName, value);
46956              } else {
46957                _emberMetalProperties.defineProperty(this, keyName, null, value); // setup mandatory setter
46958              }
46959            }
46960          }
46961        }
46962      }
46963
46964      finishPartial(this, m);
46965
46966      var length = arguments.length;
46967
46968      if (length === 0) {
46969        this.init();
46970      } else if (length === 1) {
46971        this.init(arguments[0]);
46972      } else {
46973        // v8 bug potentially incorrectly deopts this function: https://code.google.com/p/v8/issues/detail?id=3709
46974        // we may want to keep this around till this ages out on mobile
46975        var args = new Array(length);
46976        for (var x = 0; x < length; x++) {
46977          args[x] = arguments[x];
46978        }
46979        this.init.apply(this, args);
46980      }
46981
46982      this[POST_INIT]();
46983
46984      m.proto = proto;
46985      _emberMetalChains.finishChains(this);
46986      _emberMetalEvents.sendEvent(this, 'init');
46987    };
46988
46989    Class.toString = _emberMetalMixin.Mixin.prototype.toString;
46990    Class.willReopen = function () {
46991      if (wasApplied) {
46992        Class.PrototypeMixin = _emberMetalMixin.Mixin.create(Class.PrototypeMixin);
46993      }
46994
46995      wasApplied = false;
46996    };
46997
46998    Class._initProperties = function (args) {
46999      initProperties = args;
47000    };
47001
47002    Class.proto = function () {
47003      var superclass = Class.superclass;
47004      if (superclass) {
47005        superclass.proto();
47006      }
47007
47008      if (!wasApplied) {
47009        wasApplied = true;
47010        Class.PrototypeMixin.applyPartial(Class.prototype);
47011      }
47012
47013      return this.prototype;
47014    };
47015
47016    return Class;
47017  }
47018
47019  /**
47020    @class CoreObject
47021    @namespace Ember
47022    @public
47023  */
47024  var CoreObject = makeCtor();
47025  CoreObject.toString = function () {
47026    return 'Ember.CoreObject';
47027  };
47028  CoreObject.PrototypeMixin = _emberMetalMixin.Mixin.create((_Mixin$create = {
47029    reopen: function () {
47030      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
47031        args[_key] = arguments[_key];
47032      }
47033
47034      applyMixin(this, args, true);
47035      return this;
47036    },
47037
47038    /**
47039      An overridable method called when objects are instantiated. By default,
47040      does nothing unless it is overridden during class definition.
47041       Example:
47042       ```javascript
47043      App.Person = Ember.Object.extend({
47044        init: function() {
47045          alert('Name is ' + this.get('name'));
47046        }
47047      });
47048       var steve = App.Person.create({
47049        name: "Steve"
47050      });
47051       // alerts 'Name is Steve'.
47052      ```
47053       NOTE: If you do override `init` for a framework class like `Ember.View`,
47054      be sure to call `this._super(...arguments)` in your
47055      `init` declaration! If you don't, Ember may not have an opportunity to
47056      do important setup work, and you'll see strange behavior in your
47057      application.
47058       @method init
47059      @public
47060    */
47061    init: function () {}
47062
47063  }, _Mixin$create[POST_INIT] = function () {}, _Mixin$create.__defineNonEnumerable = function (property) {
47064    Object.defineProperty(this, property.name, property.descriptor);
47065    //this[property.name] = property.descriptor.value;
47066  }, _Mixin$create.concatenatedProperties = null, _Mixin$create.mergedProperties = null, _Mixin$create.isDestroyed = false, _Mixin$create.isDestroying = false, _Mixin$create.destroy = function () {
47067    if (this.isDestroying) {
47068      return;
47069    }
47070    this.isDestroying = true;
47071
47072    schedule('actions', this, this.willDestroy);
47073    schedule('destroy', this, this._scheduledDestroy);
47074    return this;
47075  }, _Mixin$create.willDestroy = _emberMetalCore.K, _Mixin$create._scheduledDestroy = function () {
47076    if (this.isDestroyed) {
47077      return;
47078    }
47079    _emberMetalWatching.destroy(this);
47080    this.isDestroyed = true;
47081  }, _Mixin$create.bind = function (to, from) {
47082    if (!(from instanceof _emberMetalBinding.Binding)) {
47083      from = _emberMetalBinding.Binding.from(from);
47084    }
47085    from.to(to).connect(this);
47086    return from;
47087  }, _Mixin$create.toString = function () {
47088    var hasToStringExtension = typeof this.toStringExtension === 'function';
47089    var extension = hasToStringExtension ? ':' + this.toStringExtension() : '';
47090    var ret = '<' + this.constructor.toString() + ':' + _emberMetalUtils.guidFor(this) + extension + '>';
47091
47092    return ret;
47093  }, _Mixin$create));
47094
47095  CoreObject.PrototypeMixin.ownerConstructor = CoreObject;
47096
47097  CoreObject.__super__ = null;
47098
47099  var ClassMixinProps = {
47100
47101    ClassMixin: _emberMetalMixin.REQUIRED,
47102
47103    PrototypeMixin: _emberMetalMixin.REQUIRED,
47104
47105    isClass: true,
47106
47107    isMethod: false,
47108
47109    /**
47110      Creates a new subclass.
47111       ```javascript
47112      App.Person = Ember.Object.extend({
47113        say: function(thing) {
47114          alert(thing);
47115         }
47116      });
47117      ```
47118       This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.
47119       You can also create a subclass from any existing class by calling its `extend()` method.
47120      For example, you might want to create a subclass of Ember's built-in `Ember.View` class:
47121       ```javascript
47122      App.PersonView = Ember.View.extend({
47123        tagName: 'li',
47124        classNameBindings: ['isAdministrator']
47125      });
47126      ```
47127       When defining a subclass, you can override methods but still access the
47128      implementation of your parent class by calling the special `_super()` method:
47129       ```javascript
47130      App.Person = Ember.Object.extend({
47131        say: function(thing) {
47132          var name = this.get('name');
47133          alert(name + ' says: ' + thing);
47134        }
47135      });
47136       App.Soldier = App.Person.extend({
47137        say: function(thing) {
47138          this._super(thing + ", sir!");
47139        },
47140        march: function(numberOfHours) {
47141          alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.');
47142        }
47143      });
47144       var yehuda = App.Soldier.create({
47145        name: "Yehuda Katz"
47146      });
47147       yehuda.say("Yes");  // alerts "Yehuda Katz says: Yes, sir!"
47148      ```
47149       The `create()` on line #17 creates an *instance* of the `App.Soldier` class.
47150      The `extend()` on line #8 creates a *subclass* of `App.Person`. Any instance
47151      of the `App.Person` class will *not* have the `march()` method.
47152       You can also pass `Mixin` classes to add additional properties to the subclass.
47153       ```javascript
47154      App.Person = Ember.Object.extend({
47155        say: function(thing) {
47156          alert(this.get('name') + ' says: ' + thing);
47157        }
47158      });
47159       App.SingingMixin = Mixin.create({
47160        sing: function(thing){
47161          alert(this.get('name') + ' sings: la la la ' + thing);
47162        }
47163      });
47164       App.BroadwayStar = App.Person.extend(App.SingingMixin, {
47165        dance: function() {
47166          alert(this.get('name') + ' dances: tap tap tap tap ');
47167        }
47168      });
47169      ```
47170       The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
47171       @method extend
47172      @static
47173       @param {Mixin} [mixins]* One or more Mixin classes
47174      @param {Object} [arguments]* Object containing values to use within the new class
47175      @public
47176    */
47177    extend: function () {
47178      var Class = makeCtor();
47179      var proto;
47180      Class.ClassMixin = _emberMetalMixin.Mixin.create(this.ClassMixin);
47181      Class.PrototypeMixin = _emberMetalMixin.Mixin.create(this.PrototypeMixin);
47182
47183      Class.ClassMixin.ownerConstructor = Class;
47184      Class.PrototypeMixin.ownerConstructor = Class;
47185
47186      reopen.apply(Class.PrototypeMixin, arguments);
47187
47188      Class.superclass = this;
47189      Class.__super__ = this.prototype;
47190
47191      proto = Class.prototype = Object.create(this.prototype);
47192      proto.constructor = Class;
47193      _emberMetalUtils.generateGuid(proto);
47194      _emberMetalMeta.meta(proto).proto = proto; // this will disable observers on prototype
47195
47196      Class.ClassMixin.apply(Class);
47197      return Class;
47198    },
47199
47200    /**
47201      Creates an instance of a class. Accepts either no arguments, or an object
47202      containing values to initialize the newly instantiated object with.
47203       ```javascript
47204      App.Person = Ember.Object.extend({
47205        helloWorld: function() {
47206          alert("Hi, my name is " + this.get('name'));
47207        }
47208      });
47209       var tom = App.Person.create({
47210        name: 'Tom Dale'
47211      });
47212       tom.helloWorld(); // alerts "Hi, my name is Tom Dale".
47213      ```
47214       `create` will call the `init` function if defined during
47215      `Ember.AnyObject.extend`
47216       If no arguments are passed to `create`, it will not set values to the new
47217      instance during initialization:
47218       ```javascript
47219      var noName = App.Person.create();
47220      noName.helloWorld(); // alerts undefined
47221      ```
47222       NOTE: For performance reasons, you cannot declare methods or computed
47223      properties during `create`. You should instead declare methods and computed
47224      properties when using `extend`.
47225       @method create
47226      @static
47227      @param [arguments]*
47228      @public
47229    */
47230    create: function () {
47231      var C = this;
47232
47233      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
47234        args[_key2] = arguments[_key2];
47235      }
47236
47237      if (args.length > 0) {
47238        this._initProperties(args);
47239      }
47240      return new C();
47241    },
47242
47243    /**
47244      Augments a constructor's prototype with additional
47245      properties and functions:
47246       ```javascript
47247      MyObject = Ember.Object.extend({
47248        name: 'an object'
47249      });
47250       o = MyObject.create();
47251      o.get('name'); // 'an object'
47252       MyObject.reopen({
47253        say: function(msg){
47254          console.log(msg);
47255        }
47256      })
47257       o2 = MyObject.create();
47258      o2.say("hello"); // logs "hello"
47259       o.say("goodbye"); // logs "goodbye"
47260      ```
47261       To add functions and properties to the constructor itself,
47262      see `reopenClass`
47263       @method reopen
47264      @public
47265    */
47266    reopen: function () {
47267      this.willReopen();
47268      reopen.apply(this.PrototypeMixin, arguments);
47269      return this;
47270    },
47271
47272    /**
47273      Augments a constructor's own properties and functions:
47274       ```javascript
47275      MyObject = Ember.Object.extend({
47276        name: 'an object'
47277      });
47278       MyObject.reopenClass({
47279        canBuild: false
47280      });
47281       MyObject.canBuild; // false
47282      o = MyObject.create();
47283      ```
47284       In other words, this creates static properties and functions for the class.
47285      These are only available on the class and not on any instance of that class.
47286       ```javascript
47287      App.Person = Ember.Object.extend({
47288        name : "",
47289        sayHello : function() {
47290          alert("Hello. My name is " + this.get('name'));
47291        }
47292      });
47293       App.Person.reopenClass({
47294        species : "Homo sapiens",
47295        createPerson: function(newPersonsName){
47296          return App.Person.create({
47297            name:newPersonsName
47298          });
47299        }
47300      });
47301       var tom = App.Person.create({
47302        name : "Tom Dale"
47303      });
47304      var yehuda = App.Person.createPerson("Yehuda Katz");
47305       tom.sayHello(); // "Hello. My name is Tom Dale"
47306      yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
47307      alert(App.Person.species); // "Homo sapiens"
47308      ```
47309       Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
47310      variables. They are only valid on `App.Person`.
47311       To add functions and properties to instances of
47312      a constructor by extending the constructor's prototype
47313      see `reopen`
47314       @method reopenClass
47315      @public
47316    */
47317    reopenClass: function () {
47318      reopen.apply(this.ClassMixin, arguments);
47319      applyMixin(this, arguments, false);
47320      return this;
47321    },
47322
47323    detect: function (obj) {
47324      if ('function' !== typeof obj) {
47325        return false;
47326      }
47327      while (obj) {
47328        if (obj === this) {
47329          return true;
47330        }
47331        obj = obj.superclass;
47332      }
47333      return false;
47334    },
47335
47336    detectInstance: function (obj) {
47337      return obj instanceof this;
47338    },
47339
47340    /**
47341      In some cases, you may want to annotate computed properties with additional
47342      metadata about how they function or what values they operate on. For
47343      example, computed property functions may close over variables that are then
47344      no longer available for introspection.
47345       You can pass a hash of these values to a computed property like this:
47346       ```javascript
47347      person: function() {
47348        var personId = this.get('personId');
47349        return App.Person.create({ id: personId });
47350      }.property().meta({ type: App.Person })
47351      ```
47352       Once you've done this, you can retrieve the values saved to the computed
47353      property from your class like this:
47354       ```javascript
47355      MyClass.metaForProperty('person');
47356      ```
47357       This will return the original hash that was passed to `meta()`.
47358       @static
47359      @method metaForProperty
47360      @param key {String} property name
47361      @private
47362    */
47363    metaForProperty: function (key) {
47364      var proto = this.proto();
47365      var possibleDesc = proto[key];
47366      var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
47367
47368      _emberMetalDebug.assert('metaForProperty() could not find a computed property ' + 'with key \'' + key + '\'.', !!desc && desc instanceof _emberMetalComputed.ComputedProperty);
47369      return desc._meta || {};
47370    },
47371
47372    _computedProperties: _emberMetalComputed.computed(function () {
47373      hasCachedComputedProperties = true;
47374      var proto = this.proto();
47375      var property;
47376      var properties = [];
47377
47378      for (var name in proto) {
47379        property = proto[name];
47380
47381        if (property && property.isDescriptor) {
47382          properties.push({
47383            name: name,
47384            meta: property._meta
47385          });
47386        }
47387      }
47388      return properties;
47389    }).readOnly(),
47390
47391    /**
47392      Iterate over each computed property for the class, passing its name
47393      and any associated metadata (see `metaForProperty`) to the callback.
47394       @static
47395      @method eachComputedProperty
47396      @param {Function} callback
47397      @param {Object} binding
47398      @private
47399    */
47400    eachComputedProperty: function (callback, binding) {
47401      var property;
47402      var empty = {};
47403
47404      var properties = _emberMetalProperty_get.get(this, '_computedProperties');
47405
47406      for (var i = 0, length = properties.length; i < length; i++) {
47407        property = properties[i];
47408        callback.call(binding || this, property.name, property.meta || empty);
47409      }
47410    }
47411  };
47412
47413  function injectedPropertyAssertion() {
47414    _emberMetalDebug.assert('Injected properties are invalid', _emberRuntimeInject.validatePropertyInjections(this));
47415  }
47416
47417  _emberMetalDebug.runInDebug(function () {
47418    /**
47419      Provides lookup-time type validation for injected properties.
47420       @private
47421      @method _onLookup
47422    */
47423    ClassMixinProps._onLookup = injectedPropertyAssertion;
47424  });
47425
47426  /**
47427    Returns a hash of property names and container names that injected
47428    properties will lookup on the container lazily.
47429  
47430    @method _lazyInjections
47431    @return {Object} Hash of all lazy injected property keys to container names
47432    @private
47433  */
47434  ClassMixinProps._lazyInjections = function () {
47435    var injections = {};
47436    var proto = this.proto();
47437    var key, desc;
47438
47439    for (key in proto) {
47440      desc = proto[key];
47441      if (desc instanceof _emberMetalInjected_property.default) {
47442        injections[key] = desc.type + ':' + (desc.name || key);
47443      }
47444    }
47445
47446    return injections;
47447  };
47448
47449  var ClassMixin = _emberMetalMixin.Mixin.create(ClassMixinProps);
47450
47451  ClassMixin.ownerConstructor = CoreObject;
47452
47453  CoreObject.ClassMixin = ClassMixin;
47454
47455  ClassMixin.apply(CoreObject);
47456
47457  CoreObject.reopen({
47458    didDefineProperty: function (proto, key, value) {
47459      if (hasCachedComputedProperties === false) {
47460        return;
47461      }
47462      if (value instanceof _emberMetalComputed.ComputedProperty) {
47463        var cache = _emberMetalMeta.meta(this.constructor).readableCache();
47464
47465        if (cache && cache._computedProperties !== undefined) {
47466          cache._computedProperties = undefined;
47467        }
47468      }
47469    }
47470  });
47471
47472  exports.default = CoreObject;
47473});
47474
47475// NOTE: this object should never be included directly. Instead use `Ember.Object`.
47476// We only define this separately so that `Ember.Set` can depend on it.
47477
47478/**
47479  Defines the properties that will be concatenated from the superclass
47480  (instead of overridden).
47481   By default, when you extend an Ember class a property defined in
47482  the subclass overrides a property with the same name that is defined
47483  in the superclass. However, there are some cases where it is preferable
47484  to build up a property's value by combining the superclass' property
47485  value with the subclass' value. An example of this in use within Ember
47486  is the `classNames` property of `Ember.View`.
47487   Here is some sample code showing the difference between a concatenated
47488  property and a normal one:
47489   ```javascript
47490  App.BarView = Ember.View.extend({
47491    someNonConcatenatedProperty: ['bar'],
47492    classNames: ['bar']
47493  });
47494   App.FooBarView = App.BarView.extend({
47495    someNonConcatenatedProperty: ['foo'],
47496    classNames: ['foo']
47497  });
47498   var fooBarView = App.FooBarView.create();
47499  fooBarView.get('someNonConcatenatedProperty'); // ['foo']
47500  fooBarView.get('classNames'); // ['ember-view', 'bar', 'foo']
47501  ```
47502   This behavior extends to object creation as well. Continuing the
47503  above example:
47504   ```javascript
47505  var view = App.FooBarView.create({
47506    someNonConcatenatedProperty: ['baz'],
47507    classNames: ['baz']
47508  })
47509  view.get('someNonConcatenatedProperty'); // ['baz']
47510  view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
47511  ```
47512  Adding a single property that is not an array will just add it in the array:
47513   ```javascript
47514  var view = App.FooBarView.create({
47515    classNames: 'baz'
47516  })
47517  view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
47518  ```
47519   Using the `concatenatedProperties` property, we can tell Ember to mix the
47520  content of the properties.
47521   In `Ember.View` the `classNameBindings` and `attributeBindings` properties
47522  are also concatenated, in addition to `classNames`.
47523   This feature is available for you to use throughout the Ember object model,
47524  although typical app developers are likely to use it infrequently. Since
47525  it changes expectations about behavior of properties, you should properly
47526  document its usage in each individual concatenated property (to not
47527  mislead your users to think they can override the property in a subclass).
47528   @property concatenatedProperties
47529  @type Array
47530  @default null
47531  @public
47532*/
47533
47534/**
47535  Defines the properties that will be merged from the superclass
47536  (instead of overridden).
47537   By default, when you extend an Ember class a property defined in
47538  the subclass overrides a property with the same name that is defined
47539  in the superclass. However, there are some cases where it is preferable
47540  to build up a property's value by merging the superclass property value
47541  with the subclass property's value. An example of this in use within Ember
47542  is the `queryParams` property of routes.
47543   Here is some sample code showing the difference between a merged
47544  property and a normal one:
47545   ```javascript
47546  App.BarRoute = Ember.Route.extend({
47547    someNonMergedProperty: {
47548      nonMerged: 'superclass value of nonMerged'
47549    },
47550    queryParams: {
47551      page: {replace: false},
47552      limit: {replace: true}
47553    }
47554  });
47555   App.FooBarRoute = App.BarRoute.extend({
47556    someNonMergedProperty: {
47557      completelyNonMerged: 'subclass value of nonMerged'
47558    },
47559    queryParams: {
47560      limit: {replace: false}
47561    }
47562  });
47563   var fooBarRoute = App.FooBarRoute.create();
47564   fooBarRoute.get('someNonMergedProperty');
47565  // => { completelyNonMerged: 'subclass value of nonMerged' }
47566  //
47567  // Note the entire object, including the nonMerged property of
47568  // the superclass object, has been replaced
47569   fooBarRoute.get('queryParams');
47570  // => {
47571  //   page: {replace: false},
47572  //   limit: {replace: false}
47573  // }
47574  //
47575  // Note the page remains from the superclass, and the
47576  // `limit` property's value of `false` has been merged from
47577  // the subclass.
47578  ```
47579   This behavior is not available during object `create` calls. It is only
47580  available at `extend` time.
47581   This feature is available for you to use throughout the Ember object model,
47582  although typical app developers are likely to use it infrequently. Since
47583  it changes expectations about behavior of properties, you should properly
47584  document its usage in each individual merged property (to not
47585  mislead your users to think they can override the property in a subclass).
47586   @property mergedProperties
47587  @type Array
47588  @default null
47589  @public
47590*/
47591
47592/**
47593  Destroyed object property flag.
47594   if this property is `true` the observers and bindings were already
47595  removed by the effect of calling the `destroy()` method.
47596   @property isDestroyed
47597  @default false
47598  @public
47599*/
47600
47601/**
47602  Destruction scheduled flag. The `destroy()` method has been called.
47603   The object stays intact until the end of the run loop at which point
47604  the `isDestroyed` flag is set.
47605   @property isDestroying
47606  @default false
47607  @public
47608*/
47609
47610/**
47611  Destroys an object by setting the `isDestroyed` flag and removing its
47612  metadata, which effectively destroys observers and bindings.
47613   If you try to set a property on a destroyed object, an exception will be
47614  raised.
47615   Note that destruction is scheduled for the end of the run loop and does not
47616  happen immediately.  It will set an isDestroying flag immediately.
47617   @method destroy
47618  @return {Ember.Object} receiver
47619  @public
47620*/
47621
47622/**
47623  Override to implement teardown.
47624   @method willDestroy
47625  @public
47626*/
47627
47628/**
47629  Invoked by the run loop to actually destroy the object. This is
47630  scheduled for execution by the `destroy` method.
47631   @private
47632  @method _scheduledDestroy
47633*/
47634
47635/**
47636  Returns a string representation which attempts to provide more information
47637  than Javascript's `toString` typically does, in a generic way for all Ember
47638  objects.
47639   ```javascript
47640  App.Person = Em.Object.extend()
47641  person = App.Person.create()
47642  person.toString() //=> "<App.Person:ember1024>"
47643  ```
47644   If the object's class is not defined on an Ember namespace, it will
47645  indicate it is a subclass of the registered superclass:
47646  ```javascript
47647  Student = App.Person.extend()
47648  student = Student.create()
47649  student.toString() //=> "<(subclass of App.Person):ember1025>"
47650  ```
47651   If the method `toStringExtension` is defined, its return value will be
47652  included in the output.
47653   ```javascript
47654  App.Teacher = App.Person.extend({
47655    toStringExtension: function() {
47656      return this.get('fullName');
47657    }
47658  });
47659  teacher = App.Teacher.create()
47660  teacher.toString(); //=> "<App.Teacher:ember1026:Tom Dale>"
47661  ```
47662   @method toString
47663  @return {String} string representation
47664  @public
47665*/
47666enifed('ember-runtime/system/each_proxy', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/observer', 'ember-metal/property_events', 'ember-metal/empty_object', 'ember-runtime/mixins/array'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalObserver, _emberMetalProperty_events, _emberMetalEmpty_object, _emberRuntimeMixinsArray) {
47667  'use strict';
47668
47669  /**
47670    This is the object instance returned when you get the `@each` property on an
47671    array. It uses the unknownProperty handler to automatically create
47672    EachArray instances for property names.
47673    @class EachProxy
47674    @private
47675  */
47676  function EachProxy(content) {
47677    this._content = content;
47678    this._keys = undefined;
47679    this.__ember_meta__ = null;
47680  }
47681
47682  EachProxy.prototype = {
47683    __defineNonEnumerable: function (property) {
47684      this[property.name] = property.descriptor.value;
47685    },
47686
47687    // ..........................................................
47688    // ARRAY CHANGES
47689    // Invokes whenever the content array itself changes.
47690
47691    arrayWillChange: function (content, idx, removedCnt, addedCnt) {
47692      var keys = this._keys;
47693      var lim = removedCnt > 0 ? idx + removedCnt : -1;
47694      for (var key in keys) {
47695        if (lim > 0) {
47696          removeObserverForContentKey(content, key, this, idx, lim);
47697        }
47698        _emberMetalProperty_events.propertyWillChange(this, key);
47699      }
47700    },
47701
47702    arrayDidChange: function (content, idx, removedCnt, addedCnt) {
47703      var keys = this._keys;
47704      var lim = addedCnt > 0 ? idx + addedCnt : -1;
47705      for (var key in keys) {
47706        if (lim > 0) {
47707          addObserverForContentKey(content, key, this, idx, lim);
47708        }
47709        _emberMetalProperty_events.propertyDidChange(this, key);
47710      }
47711    },
47712
47713    // ..........................................................
47714    // LISTEN FOR NEW OBSERVERS AND OTHER EVENT LISTENERS
47715    // Start monitoring keys based on who is listening...
47716
47717    willWatchProperty: function (property) {
47718      this.beginObservingContentKey(property);
47719    },
47720
47721    didUnwatchProperty: function (property) {
47722      this.stopObservingContentKey(property);
47723    },
47724
47725    // ..........................................................
47726    // CONTENT KEY OBSERVING
47727    // Actual watch keys on the source content.
47728
47729    beginObservingContentKey: function (keyName) {
47730      var keys = this._keys;
47731      if (!keys) {
47732        keys = this._keys = new _emberMetalEmpty_object.default();
47733      }
47734
47735      if (!keys[keyName]) {
47736        keys[keyName] = 1;
47737        var content = this._content;
47738        var len = _emberMetalProperty_get.get(content, 'length');
47739
47740        addObserverForContentKey(content, keyName, this, 0, len);
47741      } else {
47742        keys[keyName]++;
47743      }
47744    },
47745
47746    stopObservingContentKey: function (keyName) {
47747      var keys = this._keys;
47748      if (keys && keys[keyName] > 0 && --keys[keyName] <= 0) {
47749        var content = this._content;
47750        var len = _emberMetalProperty_get.get(content, 'length');
47751
47752        removeObserverForContentKey(content, keyName, this, 0, len);
47753      }
47754    },
47755
47756    contentKeyWillChange: function (obj, keyName) {
47757      _emberMetalProperty_events.propertyWillChange(this, keyName);
47758    },
47759
47760    contentKeyDidChange: function (obj, keyName) {
47761      _emberMetalProperty_events.propertyDidChange(this, keyName);
47762    }
47763  };
47764
47765  function addObserverForContentKey(content, keyName, proxy, idx, loc) {
47766    while (--loc >= idx) {
47767      var item = _emberRuntimeMixinsArray.objectAt(content, loc);
47768      if (item) {
47769        _emberMetalDebug.assert('When using @each to observe the array ' + content + ', the array must return an object', typeof item === 'object');
47770        _emberMetalObserver._addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
47771        _emberMetalObserver.addObserver(item, keyName, proxy, 'contentKeyDidChange');
47772      }
47773    }
47774  }
47775
47776  function removeObserverForContentKey(content, keyName, proxy, idx, loc) {
47777    while (--loc >= idx) {
47778      var item = _emberRuntimeMixinsArray.objectAt(content, loc);
47779      if (item) {
47780        _emberMetalObserver._removeBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
47781        _emberMetalObserver.removeObserver(item, keyName, proxy, 'contentKeyDidChange');
47782      }
47783    }
47784  }
47785
47786  exports.default = EachProxy;
47787});
47788enifed('ember-runtime/system/lazy_load', ['exports', 'ember-metal/core', 'ember-runtime/system/native_array'], function (exports, _emberMetalCore, _emberRuntimeSystemNative_array) {
47789  /*globals CustomEvent */
47790
47791  'use strict';
47792
47793  exports.onLoad = onLoad;
47794  exports.runLoadHooks = runLoadHooks;
47795
47796  /**
47797    @module ember
47798    @submodule ember-runtime
47799  */
47800
47801  var loadHooks = _emberMetalCore.default.ENV.EMBER_LOAD_HOOKS || {};
47802  var loaded = {};
47803  var _loaded = loaded;
47804
47805  exports._loaded = _loaded;
47806  /**
47807    Detects when a specific package of Ember (e.g. 'Ember.Application')
47808    has fully loaded and is available for extension.
47809  
47810    The provided `callback` will be called with the `name` passed
47811    resolved from a string into the object:
47812  
47813    ``` javascript
47814    Ember.onLoad('Ember.Application' function(hbars) {
47815      hbars.registerHelper(...);
47816    });
47817    ```
47818  
47819    @method onLoad
47820    @for Ember
47821    @param name {String} name of hook
47822    @param callback {Function} callback to be called
47823    @private
47824  */
47825
47826  function onLoad(name, callback) {
47827    var object = loaded[name];
47828
47829    loadHooks[name] = loadHooks[name] || _emberRuntimeSystemNative_array.A();
47830    loadHooks[name].pushObject(callback);
47831
47832    if (object) {
47833      callback(object);
47834    }
47835  }
47836
47837  /**
47838    Called when an Ember.js package (e.g Ember.Application) has finished
47839    loading. Triggers any callbacks registered for this event.
47840  
47841    @method runLoadHooks
47842    @for Ember
47843    @param name {String} name of hook
47844    @param object {Object} object to pass to callbacks
47845    @private
47846  */
47847
47848  function runLoadHooks(name, object) {
47849    loaded[name] = object;
47850
47851    if (typeof window === 'object' && typeof window.dispatchEvent === 'function' && typeof CustomEvent === 'function') {
47852      var event = new CustomEvent(name, { detail: object, name: name });
47853      window.dispatchEvent(event);
47854    }
47855
47856    if (loadHooks[name]) {
47857      loadHooks[name].forEach(function (callback) {
47858        return callback(object);
47859      });
47860    }
47861  }
47862});
47863// Ember.ENV.EMBER_LOAD_HOOKS
47864enifed('ember-runtime/system/namespace', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/utils', 'ember-metal/mixin', 'ember-runtime/system/object'], function (exports, _emberMetalCore, _emberMetalProperty_get, _emberMetalUtils, _emberMetalMixin, _emberRuntimeSystemObject) {
47865  /**
47866  @module ember
47867  @submodule ember-runtime
47868  */
47869
47870  // Ember.lookup, Ember.BOOTED, Ember.NAME_KEY, Ember.anyUnprocessedMixins
47871  'use strict';
47872
47873  /**
47874    A Namespace is an object usually used to contain other objects or methods
47875    such as an application or framework. Create a namespace anytime you want
47876    to define one of these new containers.
47877  
47878    # Example Usage
47879  
47880    ```javascript
47881    MyFramework = Ember.Namespace.create({
47882      VERSION: '1.0.0'
47883    });
47884    ```
47885  
47886    @class Namespace
47887    @namespace Ember
47888    @extends Ember.Object
47889    @public
47890  */
47891  var Namespace = _emberRuntimeSystemObject.default.extend({
47892    isNamespace: true,
47893
47894    init: function () {
47895      Namespace.NAMESPACES.push(this);
47896      Namespace.PROCESSED = false;
47897    },
47898
47899    toString: function () {
47900      var name = _emberMetalProperty_get.get(this, 'name') || _emberMetalProperty_get.get(this, 'modulePrefix');
47901      if (name) {
47902        return name;
47903      }
47904
47905      findNamespaces();
47906      return this[NAME_KEY];
47907    },
47908
47909    nameClasses: function () {
47910      processNamespace([this.toString()], this, {});
47911    },
47912
47913    destroy: function () {
47914      var namespaces = Namespace.NAMESPACES;
47915      var toString = this.toString();
47916
47917      if (toString) {
47918        _emberMetalCore.default.lookup[toString] = undefined;
47919        delete Namespace.NAMESPACES_BY_ID[toString];
47920      }
47921      namespaces.splice(namespaces.indexOf(this), 1);
47922      this._super.apply(this, arguments);
47923    }
47924  });
47925
47926  Namespace.reopenClass({
47927    NAMESPACES: [_emberMetalCore.default],
47928    NAMESPACES_BY_ID: {},
47929    PROCESSED: false,
47930    processAll: processAllNamespaces,
47931    byName: function (name) {
47932      if (!_emberMetalCore.default.BOOTED) {
47933        processAllNamespaces();
47934      }
47935
47936      return NAMESPACES_BY_ID[name];
47937    }
47938  });
47939
47940  var NAMESPACES_BY_ID = Namespace.NAMESPACES_BY_ID;
47941
47942  var hasOwnProp = ({}).hasOwnProperty;
47943
47944  function processNamespace(paths, root, seen) {
47945    var idx = paths.length;
47946
47947    NAMESPACES_BY_ID[paths.join('.')] = root;
47948
47949    // Loop over all of the keys in the namespace, looking for classes
47950    for (var key in root) {
47951      if (!hasOwnProp.call(root, key)) {
47952        continue;
47953      }
47954      var obj = root[key];
47955
47956      // If we are processing the `Ember` namespace, for example, the
47957      // `paths` will start with `["Ember"]`. Every iteration through
47958      // the loop will update the **second** element of this list with
47959      // the key, so processing `Ember.View` will make the Array
47960      // `['Ember', 'View']`.
47961      paths[idx] = key;
47962
47963      // If we have found an unprocessed class
47964      if (obj && obj.toString === classToString && !obj[NAME_KEY]) {
47965        // Replace the class' `toString` with the dot-separated path
47966        // and set its `NAME_KEY`
47967        obj[NAME_KEY] = paths.join('.');
47968
47969        // Support nested namespaces
47970      } else if (obj && obj.isNamespace) {
47971          // Skip aliased namespaces
47972          if (seen[_emberMetalUtils.guidFor(obj)]) {
47973            continue;
47974          }
47975          seen[_emberMetalUtils.guidFor(obj)] = true;
47976
47977          // Process the child namespace
47978          processNamespace(paths, obj, seen);
47979        }
47980    }
47981
47982    paths.length = idx; // cut out last item
47983  }
47984
47985  var STARTS_WITH_UPPERCASE = /^[A-Z]/;
47986
47987  function tryIsNamespace(lookup, prop) {
47988    try {
47989      var obj = lookup[prop];
47990      return obj && obj.isNamespace && obj;
47991    } catch (e) {
47992      // continue
47993    }
47994  }
47995
47996  function findNamespaces() {
47997    var lookup = _emberMetalCore.default.lookup;
47998    var obj;
47999
48000    if (Namespace.PROCESSED) {
48001      return;
48002    }
48003
48004    for (var prop in lookup) {
48005      // Only process entities that start with uppercase A-Z
48006      if (!STARTS_WITH_UPPERCASE.test(prop)) {
48007        continue;
48008      }
48009
48010      // Unfortunately, some versions of IE don't support window.hasOwnProperty
48011      if (lookup.hasOwnProperty && !lookup.hasOwnProperty(prop)) {
48012        continue;
48013      }
48014
48015      // At times we are not allowed to access certain properties for security reasons.
48016      // There are also times where even if we can access them, we are not allowed to access their properties.
48017      obj = tryIsNamespace(lookup, prop);
48018      if (obj) {
48019        obj[NAME_KEY] = prop;
48020      }
48021    }
48022  }
48023
48024  var NAME_KEY = _emberMetalCore.default.NAME_KEY = _emberMetalUtils.GUID_KEY + '_name';
48025
48026  function superClassString(mixin) {
48027    var superclass = mixin.superclass;
48028    if (superclass) {
48029      if (superclass[NAME_KEY]) {
48030        return superclass[NAME_KEY];
48031      } else {
48032        return superClassString(superclass);
48033      }
48034    } else {
48035      return;
48036    }
48037  }
48038
48039  function classToString() {
48040    if (!_emberMetalCore.default.BOOTED && !this[NAME_KEY]) {
48041      processAllNamespaces();
48042    }
48043
48044    var ret;
48045
48046    if (this[NAME_KEY]) {
48047      ret = this[NAME_KEY];
48048    } else if (this._toString) {
48049      ret = this._toString;
48050    } else {
48051      var str = superClassString(this);
48052      if (str) {
48053        ret = '(subclass of ' + str + ')';
48054      } else {
48055        ret = '(unknown mixin)';
48056      }
48057      this.toString = makeToString(ret);
48058    }
48059
48060    return ret;
48061  }
48062
48063  function processAllNamespaces() {
48064    var unprocessedNamespaces = !Namespace.PROCESSED;
48065    var unprocessedMixins = _emberMetalCore.default.anyUnprocessedMixins;
48066
48067    if (unprocessedNamespaces) {
48068      findNamespaces();
48069      Namespace.PROCESSED = true;
48070    }
48071
48072    if (unprocessedNamespaces || unprocessedMixins) {
48073      var namespaces = Namespace.NAMESPACES;
48074      var namespace;
48075
48076      for (var i = 0, l = namespaces.length; i < l; i++) {
48077        namespace = namespaces[i];
48078        processNamespace([namespace.toString()], namespace, {});
48079      }
48080
48081      _emberMetalCore.default.anyUnprocessedMixins = false;
48082    }
48083  }
48084
48085  function makeToString(ret) {
48086    return function () {
48087      return ret;
48088    };
48089  }
48090
48091  _emberMetalMixin.Mixin.prototype.toString = classToString; // ES6TODO: altering imported objects. SBB.
48092
48093  exports.default = Namespace;
48094});
48095enifed('ember-runtime/system/native_array', ['exports', 'ember-metal/core', 'ember-metal/replace', 'ember-metal/property_get', 'ember-metal/mixin', 'ember-runtime/mixins/array', 'ember-runtime/mixins/mutable_array', 'ember-runtime/mixins/observable', 'ember-runtime/mixins/copyable', 'ember-runtime/mixins/freezable', 'ember-runtime/copy'], function (exports, _emberMetalCore, _emberMetalReplace, _emberMetalProperty_get, _emberMetalMixin, _emberRuntimeMixinsArray, _emberRuntimeMixinsMutable_array, _emberRuntimeMixinsObservable, _emberRuntimeMixinsCopyable, _emberRuntimeMixinsFreezable, _emberRuntimeCopy) {
48096  /**
48097  @module ember
48098  @submodule ember-runtime
48099  */
48100
48101  'use strict';
48102
48103  // Add Ember.Array to Array.prototype. Remove methods with native
48104  // implementations and supply some more optimized versions of generic methods
48105  // because they are so common.
48106
48107  /**
48108    The NativeArray mixin contains the properties needed to make the native
48109    Array support Ember.MutableArray and all of its dependent APIs. Unless you
48110    have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array` set to
48111    false, this will be applied automatically. Otherwise you can apply the mixin
48112    at anytime by calling `Ember.NativeArray.activate`.
48113  
48114    @class NativeArray
48115    @namespace Ember
48116    @uses Ember.MutableArray
48117    @uses Ember.Observable
48118    @uses Ember.Copyable
48119    @public
48120  */
48121  var NativeArray = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsMutable_array.default, _emberRuntimeMixinsObservable.default, _emberRuntimeMixinsCopyable.default, {
48122
48123    // because length is a built-in property we need to know to just get the
48124    // original property.
48125    get: function (key) {
48126      if (key === 'length') {
48127        return this.length;
48128      } else if ('number' === typeof key) {
48129        return this[key];
48130      } else {
48131        return this._super(key);
48132      }
48133    },
48134
48135    objectAt: function (idx) {
48136      return this[idx];
48137    },
48138
48139    // primitive for array support.
48140    replace: function (idx, amt, objects) {
48141      if (this.isFrozen) {
48142        throw _emberRuntimeMixinsFreezable.FROZEN_ERROR;
48143      }
48144
48145      // if we replaced exactly the same number of items, then pass only the
48146      // replaced range. Otherwise, pass the full remaining array length
48147      // since everything has shifted
48148      var len = objects ? _emberMetalProperty_get.get(objects, 'length') : 0;
48149      this.arrayContentWillChange(idx, amt, len);
48150
48151      if (len === 0) {
48152        this.splice(idx, amt);
48153      } else {
48154        _emberMetalReplace._replace(this, idx, amt, objects);
48155      }
48156
48157      this.arrayContentDidChange(idx, amt, len);
48158      return this;
48159    },
48160
48161    // If you ask for an unknown property, then try to collect the value
48162    // from member items.
48163    unknownProperty: function (key, value) {
48164      var ret; // = this.reducedProperty(key, value);
48165      if (value !== undefined && ret === undefined) {
48166        ret = this[key] = value;
48167      }
48168      return ret;
48169    },
48170
48171    indexOf: Array.prototype.indexOf,
48172    lastIndexOf: Array.prototype.lastIndexOf,
48173
48174    copy: function (deep) {
48175      if (deep) {
48176        return this.map(function (item) {
48177          return _emberRuntimeCopy.default(item, true);
48178        });
48179      }
48180
48181      return this.slice();
48182    }
48183  });
48184
48185  // Remove any methods implemented natively so we don't override them
48186  var ignore = ['length'];
48187  NativeArray.keys().forEach(function (methodName) {
48188    if (Array.prototype[methodName]) {
48189      ignore.push(methodName);
48190    }
48191  });
48192
48193  exports.NativeArray // TODO: only use default export
48194   = NativeArray = NativeArray.without.apply(NativeArray, ignore);
48195
48196  /**
48197    Creates an `Ember.NativeArray` from an Array like object.
48198    Does not modify the original object. Ember.A is not needed if
48199    `Ember.EXTEND_PROTOTYPES` is `true` (the default value). However,
48200    it is recommended that you use Ember.A when creating addons for
48201    ember or when you can not guarantee that `Ember.EXTEND_PROTOTYPES`
48202    will be `true`.
48203  
48204    Example
48205  
48206    ```js
48207    var Pagination = Ember.CollectionView.extend({
48208      tagName: 'ul',
48209      classNames: ['pagination'],
48210  
48211      init: function() {
48212        this._super(...arguments);
48213        if (!this.get('content')) {
48214          this.set('content', Ember.A());
48215        }
48216      }
48217    });
48218    ```
48219  
48220    @method A
48221    @for Ember
48222    @return {Ember.NativeArray}
48223    @public
48224  */
48225  var A;
48226
48227  if (_emberMetalCore.default.EXTEND_PROTOTYPES === true || _emberMetalCore.default.EXTEND_PROTOTYPES.Array) {
48228    NativeArray.apply(Array.prototype);
48229    exports. // ES6TODO: Setting A onto the object returned by ember-metal/core to avoid circles
48230    A = A = function (arr) {
48231      return arr || [];
48232    };
48233  } else {
48234    exports.A = A = function (arr) {
48235      if (!arr) {
48236        arr = [];
48237      }
48238      return _emberRuntimeMixinsArray.default.detect(arr) ? arr : NativeArray.apply(arr);
48239    };
48240  }
48241
48242  _emberMetalCore.default.A = A;exports.A = A;
48243  exports.NativeArray = NativeArray;
48244  exports.default = NativeArray;
48245});
48246// Ember.EXTEND_PROTOTYPES
48247enifed('ember-runtime/system/object', ['exports', 'ember-runtime/system/core_object', 'ember-runtime/mixins/observable'], function (exports, _emberRuntimeSystemCore_object, _emberRuntimeMixinsObservable) {
48248  /**
48249  @module ember
48250  @submodule ember-runtime
48251  */
48252
48253  'use strict';
48254
48255  /**
48256    `Ember.Object` is the main base class for all Ember objects. It is a subclass
48257    of `Ember.CoreObject` with the `Ember.Observable` mixin applied. For details,
48258    see the documentation for each of these.
48259  
48260    @class Object
48261    @namespace Ember
48262    @extends Ember.CoreObject
48263    @uses Ember.Observable
48264    @public
48265  */
48266  var EmberObject = _emberRuntimeSystemCore_object.default.extend(_emberRuntimeMixinsObservable.default);
48267  EmberObject.toString = function () {
48268    return 'Ember.Object';
48269  };
48270
48271  exports.default = EmberObject;
48272});
48273enifed('ember-runtime/system/object_proxy', ['exports', 'ember-runtime/system/object', 'ember-runtime/mixins/-proxy'], function (exports, _emberRuntimeSystemObject, _emberRuntimeMixinsProxy) {
48274  'use strict';
48275
48276  /**
48277    `Ember.ObjectProxy` forwards all properties not defined by the proxy itself
48278    to a proxied `content` object.
48279  
48280    ```javascript
48281    object = Ember.Object.create({
48282      name: 'Foo'
48283    });
48284  
48285    proxy = Ember.ObjectProxy.create({
48286      content: object
48287    });
48288  
48289    // Access and change existing properties
48290    proxy.get('name')          // 'Foo'
48291    proxy.set('name', 'Bar');
48292    object.get('name')         // 'Bar'
48293  
48294    // Create new 'description' property on `object`
48295    proxy.set('description', 'Foo is a whizboo baz');
48296    object.get('description')  // 'Foo is a whizboo baz'
48297    ```
48298  
48299    While `content` is unset, setting a property to be delegated 
48299will throw an
48300    Error.
48301  
48302    ```javascript
48303    proxy = Ember.ObjectProxy.create({
48304      content: null,
48305      flag: null
48306    });
48307    proxy.set('flag', true);
48308    proxy.get('flag');         // true
48309    proxy.get('foo');          // undefined
48310    proxy.set('foo', 'data');  // throws Error
48311    ```
48312  
48313    Delegated properties can be bound to and will change when content is updated.
48314  
48315    Computed properties on the proxy itself can depend on delegated properties.
48316  
48317    ```javascript
48318    ProxyWithComputedProperty = Ember.ObjectProxy.extend({
48319      fullName: function() {
48320        var firstName = this.get('firstName'),
48321            lastName = this.get('lastName');
48322        if (firstName && lastName) {
48323          return firstName + ' ' + lastName;
48324        }
48325        return firstName || lastName;
48326      }.property('firstName', 'lastName')
48327    });
48328  
48329    proxy = ProxyWithComputedProperty.create();
48330  
48331    proxy.get('fullName');  // undefined
48332    proxy.set('content', {
48333      firstName: 'Tom', lastName: 'Dale'
48334    }); // triggers property change for fullName on proxy
48335  
48336    proxy.get('fullName');  // 'Tom Dale'
48337    ```
48338  
48339    @class ObjectProxy
48340    @namespace Ember
48341    @extends Ember.Object
48342    @extends Ember._ProxyMixin
48343    @public
48344  */
48345
48346  exports.default = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsProxy.default);
48347});
48348enifed('ember-runtime/system/service', ['exports', 'ember-runtime/system/object', 'ember-runtime/inject'], function (exports, _emberRuntimeSystemObject, _emberRuntimeInject) {
48349  'use strict';
48350
48351  /**
48352    Creates a property that lazily looks up a service in the container. There
48353    are no restrictions as to what objects a service can be injected into.
48354  
48355    Example:
48356  
48357    ```javascript
48358    App.ApplicationRoute = Ember.Route.extend({
48359      authManager: Ember.inject.service('auth'),
48360  
48361      model: function() {
48362        return this.get('authManager').findCurrentUser();
48363      }
48364    });
48365    ```
48366  
48367    This example will create an `authManager` property on the application route
48368    that looks up the `auth` service in the container, making it easily
48369    accessible in the `model` hook.
48370  
48371    @method service
48372    @since 1.10.0
48373    @for Ember.inject
48374    @param {String} name (optional) name of the service to inject, defaults to
48375           the property's name
48376    @return {Ember.InjectedProperty} injection descriptor instance
48377    @public
48378  */
48379  _emberRuntimeInject.createInjectionHelper('service');
48380
48381  /**
48382    @class Service
48383    @namespace Ember
48384    @extends Ember.Object
48385    @since 1.10.0
48386    @public
48387  */
48388  var Service = _emberRuntimeSystemObject.default.extend();
48389
48390  Service.reopenClass({
48391    isServiceFactory: true
48392  });
48393
48394  exports.default = Service;
48395});
48396enifed('ember-runtime/system/string', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-runtime/utils', 'ember-runtime/string_registry', 'ember-metal/cache'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberRuntimeUtils, _emberRuntimeString_registry, _emberMetalCache) {
48397  /**
48398  @module ember
48399  @submodule ember-runtime
48400  */
48401  'use strict';
48402
48403  var STRING_DASHERIZE_REGEXP = /[ _]/g;
48404
48405  var STRING_DASHERIZE_CACHE = new _emberMetalCache.default(1000, function (key) {
48406    return decamelize(key).replace(STRING_DASHERIZE_REGEXP, '-');
48407  });
48408
48409  var STRING_CAMELIZE_REGEXP_1 = /(\-|\_|\.|\s)+(.)?/g;
48410  var STRING_CAMELIZE_REGEXP_2 = /(^|\/)([A-Z])/g;
48411
48412  var CAMELIZE_CACHE = new _emberMetalCache.default(1000, function (key) {
48413    return key.replace(STRING_CAMELIZE_REGEXP_1, function (match, separator, chr) {
48414      return chr ? chr.toUpperCase() : '';
48415    }).replace(STRING_CAMELIZE_REGEXP_2, function (match, separator, chr) {
48416      return match.toLowerCase();
48417    });
48418  });
48419
48420  var STRING_CLASSIFY_REGEXP_1 = /^(\-|_)+(.)?/;
48421  var STRING_CLASSIFY_REGEXP_2 = /(.)(\-|\_|\.|\s)+(.)?/g;
48422  var STRING_CLASSIFY_REGEXP_3 = /(^|\/|\.)([a-z])/g;
48423
48424  var CLASSIFY_CACHE = new _emberMetalCache.default(1000, function (str) {
48425    var replace1 = function (match, separator, chr) {
48426      return chr ? '_' + chr.toUpperCase() : '';
48427    };
48428    var replace2 = function (match, initialChar, separator, chr) {
48429      return initialChar + (chr ? chr.toUpperCase() : '');
48430    };
48431    var parts = str.split('/');
48432    for (var i = 0, len = parts.length; i < len; i++) {
48433      parts[i] = parts[i].replace(STRING_CLASSIFY_REGEXP_1, replace1).replace(STRING_CLASSIFY_REGEXP_2, replace2);
48434    }
48435    return parts.join('/').replace(STRING_CLASSIFY_REGEXP_3, function (match, separator, chr) {
48436      return match.toUpperCase();
48437    });
48438  });
48439
48440  var STRING_UNDERSCORE_REGEXP_1 = /([a-z\d])([A-Z]+)/g;
48441  var STRING_UNDERSCORE_REGEXP_2 = /\-|\s+/g;
48442
48443  var UNDERSCORE_CACHE = new _emberMetalCache.default(1000, function (str) {
48444    return str.replace(STRING_UNDERSCORE_REGEXP_1, '$1_$2').replace(STRING_UNDERSCORE_REGEXP_2, '_').toLowerCase();
48445  });
48446
48447  var STRING_CAPITALIZE_REGEXP = /(^|\/)([a-z])/g;
48448
48449  var CAPITALIZE_CACHE = new _emberMetalCache.default(1000, function (str) {
48450    return str.replace(STRING_CAPITALIZE_REGEXP, function (match, separator, chr) {
48451      return match.toUpperCase();
48452    });
48453  });
48454
48455  var STRING_DECAMELIZE_REGEXP = /([a-z\d])([A-Z])/g;
48456
48457  var DECAMELIZE_CACHE = new _emberMetalCache.default(1000, function (str) {
48458    return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase();
48459  });
48460
48461  function _fmt(str, formats) {
48462    var cachedFormats = formats;
48463
48464    if (!_emberRuntimeUtils.isArray(cachedFormats) || arguments.length > 2) {
48465      cachedFormats = new Array(arguments.length - 1);
48466
48467      for (var i = 1, l = arguments.length; i < l; i++) {
48468        cachedFormats[i - 1] = arguments[i];
48469      }
48470    }
48471
48472    // first, replace any ORDERED replacements.
48473    var idx = 0; // the current index for non-numerical replacements
48474    return str.replace(/%@([0-9]+)?/g, function (s, argIndex) {
48475      argIndex = argIndex ? parseInt(argIndex, 10) - 1 : idx++;
48476      s = cachedFormats[argIndex];
48477      return s === null ? '(null)' : s === undefined ? '' : _emberMetalUtils.inspect(s);
48478    });
48479  }
48480
48481  function fmt(str, formats) {
48482    _emberMetalDebug.deprecate('Ember.String.fmt is deprecated, use ES6 template strings instead.', false, { id: 'ember-string-utils.fmt', until: '3.0.0', url: 'http://babeljs.io/docs/learn-es2015/#template-strings' });
48483    return _fmt.apply(undefined, arguments);
48484  }
48485
48486  function loc(str, formats) {
48487    if (!_emberRuntimeUtils.isArray(formats) || arguments.length > 2) {
48488      formats = Array.prototype.slice.call(arguments, 1);
48489    }
48490
48491    str = _emberRuntimeString_registry.get(str) || str;
48492    return _fmt(str, formats);
48493  }
48494
48495  function w(str) {
48496    return str.split(/\s+/);
48497  }
48498
48499  function decamelize(str) {
48500    return DECAMELIZE_CACHE.get(str);
48501  }
48502
48503  function dasherize(str) {
48504    return STRING_DASHERIZE_CACHE.get(str);
48505  }
48506
48507  function camelize(str) {
48508    return CAMELIZE_CACHE.get(str);
48509  }
48510
48511  function classify(str) {
48512    return CLASSIFY_CACHE.get(str);
48513  }
48514
48515  function underscore(str) {
48516    return UNDERSCORE_CACHE.get(str);
48517  }
48518
48519  function capitalize(str) {
48520    return CAPITALIZE_CACHE.get(str);
48521  }
48522
48523  /**
48524    Defines string helper methods including string formatting and localization.
48525    Unless `Ember.EXTEND_PROTOTYPES.String` is `false` these methods will also be
48526    added to the `String.prototype` as well.
48527  
48528    @class String
48529    @namespace Ember
48530    @static
48531    @public
48532  */
48533  exports.default = {
48534    /**
48535      Apply formatting options to the string. This will look for occurrences
48536      of "%@" in your string and substitute them with the arguments you pass into
48537      this method. If you want to control the specific order of replacement,
48538      you can add a number after the key as well to indicate which argument
48539      you want to insert.
48540       Ordered insertions are most useful when building loc strings where values
48541      you need to insert may appear in different orders.
48542       ```javascript
48543      "Hello %@ %@".fmt('John', 'Doe');     // "Hello John Doe"
48544      "Hello %@2, %@1".fmt('John', 'Doe');  // "Hello Doe, John"
48545      ```
48546       @method fmt
48547      @param {String} str The string to format
48548      @param {Array} formats An array of parameters to interpolate into string.
48549      @return {String} formatted string
48550      @public
48551      @deprecated Use ES6 template strings instead: http://babeljs.io/docs/learn-es2015/#template-strings
48552    */
48553    fmt: fmt,
48554
48555    /**
48556      Formats the passed string, but first looks up the string in the localized
48557      strings hash. This is a convenient way to localize text. See
48558      `Ember.String.fmt()` for more information on formatting.
48559       Note that it is traditional but not required to prefix localized string
48560      keys with an underscore or other character so you can easily identify
48561      localized strings.
48562       ```javascript
48563      Ember.STRINGS = {
48564        '_Hello World': 'Bonjour le monde',
48565        '_Hello %@ %@': 'Bonjour %@ %@'
48566      };
48567       Ember.String.loc("_Hello World");  // 'Bonjour le monde';
48568      Ember.String.loc("_Hello %@ %@", ["John", "Smith"]);  // "Bonjour John Smith";
48569      ```
48570       @method loc
48571      @param {String} str The string to format
48572      @param {Array} formats Optional array of parameters to interpolate into string.
48573      @return {String} formatted string
48574      @public
48575    */
48576    loc: loc,
48577
48578    /**
48579      Splits a string into separate units separated by spaces, eliminating any
48580      empty strings in the process. This is a convenience method for split that
48581      is mostly useful when applied to the `String.prototype`.
48582       ```javascript
48583      Ember.String.w("alpha beta gamma").forEach(function(key) {
48584        console.log(key);
48585      });
48586       // > alpha
48587      // > beta
48588      // > gamma
48589      ```
48590       @method w
48591      @param {String} str The string to split
48592      @return {Array} array containing the split strings
48593      @public
48594    */
48595    w: w,
48596
48597    /**
48598      Converts a camelized string into all lower case separated by underscores.
48599       ```javascript
48600      'innerHTML'.decamelize();           // 'inner_html'
48601      'action_name'.decamelize();        // 'action_name'
48602      'css-class-name'.decamelize();     // 'css-class-name'
48603      'my favorite items'.decamelize();  // 'my favorite items'
48604      ```
48605       @method decamelize
48606      @param {String} str The string to decamelize.
48607      @return {String} the decamelized string.
48608      @public
48609    */
48610    decamelize: decamelize,
48611
48612    /**
48613      Replaces underscores, spaces, or camelCase with dashes.
48614       ```javascript
48615      'innerHTML'.dasherize();          // 'inner-html'
48616      'action_name'.dasherize();        // 'action-name'
48617      'css-class-name'.dasherize();     // 'css-class-name'
48618      'my favorite items'.dasherize();  // 'my-favorite-items'
48619      'privateDocs/ownerInvoice'.dasherize(); // 'private-docs/owner-invoice'
48620      ```
48621       @method dasherize
48622      @param {String} str The string to dasherize.
48623      @return {String} the dasherized string.
48624      @public
48625    */
48626    dasherize: dasherize,
48627
48628    /**
48629      Returns the lowerCamelCase form of a string.
48630       ```javascript
48631      'innerHTML'.camelize();          // 'innerHTML'
48632      'action_name'.camelize();        // 'actionName'
48633      'css-class-name'.camelize();     // 'cssClassName'
48634      'my favorite items'.camelize();  // 'myFavoriteItems'
48635      'My Favorite Items'.camelize();  // 'myFavoriteItems'
48636      'private-docs/owner-invoice'.camelize(); // 'privateDocs/ownerInvoice'
48637      ```
48638       @method camelize
48639      @param {String} str The string to camelize.
48640      @return {String} the camelized string.
48641      @public
48642    */
48643    camelize: camelize,
48644
48645    /**
48646      Returns the UpperCamelCase form of a string.
48647       ```javascript
48648      'innerHTML'.classify();          // 'InnerHTML'
48649      'action_name'.classify();        // 'ActionName'
48650      'css-class-name'.classify();     // 'CssClassName'
48651      'my favorite items'.classify();  // 'MyFavoriteItems'
48652      'private-docs/owner-invoice'.classify(); // 'PrivateDocs/OwnerInvoice'
48653      ```
48654       @method classify
48655      @param {String} str the string to classify
48656      @return {String} the classified string
48657      @public
48658    */
48659    classify: classify,
48660
48661    /**
48662      More general than decamelize. Returns the lower\_case\_and\_underscored
48663      form of a string.
48664       ```javascript
48665      'innerHTML'.underscore();          // 'inner_html'
48666      'action_name'.underscore();        // 'action_name'
48667      'css-class-name'.underscore();     // 'css_class_name'
48668      'my favorite items'.underscore();  // 'my_favorite_items'
48669      'privateDocs/ownerInvoice'.underscore(); // 'private_docs/owner_invoice'
48670      ```
48671       @method underscore
48672      @param {String} str The string to underscore.
48673      @return {String} the underscored string.
48674      @public
48675    */
48676    underscore: underscore,
48677
48678    /**
48679      Returns the Capitalized form of a string
48680       ```javascript
48681      'innerHTML'.capitalize()         // 'InnerHTML'
48682      'action_name'.capitalize()       // 'Action_name'
48683      'css-class-name'.capitalize()    // 'Css-class-name'
48684      'my favorite items'.capitalize() // 'My favorite items'
48685      'privateDocs/ownerInvoice'.capitalize(); // 'PrivateDocs/ownerInvoice'
48686      ```
48687       @method capitalize
48688      @param {String} str The string to capitalize.
48689      @return {String} The capitalized string.
48690      @public
48691    */
48692    capitalize: capitalize
48693  };
48694  exports.fmt = fmt;
48695  exports.loc = loc;
48696  exports.w = w;
48697  exports.decamelize = decamelize;
48698  exports.dasherize = dasherize;
48699  exports.camelize = camelize;
48700  exports.classify = classify;
48701  exports.underscore = underscore;
48702  exports.capitalize = capitalize;
48703});
48704enifed('ember-runtime/utils', ['exports', 'ember-runtime/mixins/array', 'ember-runtime/system/object'], function (exports, _emberRuntimeMixinsArray, _emberRuntimeSystemObject) {
48705  'use strict';
48706
48707  exports.isArray = isArray;
48708  exports.typeOf = typeOf;
48709
48710  // ........................................
48711  // TYPING & ARRAY MESSAGING
48712  //
48713  var TYPE_MAP = {
48714    '[object Boolean]': 'boolean',
48715    '[object Number]': 'number',
48716    '[object String]': 'string',
48717    '[object Function]': 'function',
48718    '[object Array]': 'array',
48719    '[object Date]': 'date',
48720    '[object RegExp]': 'regexp',
48721    '[object Object]': 'object'
48722  };
48723
48724  var toString = Object.prototype.toString;
48725
48726  /**
48727    Returns true if the passed object is an array or Array-like.
48728  
48729    Objects are considered Array-like if any of the following are true:
48730  
48731      - the object is a native Array
48732      - the object has an objectAt property
48733      - the object is an Object, and has a length property
48734  
48735    Unlike `Ember.typeOf` this method returns true even if the passed object is
48736    not formally an array but appears to be array-like (i.e. implements `Ember.Array`)
48737  
48738    ```javascript
48739    Ember.isArray();                                          // false
48740    Ember.isArray([]);                                        // true
48741    Ember.isArray(Ember.ArrayProxy.create({ content: [] }));  // true
48742    ```
48743  
48744    @method isArray
48745    @for Ember
48746    @param {Object} obj The object to test
48747    @return {Boolean} true if the passed object is an array or Array-like
48748    @public
48749  */
48750
48751  function isArray(obj) {
48752    if (!obj || obj.setInterval) {
48753      return false;
48754    }
48755    if (Array.isArray(obj)) {
48756      return true;
48757    }
48758    if (_emberRuntimeMixinsArray.default.detect(obj)) {
48759      return true;
48760    }
48761
48762    var type = typeOf(obj);
48763    if ('array' === type) {
48764      return true;
48765    }
48766    if (obj.length !== undefined && 'object' === type) {
48767      return true;
48768    }
48769    return false;
48770  }
48771
48772  /**
48773    Returns a consistent type for the passed object.
48774  
48775    Use this instead of the built-in `typeof` to get the type of an item.
48776    It will return the same result across all browsers and includes a bit
48777    more detail. Here is what will be returned:
48778  
48779        | Return Value  | Meaning                                              |
48780        |---------------|------------------------------------------------------|
48781        | 'string'      | String primitive or String object.                   |
48782        | 'number'      | Number primitive or Number object.                   |
48783        | 'boolean'     | Boolean primitive or Boolean object.                 |
48784        | 'null'        | Null value                                           |
48785        | 'undefined'   | Undefined value                                      |
48786        | 'function'    | A function                                           |
48787        | 'array'       | An instance of Array                                 |
48788        | 'regexp'      | An instance of RegExp                                |
48789        | 'date'        | An instance of Date                                  |
48790        | 'class'       | An Ember class (created using Ember.Object.extend()) |
48791        | 'instance'    | An Ember object instance                             |
48792        | 'error'       | An instance of the Error object                      |
48793        | 'object'      | A JavaScript object not inheriting from Ember.Object |
48794  
48795    Examples:
48796  
48797    ```javascript
48798    Ember.typeOf();                       // 'undefined'
48799    Ember.typeOf(null);                   // 'null'
48800    Ember.typeOf(undefined);              // 'undefined'
48801    Ember.typeOf('michael');              // 'string'
48802    Ember.typeOf(new String('michael'));  // 'string'
48803    Ember.typeOf(101);                    // 'number'
48804    Ember.typeOf(new Number(101));        // 'number'
48805    Ember.typeOf(true);                   // 'boolean'
48806    Ember.typeOf(new Boolean(true));      // 'boolean'
48807    Ember.typeOf(Ember.makeArray);        // 'function'
48808    Ember.typeOf([1, 2, 90]);             // 'array'
48809    Ember.typeOf(/abc/);                  // 'regexp'
48810    Ember.typeOf(new Date());             // 'date'
48811    Ember.typeOf(Ember.Object.extend());  // 'class'
48812    Ember.typeOf(Ember.Object.create());  // 'instance'
48813    Ember.typeOf(new Error('teamocil'));  // 'error'
48814  
48815    // 'normal' JavaScript object
48816    Ember.typeOf({ a: 'b' });             // 'object'
48817    ```
48818  
48819    @method typeOf
48820    @for Ember
48821    @param {Object} item the item to check
48822    @return {String} the type
48823    @public
48824  */
48825
48826  function typeOf(item) {
48827    if (item === null) {
48828      return 'null';
48829    }
48830    if (item === undefined) {
48831      return 'undefined';
48832    }
48833    var ret = TYPE_MAP[toString.call(item)] || 'object';
48834
48835    if (ret === 'function') {
48836      if (_emberRuntimeSystemObject.default.detect(item)) {
48837        ret = 'class';
48838      }
48839    } else if (ret === 'object') {
48840      if (item instanceof Error) {
48841        ret = 'error';
48842      } else if (item instanceof _emberRuntimeSystemObject.default) {
48843        ret = 'instance';
48844      } else if (item instanceof Date) {
48845        ret = 'date';
48846      }
48847    }
48848
48849    return ret;
48850  }
48851});
48852enifed('ember-template-compiler/compat/precompile', ['exports', 'require', 'ember-template-compiler/system/compile_options'], function (exports, _require, _emberTemplateCompilerSystemCompile_options) {
48853  /**
48854  @module ember
48855  @submodule ember-template-compiler
48856  */
48857  'use strict';
48858
48859  var compile, compileSpec;
48860
48861  exports.default = function (string) {
48862    if ((!compile || !compileSpec) && _require.has('htmlbars-compiler/compiler')) {
48863      var Compiler = _require.default('htmlbars-compiler/compiler');
48864
48865      compile = Compiler.compile;
48866      compileSpec = Compiler.compileSpec;
48867    }
48868
48869    if (!compile || !compileSpec) {
48870      throw new Error('Cannot call `precompile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `precompile`.');
48871    }
48872
48873    var asObject = arguments[1] === undefined ? true : arguments[1];
48874    var compileFunc = asObject ? compile : compileSpec;
48875
48876    return compileFunc(string, _emberTemplateCompilerSystemCompile_options.default());
48877  };
48878});
48879enifed('ember-template-compiler/compat', ['exports', 'ember-metal/core', 'ember-template-compiler/compat/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/template'], function (exports, _emberMetalCore, _emberTemplateCompilerCompatPrecompile, _emberTemplateCompilerSystemCompile, _emberTemplateCompilerSystemTemplate) {
48880  'use strict';
48881
48882  var EmberHandlebars = _emberMetalCore.default.Handlebars = _emberMetalCore.default.Handlebars || {};
48883
48884  EmberHandlebars.precompile = _emberTemplateCompilerCompatPrecompile.default;
48885  EmberHandlebars.compile = _emberTemplateCompilerSystemCompile.default;
48886  EmberHandlebars.template = _emberTemplateCompilerSystemTemplate.default;
48887});
48888enifed('ember-template-compiler/index', ['exports', 'ember-metal', 'ember-template-compiler/system/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/template', 'ember-template-compiler/plugins', 'ember-template-compiler/plugins/transform-old-binding-syntax', 'ember-template-compiler/plugins/transform-old-class-binding-syntax', 'ember-template-compiler/plugins/transform-item-class', 'ember-template-compiler/plugins/transform-closure-component-attrs-into-mut', 'ember-template-compiler/plugins/transform-component-attrs-into-mut', 'ember-template-compiler/plugins/transform-component-curly-to-readonly', 'ember-template-compiler/plugins/transform-angle-bracket-components', 'ember-template-compiler/plugins/transform-input-on-to-onEvent', 'ember-template-compiler/plugins/transform-top-level-components', 'ember-template-compiler/plugins/transform-each-into-collection', 'ember-template-compiler/plugins/transform-unescaped-inline-link-to', 'ember-template-compiler/plugins/deprecate-render-block', 'ember-template-compiler/plugins/assert-no-view-and-controller-paths', 'ember-template-compiler/plugins/assert-no-view-helper', 'ember-template-compiler/plugins/assert-no-each-in', 'ember-template-compiler/compat'], function (exports, _emberMetal, _emberTemplateCompilerSystemPrecompile, _emberTemplateCompilerSystemCompile, _emberTemplateCompilerSystemTemplate, _emberTemplateCompilerPlugins, _emberTemplateCompilerPluginsTransformOldBindingSyntax, _emberTemplateCompilerPluginsTransformOldClassBindingSyntax, _emberTemplateCompilerPluginsTransformItemClass, _emberTemplateCompilerPluginsTransformClosureComponentAttrsIntoMut, _emberTemplateCompilerPluginsTransformComponentAttrsIntoMut, _emberTemplateCompilerPluginsTransformComponentCurlyToReadonly, _emberTemplateCompilerPluginsTransformAngleBracketComponents, _emberTemplateCompilerPluginsTransformInputOnToOnEvent, _emberTemplateCompilerPluginsTransformTopLevelComponents, _emberTemplateCompilerPluginsTransformEachIntoCollection, _emberTemplateCompilerPluginsTransformUnescapedInlineLinkTo, _emberTemplateCompilerPluginsDeprecateRenderBlock, _emberTemplateCompilerPluginsAssertNoViewAndControllerPaths, _emberTemplateCompilerPluginsAssertNoViewHelper, _emberTemplateCompilerPluginsAssertNoEachIn, _emberTemplateCompilerCompat) {
48889  'use strict';
48890
48891  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformOldBindingSyntax.default);
48892  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformOldClassBindingSyntax.default);
48893  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformItemClass.default);
48894  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformClosureComponentAttrsIntoMut.default);
48895  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformComponentAttrsIntoMut.default);
48896  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformComponentCurlyToReadonly.default);
48897  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformAngleBracketComponents.default);
48898  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformInputOnToOnEvent.default);
48899  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformTopLevelComponents.default);
48900  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformUnescapedInlineLinkTo.default);
48901  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsDeprecateRenderBlock.default);
48902  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsAssertNoEachIn.default);
48903
48904  if (_emberMetal.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
48905    _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformEachIntoCollection.default);
48906  } else {
48907    _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsAssertNoViewAndControllerPaths.default);
48908    _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsAssertNoViewHelper.default);
48909  }
48910
48911  exports._Ember = _emberMetal.default;
48912  exports.precompile = _emberTemplateCompilerSystemPrecompile.default;
48913  exports.compile = _emberTemplateCompilerSystemCompile.default;
48914  exports.template = _emberTemplateCompilerSystemTemplate.default;
48915  exports.registerPlugin = _emberTemplateCompilerPlugins.registerPlugin;
48916});
48917
48918// used for adding Ember.Handlebars.compile for backwards compat
48919enifed('ember-template-compiler/plugins/assert-no-each-in', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalCore, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
48920  'use strict';
48921
48922  function AssertNoEachIn() {
48923    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
48924
48925    this.syntax = null;
48926    this.options = options;
48927  }
48928
48929  AssertNoEachIn.prototype.transform = function AssertNoEachIn_transform(ast) {
48930    if (!!_emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
48931      return ast;
48932    }
48933    var walker = new this.syntax.Walker();
48934    var moduleName = this.options && this.options.moduleName;
48935
48936    walker.visit(ast, function (node) {
48937      if (!validate(node)) {
48938        return;
48939      }
48940      assertHelper(moduleName, node);
48941    });
48942
48943    return ast;
48944  };
48945
48946  function assertHelper(moduleName, node) {
48947    var moduleInfo = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc);
48948    var singular = node.params[0].original;
48949    var plural = node.params[2].original;
48950
48951    _emberMetalDebug.assert('Using {{#each ' + singular + ' in ' + plural + '}} ' + moduleInfo + 'is no longer supported in Ember 2.0+, please use {{#each ' + plural + ' as |' + singular + '|}}');
48952  }
48953
48954  function validate(node) {
48955    return (node.type === 'BlockStatement' || node.type === 'MustacheStatement') && node.path.original === 'each' && node.params.length === 3 && node.params[1].type === 'PathExpression' && node.params[1].original === 'in';
48956  }
48957
48958  exports.default = AssertNoEachIn;
48959});
48960enifed('ember-template-compiler/plugins/assert-no-view-and-controller-paths', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalCore, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
48961  'use strict';
48962
48963  function AssertNoViewAndControllerPaths() {
48964    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
48965
48966    // set later within HTMLBars to the syntax package
48967    this.syntax = null;
48968    this.options = options;
48969  }
48970
48971  /**
48972    @private
48973    @method transform
48974    @param {AST} ast The AST to be transformed.
48975  */
48976  AssertNoViewAndControllerPaths.prototype.transform = function AssertNoViewAndControllerPaths_transform(ast) {
48977    var walker = new this.syntax.Walker();
48978    var moduleName = this.options && this.options.moduleName;
48979
48980    walker.visit(ast, function (node) {
48981      if (!validate(node)) {
48982        return;
48983      }
48984
48985      assertPath(moduleName, node, node.path);
48986      assertPaths(moduleName, node, node.params);
48987      assertHash(moduleName, node, node.hash);
48988    });
48989
48990    return ast;
48991  };
48992
48993  function assertHash(moduleName, node, hash) {
48994    if (!hash || !hash.pairs) {
48995      return;
48996    }
48997    var i, l, pair, paths;
48998    for (i = 0, l = hash.pairs.length; i < l; i++) {
48999      pair = hash.pairs[i];
49000      paths = pair.value.params;
49001      assertPaths(moduleName, pair, paths);
49002    }
49003  }
49004
49005  function assertPaths(moduleName, node, paths) {
49006    if (!paths) {
49007      return;
49008    }
49009    var i, l, path;
49010    for (i = 0, l = paths.length; i < l; i++) {
49011      path = paths[i];
49012      assertPath(moduleName, node, path);
49013    }
49014  }
49015
49016  function assertPath(moduleName, node, path) {
49017    _emberMetalDebug.assert('Using `{{' + (path && path.type === 'PathExpression' && path.parts[0]) + '}}` or any path based on it ' + _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc) + 'has been removed in Ember 2.0', (function () {
49018      var noAssertion = true;
49019
49020      var viewKeyword = path && path.type === 'PathExpression' && path.parts && path.parts[0];
49021      if (viewKeyword === 'view') {
49022        noAssertion = _emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT;
49023      } else if (viewKeyword === 'controller') {
49024        noAssertion = _emberMetalCore.default.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT;
49025      }
49026
49027      return noAssertion;
49028    })(), {
49029      id: path.parts && path.parts[0] === 'view' ? 'view.keyword.view' : 'view.keyword.controller',
49030      until: '2.0.0'
49031    });
49032  }
49033
49034  function validate(node) {
49035    return node.type === 'MustacheStatement' || node.type === 'BlockStatement';
49036  }
49037
49038  exports.default = AssertNoViewAndControllerPaths;
49039});
49040enifed('ember-template-compiler/plugins/assert-no-view-helper', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalCore, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
49041  'use strict';
49042
49043  function AssertNoViewHelper() {
49044    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
49045
49046    // set later within HTMLBars to the syntax package
49047    this.syntax = null;
49048    this.options = options;
49049  }
49050
49051  /**
49052    @private
49053    @method transform
49054    @param {AST} ast The AST to be transformed.
49055  */
49056  AssertNoViewHelper.prototype.transform = function AssertNoViewHelper_transform(ast) {
49057    if (!!_emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
49058      return ast;
49059    }
49060    var walker = new this.syntax.Walker();
49061    var moduleName = this.options && this.options.moduleName;
49062
49063    walker.visit(ast, function (node) {
49064      if (!validate(node)) {
49065        return;
49066      }
49067
49068      assertHelper(moduleName, node);
49069    });
49070
49071    return ast;
49072  };
49073
49074  function assertHelper(moduleName, node) {
49075    var paramValue = node.params.length && node.params[0].value;
49076
49077    if (!paramValue) {
49078      return;
49079    } else {
49080      _emberMetalDebug.assert('Using the `{{view "string"}}` helper is removed in 2.0. ' + _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc), _emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT, { id: 'view.helper', until: '2.0.0' });
49081    }
49082  }
49083
49084  function validate(node) {
49085    return (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && node.path.parts[0] === 'view';
49086  }
49087
49088  exports.default = AssertNoViewHelper;
49089});
49090enifed('ember-template-compiler/plugins/deprecate-render-block', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
49091  'use strict';
49092
49093  exports.default = DeprecateRenderBlock;
49094
49095  function DeprecateRenderBlock(options) {
49096    this.syntax = null;
49097    this.options = options;
49098  }
49099
49100  DeprecateRenderBlock.prototype.transform = function DeprecateRenderBlock_transform(ast) {
49101    var moduleName = this.options.moduleName;
49102    var walker = new this.syntax.Walker();
49103
49104    walker.visit(ast, function (node) {
49105      if (!validate(node)) {
49106        return;
49107      }
49108
49109      _emberMetalDebug.deprecate(deprecationMessage(moduleName, node), false, {
49110        id: 'ember-template-compiler.deprecate-render-block',
49111        until: '2.4.0',
49112        url: 'http://emberjs.com/deprecations/v2.x#toc_render-helper-with-block'
49113      });
49114    });
49115
49116    return ast;
49117  };
49118
49119  function validate(node) {
49120    return node.type === 'BlockStatement' && node.path.original === 'render';
49121  }
49122
49123  function deprecationMessage(moduleName, node) {
49124    var sourceInformation = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc);
49125
49126    return 'Usage of `render` in block form is deprecated ' + sourceInformation + '.';
49127  }
49128});
49129enifed('ember-template-compiler/plugins/transform-angle-bracket-components', ['exports'], function (exports) {
49130  'use strict';
49131
49132  function TransformAngleBracketComponents() {
49133    // set later within HTMLBars to the syntax package
49134    this.syntax = null;
49135  }
49136
49137  /**
49138    @private
49139    @method transform
49140    @param {AST} ast The AST to be transformed.
49141  */
49142  TransformAngleBracketComponents.prototype.transform = function TransformAngleBracketComponents_transform(ast) {
49143    var walker = new this.syntax.Walker();
49144
49145    walker.visit(ast, function (node) {
49146      if (!validate(node)) {
49147        return;
49148      }
49149
49150      node.tag = '<' + node.tag + '>';
49151    });
49152
49153    return ast;
49154  };
49155
49156  function validate(node) {
49157    return node.type === 'ComponentNode';
49158  }
49159
49160  exports.default = TransformAngleBracketComponents;
49161});
49162enifed('ember-template-compiler/plugins/transform-closure-component-attrs-into-mut', ['exports'], function (exports) {
49163  'use strict';
49164
49165  function TransformClosureComponentAttrsIntoMut() {
49166    // set later within HTMLBars to the syntax package
49167    this.syntax = null;
49168  }
49169
49170  /**
49171    @private
49172    @method transform
49173    @param {AST} ast The AST to be transformed.
49174  */
49175  TransformClosureComponentAttrsIntoMut.prototype.transform = function TransformClosureComponentAttrsIntoMut_transform(ast) {
49176    var b = this.syntax.builders;
49177    var walker = new this.syntax.Walker();
49178
49179    walker.visit(ast, function (node) {
49180      if (validate(node)) {
49181        processExpression(b, node);
49182      }
49183    });
49184
49185    return ast;
49186  };
49187
49188  function processExpression(builder, node) {
49189    processSubExpressionsInNode(builder, node);
49190
49191    if (isComponentClosure(node)) {
49192      mutParameters(builder, node);
49193    }
49194  }
49195
49196  function processSubExpressionsInNode(builder, node) {
49197    for (var i = 0; i < node.params.length; i++) {
49198      if (node.params[i].type === 'SubExpression') {
49199        processExpression(builder, node.params[i]);
49200      }
49201    }
49202
49203    each(node.hash.pairs, function (pair) {
49204      var value = pair.value;
49205
49206      if (value.type === 'SubExpression') {
49207        processExpression(builder, value);
49208      }
49209    });
49210  }
49211
49212  function isComponentClosure(node) {
49213    return node.type === 'SubExpression' && node.path.original === 'component';
49214  }
49215
49216  function mutParameters(builder, node) {
49217    for (var i = 1; i < node.params.length; i++) {
49218      if (node.params[i].type === 'PathExpression') {
49219        node.params[i] = builder.sexpr(builder.path('@mut'), [node.params[i]]);
49220      }
49221    }
49222
49223    each(node.hash.pairs, function (pair) {
49224      var value = pair.value;
49225
49226      if (value.type === 'PathExpression') {
49227        pair.value = builder.sexpr(builder.path('@mut'), [pair.value]);
49228      }
49229    });
49230  }
49231
49232  function validate(node) {
49233    return node.type === 'BlockStatement' || node.type === 'MustacheStatement';
49234  }
49235
49236  function each(list, callback) {
49237    for (var i = 0, l = list.length; i < l; i++) {
49238      callback(list[i]);
49239    }
49240  }
49241
49242  exports.default = TransformClosureComponentAttrsIntoMut;
49243});
49244enifed('ember-template-compiler/plugins/transform-component-attrs-into-mut', ['exports'], function (exports) {
49245  'use strict';
49246
49247  function TransformComponentAttrsIntoMut() {
49248    // set later within HTMLBars to the syntax package
49249    this.syntax = null;
49250  }
49251
49252  /**
49253    @private
49254    @method transform
49255    @param {AST} ast The AST to be transformed.
49256  */
49257  TransformComponentAttrsIntoMut.prototype.transform = function TransformComponentAttrsIntoMut_transform(ast) {
49258    var b = this.syntax.builders;
49259    var walker = new this.syntax.Walker();
49260
49261    walker.visit(ast, function (node) {
49262      if (!validate(node)) {
49263        return;
49264      }
49265
49266      each(node.hash.pairs, function (pair) {
49267        var value = pair.value;
49268
49269        if (value.type === 'PathExpression') {
49270          pair.value = b.sexpr(b.path('@mut'), [pair.value]);
49271        }
49272      });
49273    });
49274
49275    return ast;
49276  };
49277
49278  function validate(node) {
49279    return node.type === 'BlockStatement' || node.type === 'MustacheStatement';
49280  }
49281
49282  function each(list, callback) {
49283    for (var i = 0, l = list.length; i < l; i++) {
49284      callback(list[i]);
49285    }
49286  }
49287
49288  exports.default = TransformComponentAttrsIntoMut;
49289});
49290enifed('ember-template-compiler/plugins/transform-component-curly-to-readonly', ['exports'], function (exports) {
49291  'use strict';
49292
49293  function TransformComponentCurlyToReadonly() {
49294    // set later within HTMLBars to the syntax package
49295    this.syntax = null;
49296  }
49297
49298  /**
49299    @private
49300    @method transform
49301    @param {AST} ast The AST to be transformed.
49302  */
49303  TransformComponentCurlyToReadonly.prototype.transform = function TransformComponetnCurlyToReadonly_transform(ast) {
49304    var b = this.syntax.builders;
49305    var walker = new this.syntax.Walker();
49306
49307    walker.visit(ast, function (node) {
49308      if (!validate(node)) {
49309        return;
49310      }
49311
49312      each(node.attributes, function (attr) {
49313        if (attr.value.type !== 'MustacheStatement') {
49314          return;
49315        }
49316        if (attr.value.params.length || attr.value.hash.pairs.length) {
49317          return;
49318        }
49319
49320        attr.value = b.mustache(b.path('readonly'), [attr.value.path], null, !attr.value.escape);
49321      });
49322    });
49323
49324    return ast;
49325  };
49326
49327  function validate(node) {
49328    return node.type === 'ComponentNode';
49329  }
49330
49331  function each(list, callback) {
49332    for (var i = 0, l = list.length; i < l; i++) {
49333      callback(list[i]);
49334    }
49335  }
49336
49337  exports.default = TransformComponentCurlyToReadonly;
49338});
49339enifed('ember-template-compiler/plugins/transform-each-into-collection', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
49340  'use strict';
49341
49342  exports.default = TransformEachIntoCollection;
49343
49344  function TransformEachIntoCollection(options) {
49345    this.options = options;
49346    this.syntax = null;
49347  }
49348
49349  TransformEachIntoCollection.prototype.transform = function TransformEachIntoCollection_transform(ast) {
49350    var moduleName = this.options.moduleName;
49351    var b = this.syntax.builders;
49352    var walker = new this.syntax.Walker();
49353
49354    walker.visit(ast, function (node) {
49355      var legacyHashKey = validate(node);
49356      if (!legacyHashKey) {
49357        return;
49358      }
49359
49360      var moduleInfo = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, legacyHashKey.loc);
49361
49362      _emberMetalDebug.deprecate('Using \'' + legacyHashKey.key + '\' with \'{{each}}\' ' + moduleInfo + 'is deprecated.  Please refactor to a component.', false, { id: 'ember-template-compiler.transform-each-into-collection', until: '2.0.0' });
49363
49364      var list = node.params.shift();
49365      node.path = b.path('collection');
49366
49367      node.params.unshift(b.string('-legacy-each'));
49368
49369      var pair = b.pair('content', list);
49370      pair.loc = list.loc;
49371
49372      node.hash.pairs.push(pair);
49373
49374      //pair = b.pair('dataSource', list);
49375      //node.hash.pairs.push(pair);
49376    });
49377
49378    return ast;
49379  };
49380
49381  function validate(node) {
49382    if ((node.type === 'BlockStatement' || node.type === 'MustacheStatement') && node.path.original === 'each') {
49383      return any(node.hash.pairs, function (pair) {
49384        var key = pair.key;
49385        return key === 'itemController' || key === 'itemView' || key === 'itemViewClass' || key === 'tagName' || key === 'emptyView' || key === 'emptyViewClass';
49386      });
49387    }
49388
49389    return false;
49390  }
49391
49392  function any(list, predicate) {
49393    for (var i = 0, l = list.length; i < l; i++) {
49394      if (predicate(list[i])) {
49395        return list[i];
49396      }
49397    }
49398
49399    return false;
49400  }
49401});
49402enifed('ember-template-compiler/plugins/transform-input-on-to-onEvent', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
49403  'use strict';
49404
49405  /**
49406   @module ember
49407   @submodule ember-htmlbars
49408  */
49409
49410  /**
49411    An HTMLBars AST transformation that replaces all instances of
49412  
49413    ```handlebars
49414   {{input on="enter" action="doStuff"}}
49415   {{input on="key-press" action="doStuff"}}
49416    ```
49417  
49418    with
49419  
49420    ```handlebars
49421   {{input enter="doStuff"}}
49422   {{input key-press="doStuff"}}
49423    ```
49424  
49425    @private
49426    @class TransformInputOnToOnEvent
49427  */
49428  function TransformInputOnToOnEvent() {
49429    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
49430
49431    // set later within HTMLBars to the syntax package
49432    this.syntax = null;
49433    this.options = options;
49434  }
49435
49436  /**
49437    @private
49438    @method transform
49439    @param {AST} ast The AST to be transformed.
49440  */
49441  TransformInputOnToOnEvent.prototype.transform = function TransformInputOnToOnEvent_transform(ast) {
49442    var pluginContext = this;
49443    var b = pluginContext.syntax.builders;
49444    var walker = new pluginContext.syntax.Walker();
49445    var moduleName = pluginContext.options.moduleName;
49446
49447    walker.visit(ast, function (node) {
49448      if (pluginContext.validate(node)) {
49449        var action = hashPairForKey(node.hash, 'action');
49450        var on = hashPairForKey(node.hash, 'on');
49451        var onEvent = hashPairForKey(node.hash, 'onEvent');
49452        var normalizedOn = on || onEvent;
49453        var moduleInfo = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc);
49454
49455        if (normalizedOn && normalizedOn.value.type !== 'StringLiteral') {
49456          _emberMetalDebug.deprecate('Using a dynamic value for \'#{normalizedOn.key}=\' with the \'{{input}}\' helper ' + moduleInfo + 'is deprecated.', false, { id: 'ember-template-compiler.transform-input-on-to-onEvent.dynamic-value', until: '3.0.0' });
49457
49458          normalizedOn.key = 'onEvent';
49459          return; // exit early, as we cannot transform further
49460        }
49461
49462        removeFromHash(node.hash, normalizedOn);
49463        removeFromHash(node.hash, action);
49464
49465        if (!action) {
49466          _emberMetalDebug.deprecate('Using \'{{input ' + normalizedOn.key + '="' + normalizedOn.value.value + '" ...}}\' without specifying an action ' + moduleInfo + 'will do nothing.', false, { id: 'ember-template-compiler.transform-input-on-to-onEvent.no-action', until: '3.0.0' });
49467
49468          return; // exit early, if no action was available there is nothing to do
49469        }
49470
49471        var specifiedOn = normalizedOn ? normalizedOn.key + '="' + normalizedOn.value.value + '" ' : '';
49472        if (normalizedOn && normalizedOn.value.value === 'keyPress') {
49473          // using `keyPress` in the root of the component will
49474          // clobber the keyPress event handler
49475          normalizedOn.value.value = 'key-press';
49476        }
49477
49478        var expected = (normalizedOn ? normalizedOn.value.value : 'enter') + '="' + action.value.original + '"';
49479
49480        _emberMetalDebug.deprecate('Using \'{{input ' + specifiedOn + 'action="' + action.value.original + '"}}\' ' + moduleInfo + 'is deprecated. Please use \'{{input ' + expected + '}}\' instead.', false, { id: 'ember-template-compiler.transform-input-on-to-onEvent.normalized-on', until: '3.0.0' });
49481        if (!normalizedOn) {
49482          normalizedOn = b.pair('onEvent', b.string('enter'));
49483        }
49484
49485        node.hash.pairs.push(b.pair(normalizedOn.value.value, action.value));
49486      }
49487    });
49488
49489    return ast;
49490  };
49491
49492  TransformInputOnToOnEvent.prototype.validate = function TransformWithAsToHash_validate(node) {
49493    return node.type === 'MustacheStatement' && node.path.original === 'input' && (hashPairForKey(node.hash, 'action') || hashPairForKey(node.hash, 'on') || hashPairForKey(node.hash, 'onEvent'));
49494  };
49495
49496  function hashPairForKey(hash, key) {
49497    for (var i = 0, l = hash.pairs.length; i < l; i++) {
49498      var pair = hash.pairs[i];
49499      if (pair.key === key) {
49500        return pair;
49501      }
49502    }
49503
49504    return false;
49505  }
49506
49507  function removeFromHash(hash, pairToRemove) {
49508    var newPairs = [];
49509    for (var i = 0, l = hash.pairs.length; i < l; i++) {
49510      var pair = hash.pairs[i];
49511
49512      if (pair !== pairToRemove) {
49513        newPairs.push(pair);
49514      }
49515    }
49516
49517    hash.pairs = newPairs;
49518  }
49519
49520  exports.default = TransformInputOnToOnEvent;
49521});
49522enifed('ember-template-compiler/plugins/transform-item-class', ['exports'], function (exports) {
49523  'use strict';
49524
49525  exports.default = TransformItemClass;
49526
49527  function TransformItemClass() {
49528    this.syntax = null;
49529  }
49530
49531  TransformItemClass.prototype.transform = function TransformItemClass_transform(ast) {
49532    var b = this.syntax.builders;
49533    var walker = new this.syntax.Walker();
49534
49535    walker.visit(ast, function (node) {
49536      if (!validate(node)) {
49537        return;
49538      }
49539
49540      each(node.hash.pairs, function (pair) {
49541        var key = pair.key;
49542        var value = pair.value;
49543
49544        if (key !== 'itemClass') {
49545          return;
49546        }
49547        if (value.type === 'StringLiteral') {
49548          return;
49549        }
49550
49551        var propName = value.original;
49552        var params = [value];
49553        var sexprParams = [b.string(propName), b.path(propName)];
49554
49555        params.push(b.sexpr(b.string('-normalize-class'), sexprParams));
49556        var sexpr = b.sexpr(b.string('if'), params);
49557
49558        pair.value = sexpr;
49559      });
49560    });
49561
49562    return ast;
49563  };
49564
49565  function validate(node) {
49566    return (node.type === 'BlockStatement' || node.type === 'MustacheStatement') && node.path.original === 'collection';
49567  }
49568
49569  function each(list, callback) {
49570    for (var i = 0, l = list.length; i < l; i++) {
49571      callback(list[i]);
49572    }
49573  }
49574});
49575enifed('ember-template-compiler/plugins/transform-old-binding-syntax', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) {
49576  'use strict';
49577
49578  exports.default = TransformOldBindingSyntax;
49579
49580  function TransformOldBindingSyntax(options) {
49581    this.syntax = null;
49582    this.options = options;
49583  }
49584
49585  TransformOldBindingSyntax.prototype.transform = function TransformOldBindingSyntax_transform(ast) {
49586    var moduleName = this.options.moduleName;
49587    var b = this.syntax.builders;
49588    var walker = new this.syntax.Walker();
49589
49590    walker.visit(ast, function (node) {
49591      if (!validate(node)) {
49592        return;
49593      }
49594
49595      each(node.hash.pairs, function (pair) {
49596        var key = pair.key;
49597        var value = pair.value;
49598
49599        var sourceInformation = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, pair.loc);
49600
49601        if (key === 'classBinding') {
49602          return;
49603        }
49604
49605        _emberMetalDebug.assert('Setting \'attributeBindings\' via template helpers is not allowed ' + sourceInformation, key !== 'attributeBindings');
49606
49607        if (key.substr(-7) === 'Binding') {
49608          var newKey = key.slice(0, -7);
49609
49610          _emberMetalDebug.deprecate('You\'re using legacy binding syntax: ' + key + '=' + exprToString(value) + ' ' + sourceInformation + '. Please replace with ' + newKey + '=' + value.original, false, { id: 'ember-template-compiler.transform-old-binding-syntax', until: '3.0.0' });
49611
49612          pair.key = newKey;
49613          if (value.type === 'StringLiteral') {
49614            pair.value = b.path(value.original);
49615          }
49616        }
49617      });
49618    });
49619
49620    return ast;
49621  };
49622
49623  function validate(node) {
49624    return node.type === 'BlockStatement' || node.type === 'MustacheStatement';
49625  }
49626
49627  function each(list, callback) {
49628    for (var i = 0, l = list.length; i < l; i++) {
49629      callback(list[i]);
49630    }
49631  }
49632
49633  function exprToString(expr) {
49634    switch (expr.type) {
49635      case 'StringLiteral':
49636        return '"' + expr.original + '"';
49637      case 'PathExpression':
49638        return expr.original;
49639    }
49640  }
49641});
49642enifed('ember-template-compiler/plugins/transform-old-class-binding-syntax', ['exports'], function (exports) {
49643  'use strict';
49644
49645  exports.default = TransformOldClassBindingSyntax;
49646
49647  function TransformOldClassBindingSyntax(options) {
49648    this.syntax = null;
49649    this.options = options;
49650  }
49651
49652  TransformOldClassBindingSyntax.prototype.transform = function TransformOldClassBindingSyntax_transform(ast) {
49653    var b = this.syntax.builders;
49654    var walker = new this.syntax.Walker();
49655
49656    walker.visit(ast, function (node) {
49657      if (!validate(node)) {
49658        return;
49659      }
49660
49661      var allOfTheMicrosyntaxes = [];
49662      var allOfTheMicrosyntaxIndexes = [];
49663      var classPair = undefined;
49664
49665      each(node.hash.pairs, function (pair, index) {
49666        var key = pair.key;
49667
49668        if (key === 'classBinding' || key === 'classNameBindings') {
49669          allOfTheMicrosyntaxIndexes.push(index);
49670          allOfTheMicrosyntaxes.push(pair);
49671        } else if (key === 'class') {
49672          classPair = pair;
49673        }
49674      });
49675
49676      if (allOfTheMicrosyntaxes.length === 0) {
49677        return;
49678      }
49679
49680      var classValue = [];
49681
49682      if (classPair) {
49683        classValue.push(classPair.value);
49684        classValue.push(b.string(' '));
49685      } else {
49686        classPair = b.pair('class', null);
49687        node.hash.pairs.push(classPair);
49688      }
49689
49690      each(allOfTheMicrosyntaxIndexes, function (index) {
49691        node.hash.pairs.splice(index, 1);
49692      });
49693
49694      each(allOfTheMicrosyntaxes, function (_ref) {
49695        var value = _ref.value;
49696        var loc = _ref.loc;
49697
49698        var sexprs = [];
49699        // TODO: add helpful deprecation when both `classNames` and `classNameBindings` can
49700        // be removed.
49701
49702        if (value.type === 'StringLiteral') {
49703          var microsyntax = parseMicrosyntax(value.original);
49704
49705          buildSexprs(microsyntax, sexprs, b);
49706
49707          classValue.push.apply(classValue, sexprs);
49708        }
49709      });
49710
49711      var hash = b.hash();
49712      classPair.value = b.sexpr(b.string('concat'), classValue, hash);
49713    });
49714
49715    return ast;
49716  };
49717
49718  function buildSexprs(microsyntax, sexprs, b) {
49719    for (var i = 0, l = microsyntax.length; i < l; i++) {
49720      var _microsyntax$i = microsyntax[i];
49721      var propName = _microsyntax$i[0];
49722      var activeClass = _microsyntax$i[1];
49723      var inactiveClass = _microsyntax$i[2];
49724
49725      var sexpr = undefined;
49726
49727      // :my-class-name microsyntax for static values
49728      if (propName === '') {
49729        sexpr = b.string(activeClass);
49730      } else {
49731        var params = [b.path(propName)];
49732
49733        if (activeClass) {
49734          params.push(b.string(activeClass));
49735        } else {
49736          var sexprParams = [b.string(propName), b.path(propName)];
49737
49738          var hash = b.hash();
49739          if (activeClass !== undefined) {
49740            hash.pairs.push(b.pair('activeClass', b.string(activeClass)));
49741          }
49742
49743          if (inactiveClass !== undefined) {
49744            hash.pairs.push(b.pair('inactiveClass', b.string(inactiveClass)));
49745          }
49746
49747          params.push(b.sexpr(b.string('-normalize-class'), sexprParams, hash));
49748        }
49749
49750        if (inactiveClass) {
49751          params.push(b.string(inactiveClass));
49752        }
49753
49754        sexpr = b.sexpr(b.string('if'), params);
49755      }
49756
49757      sexprs.push(sexpr);
49758      sexprs.push(b.string(' '));
49759    }
49760  }
49761
49762  function validate(node) {
49763    return node.type === 'BlockStatement' || node.type === 'MustacheStatement';
49764  }
49765
49766  function each(list, callback) {
49767    for (var i = 0, l = list.length; i < l; i++) {
49768      callback(list[i], i);
49769    }
49770  }
49771
49772  function parseMicrosyntax(string) {
49773    var segments = string.split(' ');
49774
49775    for (var i = 0, l = segments.length; i < l; i++) {
49776      segments[i] = segments[i].split(':');
49777    }
49778
49779    return segments;
49780  }
49781});
49782enifed('ember-template-compiler/plugins/transform-top-level-components', ['exports'], function (exports) {
49783  'use strict';
49784
49785  function TransformTopLevelComponents() {
49786    // set later within HTMLBars to the syntax package
49787    this.syntax = null;
49788  }
49789
49790  /**
49791    @private
49792    @method transform
49793    @param {AST} The AST to be transformed.
49794  */
49795  TransformTopLevelComponents.prototype.transform = function TransformTopLevelComponents_transform(ast) {
49796    var b = this.syntax.builders;
49797
49798    hasSingleComponentNode(ast, function (component) {
49799      if (component.type === 'ComponentNode') {
49800        component.tag = '@' + component.tag;
49801        component.isStatic = true;
49802      }
49803    }, function (element) {
49804      var hasTripleCurlies = element.attributes.some(function (attr) {
49805        return attr.value.escaped === false;
49806      });
49807
49808      if (element.modifiers.length || hasTripleCurlies) {
49809        return element;
49810      } else {
49811        // TODO: Properly copy loc from children
49812        var program = b.program(element.children);
49813        var component = b.component('@<' + element.tag + '>', element.attributes, program, element.loc);
49814        component.isStatic = true;
49815        return component;
49816      }
49817    });
49818
49819    return ast;
49820  };
49821
49822  function hasSingleComponentNode(program, componentCallback, elementCallback) {
49823    var loc = program.loc;
49824    var body = program.body;
49825
49826    if (!loc || loc.start.line !== 1 || loc.start.column !== 0) {
49827      return;
49828    }
49829
49830    var lastComponentNode = undefined;
49831    var lastIndex = undefined;
49832    var nodeCount = 0;
49833
49834    for (var i = 0, l = body.length; i < l; i++) {
49835      var curr = body[i];
49836
49837      // text node with whitespace only
49838      if (curr.type === 'TextNode' && /^[\s]*$/.test(curr.chars)) {
49839        continue;
49840      }
49841
49842      // has multiple root elements if we've been here before
49843      if (nodeCount++ > 0) {
49844        return false;
49845      }
49846
49847      if (curr.type === 'ComponentNode' || curr.type === 'ElementNode') {
49848        lastComponentNode = curr;
49849        lastIndex = i;
49850      }
49851    }
49852
49853    if (!lastComponentNode) {
49854      return;
49855    }
49856
49857    if (lastComponentNode.type === 'ComponentNode') {
49858      componentCallback(lastComponentNode);
49859    }
49860  }
49861
49862  exports.default = TransformTopLevelComponents;
49863});
49864enifed('ember-template-compiler/plugins/transform-unescaped-inline-link-to', ['exports'], function (exports) {
49865  'use strict';
49866
49867  exports.default = TransformUnescapedInlineLinkTo;
49868
49869  function TransformUnescapedInlineLinkTo(options) {
49870    this.options = options;
49871    this.syntax = null;
49872  }
49873
49874  TransformUnescapedInlineLinkTo.prototype.transform = function TransformUnescapedInlineLinkTo_transform(ast) {
49875    var b = this.syntax.builders;
49876    var walker = new this.syntax.Walker();
49877
49878    walker.visit(ast, function (node) {
49879      if (!validate(node)) {
49880        return;
49881      }
49882
49883      node.escaped = true;
49884      node.params[0] = b.sexpr(b.string('-html-safe'), [node.params[0]]);
49885    });
49886
49887    return ast;
49888  };
49889
49890  function validate(node) {
49891    return node.type === 'MustacheStatement' && node.path.original === 'link-to' && !node.escaped;
49892  }
49893});
49894enifed('ember-template-compiler/plugins', ['exports'], function (exports) {
49895  /**
49896  @module ember
49897  @submodule ember-template-compiler
49898  */
49899
49900  /**
49901   @private
49902   @property helpers
49903  */
49904  'use strict';
49905
49906  exports.registerPlugin = registerPlugin;
49907  var plugins = {
49908    ast: []
49909  };
49910
49911  /**
49912    Adds an AST plugin to be used by Ember.HTMLBars.compile.
49913  
49914    @private
49915    @method registerASTPlugin
49916  */
49917
49918  function registerPlugin(type, Plugin) {
49919    if (!plugins[type]) {
49920      throw new Error('Attempting to register "' + Plugin + '" as "' + type + '" which is not a valid HTMLBars plugin type.');
49921    }
49922
49923    plugins[type].push(Plugin);
49924  }
49925
49926  exports.default = plugins;
49927});
49928enifed('ember-template-compiler/system/calculate-location-display', ['exports'], function (exports) {
49929  'use strict';
49930
49931  exports.default = calculateLocationDisplay;
49932
49933  function calculateLocationDisplay(moduleName) {
49934    var loc = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
49935
49936    var _ref = loc.start || {};
49937
49938    var column = _ref.column;
49939    var line = _ref.line;
49940
49941    var moduleInfo = '';
49942    if (moduleName) {
49943      moduleInfo += '\'' + moduleName + '\' ';
49944    }
49945
49946    if (line !== undefined && column !== undefined) {
49947      if (moduleName) {
49948        // only prepend @ if the moduleName was present
49949        moduleInfo += '@ ';
49950      }
49951      moduleInfo += 'L' + line + ':C' + column;
49952    }
49953
49954    if (moduleInfo) {
49955      moduleInfo = '(' + moduleInfo + ') ';
49956    }
49957
49958    return moduleInfo;
49959  }
49960});
49961enifed('ember-template-compiler/system/compile', ['exports', 'require', 'ember-template-compiler/system/compile_options', 'ember-template-compiler/system/template'], function (exports, _require, _emberTemplateCompilerSystemCompile_options, _emberTemplateCompilerSystemTemplate) {
49962  /**
49963  @module ember
49964  @submodule ember-template-compiler
49965  */
49966
49967  'use strict';
49968
49969  var compile;
49970
49971  /**
49972    Uses HTMLBars `compile` function to process a string into a compiled template.
49973  
49974    This is not present in production builds.
49975  
49976    @private
49977    @method compile
49978    @param {String} templateString This is the string to be compiled by HTMLBars.
49979    @param {Object} options This is an options hash to augment the compiler options.
49980  */
49981
49982  exports.default = function (templateString, options) {
49983    if (!compile && _require.has('htmlbars-compiler/compiler')) {
49984      compile = _require.default('htmlbars-compiler/compiler').compile;
49985    }
49986
49987    if (!compile) {
49988      throw new Error('Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`.');
49989    }
49990
49991    var templateSpec = compile(templateString, _emberTemplateCompilerSystemCompile_options.default(options));
49992
49993    return _emberTemplateCompilerSystemTemplate.default(templateSpec);
49994  };
49995});
49996enifed('ember-template-compiler/system/compile_options', ['exports', 'ember-metal/assign', 'ember-template-compiler/plugins'], function (exports, _emberMetalAssign, _emberTemplateCompilerPlugins) {
49997  /**
49998  @module ember
49999  @submodule ember-template-compiler
50000  */
50001
50002  'use strict';
50003
50004  /**
50005    @private
50006    @property compileOptions
50007  */
50008
50009  exports.default = function (_options) {
50010    var disableComponentGeneration = true;
50011
50012    var options = undefined;
50013    // When calling `Ember.Handlebars.compile()` a second argument of `true`
50014    // had a special meaning (long since lost), this just gaurds against
50015    // `options` being true, and causing an error during compilation.
50016    if (_options === true) {
50017      options = {};
50018    } else {
50019      options = _emberMetalAssign.default({}, _options);
50020    }
50021
50022    options.disableComponentGeneration = disableComponentGeneration;
50023
50024    var plugins = {
50025      ast: _emberTemplateCompilerPlugins.default.ast.slice()
50026    };
50027
50028    if (options.plugins && options.plugins.ast) {
50029      plugins.ast = plugins.ast.concat(options.plugins.ast);
50030    }
50031    options.plugins = plugins;
50032
50033    options.buildMeta = function buildMeta(program) {
50034      return {
50035        fragmentReason: fragmentReason(program),
50036        revision: '[email protected]',
50037        loc: program.loc,
50038        moduleName: options.moduleName
50039      };
50040    };
50041
50042    return options;
50043  };
50044
50045  function fragmentReason(program) {
50046    var loc = program.loc;
50047    var body = program.body;
50048
50049    if (!loc || loc.start.line !== 1 || loc.start.column !== 0) {
50050      return false;
50051    }
50052
50053    var candidate = undefined;
50054    var nodeCount = 0;
50055
50056    var problems = {};
50057
50058    for (var i = 0, l = body.length; i < l; i++) {
50059      var curr = body[i];
50060
50061      // text node with whitespace only
50062      if (curr.type === 'TextNode' && /^[\s]*$/.test(curr.chars)) {
50063        continue;
50064      }
50065
50066      // has multiple root elements if we've been here before
50067      if (nodeCount++ > 0) {
50068        problems['multiple-nodes'] = true;
50069      }
50070
50071      if (curr.type === 'ComponentNode' || curr.type === 'ElementNode') {
50072        candidate = curr;
50073      } else {
50074        problems['wrong-type'] = true;
50075      }
50076    }
50077
50078    if (nodeCount === 0) {
50079      return { name: 'missing-wrapper', problems: ['empty-body'] };
50080    }
50081
50082    var problemList = Object.keys(problems);
50083    if (problemList.length) {
50084      return { name: 'missing-wrapper', problems: problemList };
50085    }
50086
50087    if (candidate.type === 'ComponentNode') {
50088      return false;
50089    } else if (candidate.modifiers.length) {
50090      return { name: 'modifiers', modifiers: candidate.modifiers.map(function (m) {
50091          return m.path.original;
50092        }) };
50093    } else if (candidate.attributes.some(function (attr) {
50094      return !attr.value.escaped;
50095    })) {
50096      return { name: 'triple-curlies' };
50097    } else {
50098      return false;
50099    }
50100  }
50101});
50102enifed('ember-template-compiler/system/precompile', ['exports', 'require', 'ember-template-compiler/system/compile_options'], function (exports, _require, _emberTemplateCompilerSystemCompile_options) {
50103  /**
50104  @module ember
50105  @submodule ember-template-compiler
50106  */
50107  'use strict';
50108
50109  var compileSpec;
50110
50111  /**
50112    Uses HTMLBars `compile` function to process a string into a compiled template string.
50113    The returned string must be passed through `Ember.HTMLBars.template`.
50114  
50115    This is not present in production builds.
50116  
50117    @private
50118    @method precompile
50119    @param {String} templateString This is the string to be compiled by HTMLBars.
50120  */
50121
50122  exports.default = function (templateString, options) {
50123    if (!compileSpec && _require.has('htmlbars-compiler/compiler')) {
50124      compileSpec = _require.default('htmlbars-compiler/compiler').compileSpec;
50125    }
50126
50127    if (!compileSpec) {
50128      throw new Error('Cannot call `compileSpec` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compileSpec`.');
50129    }
50130
50131    return compileSpec(templateString, _emberTemplateCompilerSystemCompile_options.default(options));
50132  };
50133});
50134enifed('ember-template-compiler/system/template', ['exports', 'htmlbars-runtime/hooks'], function (exports, _htmlbarsRuntimeHooks) {
50135  'use strict';
50136
50137  /**
50138  @module ember
50139  @submodule ember-template-compiler
50140  */
50141
50142  /**
50143    Augments the default precompiled output of an HTMLBars template with
50144    additional information needed by Ember.
50145  
50146    @private
50147    @method template
50148    @param {Function} templateSpec This is the compiled HTMLBars template spec.
50149  */
50150
50151  exports.default = function (templateSpec) {
50152    if (!templateSpec.render) {
50153      templateSpec = _htmlbarsRuntimeHooks.wrap(templateSpec);
50154    }
50155
50156    templateSpec.isTop = true;
50157    templateSpec.isMethod = false;
50158
50159    return templateSpec;
50160  };
50161});
50162enifed('ember-testing/adapters/adapter', ['exports', 'ember-runtime/system/object'], function (exports, _emberRuntimeSystemObject) {
50163  'use strict';
50164
50165  function K() {
50166    return this;
50167  }
50168
50169  /**
50170   @module ember
50171   @submodule ember-testing
50172  */
50173
50174  /**
50175    The primary purpose of this class is to create hooks that can be implemented
50176    by an adapter for various test frameworks.
50177  
50178    @class Adapter
50179    @namespace Ember.Test
50180    @public
50181  */
50182  var Adapter = _emberRuntimeSystemObject.default.extend({
50183    /**
50184      This callback will be called whenever an async operation is about to start.
50185       Override this to call your framework's methods that handle async
50186      operations.
50187       @public
50188      @method asyncStart
50189    */
50190    asyncStart: K,
50191
50192    /**
50193      This callback will be called whenever an async operation has completed.
50194       @public
50195      @method asyncEnd
50196    */
50197    asyncEnd: K,
50198
50199    /**
50200      Override this method with your testing framework's false assertion.
50201      This function is called whenever an exception occurs causing the testing
50202      promise to fail.
50203       QUnit example:
50204       ```javascript
50205        exception: function(error) {
50206          ok(false, error);
50207        };
50208      ```
50209       @public
50210      @method exception
50211      @param {String} error The exception to be raised.
50212    */
50213    exception: function (error) {
50214      throw error;
50215    }
50216  });
50217
50218  exports.default = Adapter;
50219});
50220enifed('ember-testing/adapters/qunit', ['exports', 'ember-testing/adapters/adapter', 'ember-metal/utils'], function (exports, _emberTestingAdaptersAdapter, _emberMetalUtils) {
50221  'use strict';
50222
50223  /**
50224    This class implements the methods defined by Ember.Test.Adapter for the
50225    QUnit testing framework.
50226  
50227    @class QUnitAdapter
50228    @namespace Ember.Test
50229    @extends Ember.Test.Adapter
50230    @public
50231  */
50232  exports.default = _emberTestingAdaptersAdapter.default.extend({
50233    asyncStart: function () {
50234      QUnit.stop();
50235    },
50236    asyncEnd: function () {
50237      QUnit.start();
50238    },
50239    exception: function (error) {
50240      ok(false, _emberMetalUtils.inspect(error));
50241    }
50242  });
50243});
50244enifed('ember-testing/helpers', ['exports', 'ember-metal/property_get', 'ember-metal/error', 'ember-metal/run_loop', 'ember-views/system/jquery', 'ember-testing/test', 'ember-runtime/ext/rsvp', 'ember-metal/features'], function (exports, _emberMetalProperty_get, _emberMetalError, _emberMetalRun_loop, _emberViewsSystemJquery, _emberTestingTest, _emberRuntimeExtRsvp, _emberMetalFeatures) {
50245  'use strict';
50246
50247  /**
50248  @module ember
50249  @submodule ember-testing
50250  */
50251
50252  var helper = _emberTestingTest.default.registerHelper;
50253  var asyncHelper = _emberTestingTest.default.registerAsyncHelper;
50254
50255  var keyboardEventTypes, mouseEventTypes, buildKeyboardEvent, buildMouseEvent, buildBasicEvent, fireEvent, focus;
50256
50257  var defaultEventOptions = { canBubble: true, cancelable: true };
50258  keyboardEventTypes = ['keydown', 'keypress', 'keyup'];
50259  mouseEventTypes = ['click', 'mousedown', 'mouseup', 'dblclick', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover'];
50260
50261  buildKeyboardEvent = function buildKeyboardEvent(type) {
50262    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
50263
50264    var event = undefined;
50265    try {
50266      event = document.createEvent('KeyEvents');
50267      var eventOpts = _emberViewsSystemJquery.default.extend({}, defaultEventOptions, options);
50268      event.initKeyEvent(type, eventOpts.canBubble, eventOpts.cancelable, window, eventOpts.ctrlKey, eventOpts.altKey, eventOpts.shiftKey, eventOpts.metaKey, eventOpts.keyCode, eventOpts.charCode);
50269    } catch (e) {
50270      event = buildBasicEvent(type, options);
50271    }
50272    return event;
50273  };
50274
50275  buildMouseEvent = function buildMouseEvent(type) {
50276    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
50277
50278    var event = undefined;
50279    try {
50280      event = document.createEvent('MouseEvents');
50281      var eventOpts = _emberViewsSystemJquery.default.extend({}, defaultEventOptions, options);
50282      event.initMouseEvent(type, eventOpts.canBubble, eventOpts.cancelable, window, eventOpts.detail, eventOpts.screenX, eventOpts.screenY, eventOpts.clientX, eventOpts.clientY, eventOpts.ctrlKey, eventOpts.altKey, eventOpts.shiftKey, eventOpts.metaKey, eventOpts.button, eventOpts.relatedTarget);
50283    } catch (e) {
50284      event = buildBasicEvent(type, options);
50285    }
50286    return event;
50287  };
50288
50289  buildBasicEvent = function buildBasicEvent(type) {
50290    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
50291
50292    var event = document.createEvent('Events');
50293    event.initEvent(type, true, true);
50294    _emberViewsSystemJquery.default.extend(event, options);
50295    return event;
50296  };
50297
50298  fireEvent = function fireEvent(element, type) {
50299    var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
50300
50301    if (!element) {
50302      return;
50303    }
50304    var event = undefined;
50305    if (keyboardEventTypes.indexOf(type) > -1) {
50306      event = buildKeyboardEvent(type, options);
50307    } else if (mouseEventTypes.indexOf(type) > -1) {
50308      var rect = element.getBoundingClientRect();
50309      var x = rect.left + 1;
50310      var y = rect.top + 1;
50311      var simulatedCoordinates = {
50312        screenX: x + 5,
50313        screenY: y + 95,
50314        clientX: x,
50315        clientY: y
50316      };
50317      event = buildMouseEvent(type, _emberViewsSystemJquery.default.extend(simulatedCoordinates, options));
50318    } else {
50319      event = buildBasicEvent(type, options);
50320    }
50321    element.dispatchEvent(event);
50322  };
50323
50324  focus = function focus(el) {
50325    if (!el) {
50326      return;
50327    }
50328    var $el = _emberViewsSystemJquery.default(el);
50329    if ($el.is(':input, [contenteditable=true]')) {
50330      var type = $el.prop('type');
50331      if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
50332        _emberMetalRun_loop.default(null, function () {
50333          // Firefox does not trigger the `focusin` event if the window
50334          // does not have focus. If the document doesn't have focus just
50335          // use trigger('focusin') instead.
50336
50337          if (!document.hasFocus || document.hasFocus()) {
50338            el.focus();
50339          } else {
50340            $el.trigger('focusin');
50341          }
50342        });
50343      }
50344    }
50345  };
50346
50347  function currentRouteName(app) {
50348    var routingService = app.__container__.lookup('service:-routing');
50349
50350    return _emberMetalProperty_get.get(routingService, 'currentRouteName');
50351  }
50352
50353  function currentPath(app) {
50354    var routingService = app.__container__.lookup('service:-routing');
50355
50356    return _emberMetalProperty_get.get(routingService, 'currentPath');
50357  }
50358
50359  function currentURL(app) {
50360    var router = app.__container__.lookup('router:main');
50361
50362    return _emberMetalProperty_get.get(router, 'location').getURL();
50363  }
50364
50365  function pauseTest() {
50366    _emberTestingTest.default.adapter.asyncStart();
50367    return new _emberRuntimeExtRsvp.default.Promise(function () {}, 'TestAdapter paused promise');
50368  }
50369
50370  function visit(app, url) {
50371    var router = app.__container__.lookup('router:main');
50372    var shouldHandleURL = false;
50373
50374    app.boot().then(function () {
50375      router.location.setURL(url);
50376
50377      if (shouldHandleURL) {
50378        _emberMetalRun_loop.default(app.__deprecatedInstance__, 'handleURL', url);
50379      }
50380    });
50381
50382    if (app._readinessDeferrals > 0) {
50383      router['initialURL'] = url;
50384      _emberMetalRun_loop.default(app, 'advanceReadiness');
50385      delete router['initialURL'];
50386    } else {
50387      shouldHandleURL = true;
50388    }
50389
50390    return app.testHelpers.wait();
50391  }
50392
50393  function click(app, selector, context) {
50394    var $el = app.testHelpers.findWithAssert(selector, context);
50395    var el = $el[0];
50396
50397    _emberMetalRun_loop.default(null, fireEvent, el, 'mousedown');
50398
50399    focus(el);
50400
50401    _emberMetalRun_loop.default(null, fireEvent, el, 'mouseup');
50402    _emberMetalRun_loop.default(null, fireEvent, el, 'click');
50403
50404    return app.testHelpers.wait();
50405  }
50406
50407  function triggerEvent(app, selector, contextOrType, typeOrOptions, possibleOptions) {
50408    var arity = arguments.length;
50409    var context, type, options;
50410
50411    if (arity === 3) {
50412      // context and options are optional, so this is
50413      // app, selector, type
50414      context = null;
50415      type = contextOrType;
50416      options = {};
50417    } else if (arity === 4) {
50418      // context and options are optional, so this is
50419      if (typeof typeOrOptions === 'object') {
50420        // either
50421        // app, selector, type, options
50422        context = null;
50423        type = contextOrType;
50424        options = typeOrOptions;
50425      } else {
50426        // or
50427        // app, selector, context, type
50428        context = contextOrType;
50429        type = typeOrOptions;
50430        options = {};
50431      }
50432    } else {
50433      context = contextOrType;
50434      type = typeOrOptions;
50435      options = possibleOptions;
50436    }
50437
50438    var $el = app.testHelpers.findWithAssert(selector, context);
50439    var el = $el[0];
50440
50441    _emberMetalRun_loop.default(null, fireEvent, el, type, options);
50442
50443    return app.testHelpers.wait();
50444  }
50445
50446  function keyEvent(app, selector, contextOrType, typeOrKeyCode, keyCode) {
50447    var context, type;
50448
50449    if (typeof keyCode === 'undefined') {
50450      context = null;
50451      keyCode = typeOrKeyCode;
50452      type = contextOrType;
50453    } else {
50454      context = contextOrType;
50455      type = typeOrKeyCode;
50456    }
50457
50458    return app.testHelpers.triggerEvent(selector, context, type, { keyCode: keyCode, which: keyCode });
50459  }
50460
50461  function fillIn(app, selector, contextOrText, text) {
50462    var $el, el, context;
50463    if (typeof text === 'undefined') {
50464      text = contextOrText;
50465    } else {
50466      context = contextOrText;
50467    }
50468    $el = app.testHelpers.findWithAssert(selector, context);
50469    el = $el[0];
50470    focus(el);
50471    _emberMetalRun_loop.default(function () {
50472      $el.val(text);
50473      fireEvent(el, 'input');
50474      fireEvent(el, 'change');
50475    });
50476    return app.testHelpers.wait();
50477  }
50478
50479  function findWithAssert(app, selector, context) {
50480    var $el = app.testHelpers.find(selector, context);
50481    if ($el.length === 0) {
50482      throw new _emberMetalError.default('Element ' + selector + ' not found.');
50483    }
50484    return $el;
50485  }
50486
50487  function find(app, selector, context) {
50488    var $el;
50489    context = context || _emberMetalProperty_get.get(app, 'rootElement');
50490    $el = app.$(selector, context);
50491
50492    return $el;
50493  }
50494
50495  function andThen(app, callback) {
50496    return app.testHelpers.wait(callback(app));
50497  }
50498
50499  function wait(app, value) {
50500    return new _emberRuntimeExtRsvp.default.Promise(function (resolve) {
50501      var router = app.__container__.lookup('router:main');
50502
50503      // Every 10ms, poll for the async thing to have finished
50504      var watcher = setInterval(function () {
50505        // 1. If the router is loading, keep polling
50506        var routerIsLoading = router.router && !!router.router.activeTransition;
50507        if (routerIsLoading) {
50508          return;
50509        }
50510
50511        // 2. If there are pending Ajax requests, keep polling
50512        if (_emberTestingTest.default.pendingAjaxRequests) {
50513          return;
50514        }
50515
50516        // 3. If there are scheduled timers or we are inside of a run loop, keep polling
50517        if (_emberMetalRun_loop.default.hasScheduledTimers() || _emberMetalRun_loop.default.currentRunLoop) {
50518          return;
50519        }
50520        if (_emberTestingTest.default.waiters && _emberTestingTest.default.waiters.any(function (waiter) {
50521          var context = waiter[0];
50522          var callback = waiter[1];
50523          return !callback.call(context);
50524        })) {
50525          return;
50526        }
50527        // Stop polling
50528        clearInterval(watcher);
50529
50530        // Synchronously resolve the promise
50531        _emberMetalRun_loop.default(null, resolve, value);
50532      }, 10);
50533    });
50534  }
50535
50536  /**
50537    Loads a route, sets up any controllers, and renders any templates associated
50538    with the route as though a real user had triggered the route change while
50539    using your app.
50540  
50541    Example:
50542  
50543    ```javascript
50544    visit('posts/index').then(function() {
50545      // assert something
50546    });
50547    ```
50548  
50549    @method visit
50550    @param {String} url the name of the route
50551    @return {RSVP.Promise}
50552    @public
50553  */
50554  asyncHelper('visit', visit);
50555
50556  /**
50557    Clicks an element and triggers any actions triggered by the element's `click`
50558    event.
50559  
50560    Example:
50561  
50562    ```javascript
50563    click('.some-jQuery-selector').then(function() {
50564      // assert something
50565    });
50566    ```
50567  
50568    @method click
50569    @param {String} selector jQuery selector for finding element on the DOM
50570    @return {RSVP.Promise}
50571    @public
50572  */
50573  asyncHelper('click', click);
50574
50575  /**
50576    Simulates a key event, e.g. `keypress`, `keydown`, `keyup` with the desired keyCode
50577  
50578    Example:
50579  
50580    ```javascript
50581    keyEvent('.some-jQuery-selector', 'keypress', 13).then(function() {
50582     // assert something
50583    });
50584    ```
50585  
50586    @method keyEvent
50587    @param {String} selector jQuery selector for finding element on the DOM
50588    @param {String} type the type of key event, e.g. `keypress`, `keydown`, `keyup`
50589    @param {Number} keyCode the keyCode of the simulated key event
50590    @return {RSVP.Promise}
50591    @since 1.5.0
50592    @public
50593  */
50594  asyncHelper('keyEvent', keyEvent);
50595
50596  /**
50597    Fills in an input element with some text.
50598  
50599    Example:
50600  
50601    ```javascript
50602    fillIn('#email', '[email protected]').then(function() {
50603      // assert something
50604    });
50605    ```
50606  
50607    @method fillIn
50608    @param {String} selector jQuery selector finding an input element on the DOM
50609    to fill text with
50610    @param {String} text text to place inside the input element
50611    @return {RSVP.Promise}
50612    @public
50613  */
50614  asyncHelper('fillIn', fillIn);
50615
50616  /**
50617    Finds an element in the context of the app's container element. A simple alias
50618    for `app.$(selector)`.
50619  
50620    Example:
50621  
50622    ```javascript
50623    var $el = find('.my-selector');
50624    ```
50625  
50626    @method find
50627    @param {String} selector jQuery string selector for element lookup
50628    @return {Object} jQuery object representing the results of the query
50629    @public
50630  */
50631  helper('find', find);
50632
50633  /**
50634    Like `find`, but throws an error if the element selector returns no results.
50635  
50636    Example:
50637  
50638    ```javascript
50639    var $el = findWithAssert('.doesnt-exist'); // throws error
50640    ```
50641  
50642    @method findWithAssert
50643    @param {String} selector jQuery selector string for finding an element within
50644    the DOM
50645    @return {Object} jQuery object representing the results of the query
50646    @throws {Error} throws error if jQuery object returned has a length of 0
50647    @public
50648  */
50649  helper('findWithAssert', findWithAssert);
50650
50651  /**
50652    Causes the run loop to process any pending events. This is used to ensure that
50653    any async operations from other helpers (or your assertions) have been processed.
50654  
50655    This is most often used as the return value for the helper functions (see 'click',
50656    'fillIn','visit',etc).
50657  
50658    Example:
50659  
50660    ```javascript
50661    Ember.Test.registerAsyncHelper('loginUser', function(app, username, password) {
50662      visit('secured/path/here')
50663      .fillIn('#username', username)
50664      .fillIn('#password', password)
50665      .click('.submit')
50666  
50667      return app.testHelpers.wait();
50668    });
50669  
50670    @method wait
50671    @param {Object} value The value to be returned.
50672    @return {RSVP.Promise}
50673    @public
50674  */
50675  asyncHelper('wait', wait);
50676  asyncHelper('andThen', andThen);
50677
50678  /**
50679    Returns the currently active route name.
50680  
50681  Example:
50682  
50683  ```javascript
50684  function validateRouteName() {
50685    equal(currentRouteName(), 'some.path', "correct route was transitioned into.");
50686  }
50687  
50688  visit('/some/path').then(validateRouteName)
50689  ```
50690  
50691  @method currentRouteName
50692  @return {Object} The name of the currently active route.
50693  @since 1.5.0
50694  @public
50695  */
50696  helper('currentRouteName', currentRouteName);
50697
50698  /**
50699    Returns the current path.
50700  
50701  Example:
50702  
50703  ```javascript
50704  function validateURL() {
50705    equal(currentPath(), 'some.path.index', "correct path was transitioned into.");
50706  }
50707  
50708  click('#some-link-id').then(validateURL);
50709  ```
50710  
50711  @method currentPath
50712  @return {Object} The currently active path.
50713  @since 1.5.0
50714  @public
50715  */
50716  helper('currentPath', currentPath);
50717
50718  /**
50719    Returns the current URL.
50720  
50721  Example:
50722  
50723  ```javascript
50724  function validateURL() {
50725    equal(currentURL(), '/some/path', "correct URL was transitioned into.");
50726  }
50727  
50728  click('#some-link-id').then(validateURL);
50729  ```
50730  
50731  @method currentURL
50732  @return {Object} The currently active URL.
50733  @since 1.5.0
50734  @public
50735  */
50736  helper('currentURL', currentURL);
50737
50738  /**
50739   Pauses the current test - this is useful for debugging while testing or for test-driving.
50740   It allows you to inspect the state of your application at any point.
50741  
50742   Example (The test will pause before clicking the button):
50743  
50744   ```javascript
50745   visit('/')
50746   return pauseTest();
50747  
50748   click('.btn');
50749   ```
50750  
50751   @since 1.9.0
50752   @method pauseTest
50753   @return {Object} A promise that will never resolve
50754   @public
50755  */
50756  helper('pauseTest', pauseTest);
50757
50758  /**
50759    Triggers the given DOM event on the element identified by the provided selector.
50760  
50761    Example:
50762  
50763    ```javascript
50764    triggerEvent('#some-elem-id', 'blur');
50765    ```
50766  
50767    This is actually used internally by the `keyEvent` helper like so:
50768  
50769    ```javascript
50770    triggerEvent('#some-elem-id', 'keypress', { keyCode: 13 });
50771    ```
50772  
50773   @method triggerEvent
50774   @param {String} selector jQuery selector for finding element on the DOM
50775   @param {String} [context] jQuery selector that will limit the selector
50776                             argument to find only within the context's children
50777   @param {String} type The event type to be triggered.
50778   @param {Object} [options] The options to be passed to jQuery.Event.
50779   @return {RSVP.Promise}
50780   @since 1.5.0
50781   @public
50782  */
50783  asyncHelper('triggerEvent', triggerEvent);
50784});
50785
50786// Firefox does not trigger the `focusin` event if the window
50787// does not have focus. If the document doesn't have focus just
50788// use trigger('focusin') instead.
50789enifed('ember-testing/index', ['exports', 'ember-metal/core', 'ember-testing/initializers', 'ember-testing/support', 'ember-testing/setup_for_testing', 'ember-testing/test', 'ember-testing/adapters/adapter', 'ember-testing/adapters/qunit', 'ember-testing/helpers'], function (exports, _emberMetalCore, _emberTestingInitializers, _emberTestingSupport, _emberTestingSetup_for_testing, _emberTestingTest, _emberTestingAdaptersAdapter, _emberTestingAdaptersQunit, _emberTestingHelpers) {
50790  'use strict';
50791
50792  // adds helpers to helpers object in Test
50793
50794  /**
50795    @module ember
50796    @submodule ember-testing
50797  */
50798
50799  _emberMetalCore.default.Test = _emberTestingTest.default;
50800  _emberMetalCore.default.Test.Adapter = _emberTestingAdaptersAdapter.default;
50801  _emberMetalCore.default.Test.QUnitAdapter = _emberTestingAdaptersQunit.default;
50802  _emberMetalCore.default.setupForTesting = _emberTestingSetup_for_testing.default;
50803});
50804// to setup initializer
50805// to handle various edge cases
50806enifed('ember-testing/initializers', ['exports', 'ember-runtime/system/lazy_load'], function (exports, _emberRuntimeSystemLazy_load) {
50807  'use strict';
50808
50809  var name = 'deferReadiness in `testing` mode';
50810
50811  _emberRuntimeSystemLazy_load.onLoad('Ember.Application', function (Application) {
50812    if (!Application.initializers[name]) {
50813      Application.initializer({
50814        name: name,
50815
50816        initialize: function (application) {
50817          if (application.testing) {
50818            application.deferReadiness();
50819          }
50820        }
50821      });
50822    }
50823  });
50824});
50825enifed('ember-testing/setup_for_testing', ['exports', 'ember-metal/core', 'ember-testing/adapters/qunit', 'ember-views/system/jquery'], function (exports, _emberMetalCore, _emberTestingAdaptersQunit, _emberViewsSystemJquery) {
50826  'use strict';
50827
50828  exports.default = setupForTesting;
50829
50830  var Test, requests;
50831
50832  function incrementAjaxPendingRequests(_, xhr) {
50833    requests.push(xhr);
50834    Test.pendingAjaxRequests = requests.length;
50835  }
50836
50837  function decrementAjaxPendingRequests(_, xhr) {
50838    for (var i = 0; i < requests.length; i++) {
50839      if (xhr === requests[i]) {
50840        requests.splice(i, 1);
50841      }
50842    }
50843    Test.pendingAjaxRequests = requests.length;
50844  }
50845
50846  /**
50847    Sets Ember up for testing. This is useful to perform
50848    basic setup steps in order to unit test.
50849  
50850    Use `App.setupForTesting` to perform integration tests (full
50851    application testing).
50852  
50853    @method setupForTesting
50854    @namespace Ember
50855    @since 1.5.0
50856    @private
50857  */
50858
50859  function setupForTesting() {
50860    if (!Test) {
50861      Test = requireModule('ember-testing/test')['default'];
50862    }
50863
50864    _emberMetalCore.default.testing = true;
50865
50866    // if adapter is not manually set default to QUnit
50867    if (!Test.adapter) {
50868      Test.adapter = _emberTestingAdaptersQunit.default.create();
50869    }
50870
50871    requests = [];
50872    Test.pendingAjaxRequests = requests.length;
50873
50874    _emberViewsSystemJquery.default(document).off('ajaxSend', incrementAjaxPendingRequests);
50875    _emberViewsSystemJquery.default(document).off('ajaxComplete', decrementAjaxPendingRequests);
50876    _emberViewsSystemJquery.default(document).on('ajaxSend', incrementAjaxPendingRequests);
50877    _emberViewsSystemJquery.default(document).on('ajaxComplete', decrementAjaxPendingRequests);
50878  }
50879});
50880
50881// import Test from "ember-testing/test";  // ES6TODO: fix when cycles are supported
50882enifed('ember-testing/support', ['exports', 'ember-metal/debug', 'ember-views/system/jquery', 'ember-metal/environment'], function (exports, _emberMetalDebug, _emberViewsSystemJquery, _emberMetalEnvironment) {
50883  'use strict';
50884
50885  /**
50886    @module ember
50887    @submodule ember-testing
50888  */
50889
50890  var $ = _emberViewsSystemJquery.default;
50891
50892  /**
50893    This method creates a checkbox and triggers the click event to fire the
50894    passed in handler. It is used to correct for a bug in older versions
50895    of jQuery (e.g 1.8.3).
50896  
50897    @private
50898    @method testCheckboxClick
50899  */
50900  function testCheckboxClick(handler) {
50901    $('<input type="checkbox">').css({ position: 'absolute', left: '-1000px', top: '-1000px' }).appendTo('body').on('click', handler).trigger('click').remove();
50902  }
50903
50904  if (_emberMetalEnvironment.default.hasDOM) {
50905    $(function () {
50906      /*
50907        Determine whether a checkbox checked using jQuery's "click" method will have
50908        the correct value for its checked property.
50909         If we determine that the current jQuery version exhibits this behavior,
50910        patch it to work correctly as in the commit for the actual fix:
50911        https://github.com/jquery/jquery/commit/1fb2f92.
50912      */
50913      testCheckboxClick(function () {
50914        if (!this.checked && !$.event.special.click) {
50915          $.event.special.click = {
50916            // For checkbox, fire native event so checked state will be right
50917            trigger: function () {
50918              if ($.nodeName(this, 'input') && this.type === 'checkbox' && this.click) {
50919                this.click();
50920                return false;
50921              }
50922            }
50923          };
50924        }
50925      });
50926
50927      // Try again to verify that the patch took effect or blow up.
50928      testCheckboxClick(function () {
50929        _emberMetalDebug.warn('clicked checkboxes should be checked! the jQuery patch didn\'t work', this.checked, { id: 'ember-testing.test-checkbox-click' });
50930      });
50931    });
50932  }
50933});
50934enifed('ember-testing/test', ['exports', 'ember-metal/run_loop', 'ember-runtime/ext/rsvp', 'ember-testing/setup_for_testing', 'ember-application/system/application', 'ember-runtime/system/native_array'], function (exports, _emberMetalRun_loop, _emberRuntimeExtRsvp, _emberTestingSetup_for_testing, _emberApplicationSystemApplication, _emberRuntimeSystemNative_array) {
50935  'use strict';
50936
50937  /**
50938    @module ember
50939    @submodule ember-testing
50940  */
50941  var helpers = {};
50942  var injectHelpersCallbacks = [];
50943
50944  /**
50945    This is a container for an assortment of testing related functionality:
50946  
50947    * Choose your default test adapter (for your framework of choice).
50948    * Register/Unregister additional test helpers.
50949    * Setup callbacks to be fired when the test helpers are injected into
50950      your application.
50951  
50952    @class Test
50953    @namespace Ember
50954    @public
50955  */
50956  var Test = {
50957    /**
50958      Hash containing all known test helpers.
50959       @property _helpers
50960      @private
50961      @since 1.7.0
50962    */
50963    _helpers: helpers,
50964
50965    /**
50966      `registerHelper` is used to register a test helper that will be injected
50967      when `App.injectTestHelpers` is called.
50968       The helper method will always be called with the current Application as
50969      the first parameter.
50970       For example:
50971       ```javascript
50972      Ember.Test.registerHelper('boot', function(app) {
50973        Ember.run(app, app.advanceReadiness);
50974      });
50975      ```
50976       This helper can later be called without arguments because it will be
50977      called with `app` as the first parameter.
50978       ```javascript
50979      App = Ember.Application.create();
50980      App.injectTestHelpers();
50981      boot();
50982      ```
50983       @public
50984      @method registerHelper
50985      @param {String} name The name of the helper method to add.
50986      @param {Function} helperMethod
50987      @param options {Object}
50988    */
50989    registerHelper: function (name, helperMethod) {
50990      helpers[name] = {
50991        method: helperMethod,
50992        meta: { wait: false }
50993      };
50994    },
50995
50996    /**
50997      `registerAsyncHelper` is used to register an async test helper that will be injected
50998      when `App.injectTestHelpers` is called.
50999       The helper method will always be called with the current Application as
51000      the first parameter.
51001       For example:
51002       ```javascript
51003      Ember.Test.registerAsyncHelper('boot', function(app) {
51004        Ember.run(app, app.advanceReadiness);
51005      });
51006      ```
51007       The advantage of an async helper is that it will not run
51008      until the last async helper has completed.  All async helpers
51009      after it will wait for it complete before running.
51010        For example:
51011       ```javascript
51012      Ember.Test.registerAsyncHelper('deletePost', function(app, postId) {
51013        click('.delete-' + postId);
51014      });
51015       // ... in your test
51016      visit('/post/2');
51017      deletePost(2);
51018      visit('/post/3');
51019      deletePost(3);
51020      ```
51021       @public
51022      @method registerAsyncHelper
51023      @param {String} name The name of the helper method to add.
51024      @param {Function} helperMethod
51025      @since 1.2.0
51026    */
51027    registerAsyncHelper: function (name, helperMethod) {
51028      helpers[name] = {
51029        method: helperMethod,
51030        meta: { wait: true }
51031      };
51032    },
51033
51034    /**
51035      Remove a previously added helper method.
51036       Example:
51037       ```javascript
51038      Ember.Test.unregisterHelper('wait');
51039      ```
51040       @public
51041      @method unregisterHelper
51042      @param {String} name The helper to remove.
51043    */
51044    unregisterHelper: function (name) {
51045      delete helpers[name];
51046      delete Test.Promise.prototype[name];
51047    },
51048
51049    /**
51050      Used to register callbacks to be fired whenever `App.injectTestHelpers`
51051      is called.
51052       The callback will receive the current application as an argument.
51053       Example:
51054       ```javascript
51055      Ember.Test.onInjectHelpers(function() {
51056        Ember.$(document).ajaxSend(function() {
51057          Test.pendingAjaxRequests++;
51058        });
51059         Ember.$(document).ajaxComplete(function() {
51060          Test.pendingAjaxRequests--;
51061        });
51062      });
51063      ```
51064       @public
51065      @method onInjectHelpers
51066      @param {Function} callback The function to be called.
51067    */
51068    onInjectHelpers: function (callback) {
51069      injectHelpersCallbacks.push(callback);
51070    },
51071
51072    /**
51073      This returns a thenable tailored for testing.  It catches failed
51074      `onSuccess` callbacks and invokes the `Ember.Test.adapter.exception`
51075      callback in the last chained then.
51076       This method should be returned by async helpers such as `wait`.
51077       @public
51078      @method promise
51079      @param {Function} resolver The function used to resolve the promise.
51080      @param {String} label An optional string for identifying the promise.
51081    */
51082    promise: function (resolver, label) {
51083      var fullLabel = 'Ember.Test.promise: ' + (label || '<Unknown Promise>');
51084      return new Test.Promise(resolver, fullLabel);
51085    },
51086
51087    /**
51088     Used to allow ember-testing to communicate with a specific testing
51089     framework.
51090      You can manually set it before calling `App.setupForTesting()`.
51091      Example:
51092      ```javascript
51093     Ember.Test.adapter = MyCustomAdapter.create()
51094     ```
51095      If you do not set it, ember-testing will default to `Ember.Test.QUnitAdapter`.
51096      @public
51097     @property adapter
51098     @type {Class} The adapter to be used.
51099     @default Ember.Test.QUnitAdapter
51100    */
51101    adapter: null,
51102
51103    /**
51104      Replacement for `Ember.RSVP.resolve`
51105      The only difference is this uses
51106      an instance of `Ember.Test.Promise`
51107       @public
51108      @method resolve
51109      @param {Mixed} The value to resolve
51110      @since 1.2.0
51111    */
51112    resolve: function (val) {
51113      return Test.promise(function (resolve) {
51114        return resolve(val);
51115      });
51116    },
51117
51118    /**
51119       This allows ember-testing to play nicely with other asynchronous
51120       events, such as an application that is waiting for a CSS3
51121       transition or an IndexDB transaction.
51122        For example:
51123        ```javascript
51124       Ember.Test.registerWaiter(function() {
51125         return myPendingTransactions() == 0;
51126       });
51127       ```
51128       The `context` argument allows you to optionally specify the `this`
51129       with which your callback will be invoked.
51130        For example:
51131        ```javascript
51132       Ember.Test.registerWaiter(MyDB, MyDB.hasPendingTransactions);
51133       ```
51134        @public
51135       @method registerWaiter
51136       @param {Object} context (optional)
51137       @param {Function} callback
51138       @since 1.2.0
51139    */
51140    registerWaiter: function (context, callback) {
51141      if (arguments.length === 1) {
51142        callback = context;
51143        context = null;
51144      }
51145      if (!this.waiters) {
51146        this.waiters = _emberRuntimeSystemNative_array.A();
51147      }
51148      this.waiters.push([context, callback]);
51149    },
51150    /**
51151       `unregisterWaiter` is used to unregister a callback that was
51152       registered with `registerWaiter`.
51153        @public
51154       @method unregisterWaiter
51155       @param {Object} context (optional)
51156       @param {Function} callback
51157       @since 1.2.0
51158    */
51159    unregisterWaiter: function (context, callback) {
51160      if (!this.waiters) {
51161        return;
51162      }
51163      if (arguments.length === 1) {
51164        callback = context;
51165        context = null;
51166      }
51167      this.waiters = _emberRuntimeSystemNative_array.A(this.waiters.filter(function (elt) {
51168        return !(elt[0] === context && elt[1] === callback);
51169      }));
51170    }
51171  };
51172
51173  function helper(app, name) {
51174    var fn = helpers[name].method;
51175    var meta = helpers[name].meta;
51176
51177    return function () {
51178      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
51179        args[_key] = arguments[_key];
51180      }
51181
51182      var lastPromise;
51183
51184      args.unshift(app);
51185
51186      // some helpers are not async and
51187      // need to return a value immediately.
51188      // example: `find`
51189      if (!meta.wait) {
51190        return fn.apply(app, args);
51191      }
51192
51193      lastPromise = run(function () {
51194        return Test.resolve(Test.lastPromise);
51195      });
51196
51197      // wait for last helper's promise to resolve and then
51198      // execute. To be safe, we need to tell the adapter we're going
51199      // asynchronous here, because fn may not be invoked before we
51200      // return.
51201      Test.adapter.asyncStart();
51202      return lastPromise.then(function () {
51203        return fn.apply(app, args);
51204      }).finally(function () {
51205        Test.adapter.asyncEnd();
51206      });
51207    };
51208  }
51209
51210  function run(fn) {
51211    if (!_emberMetalRun_loop.default.currentRunLoop) {
51212      return _emberMetalRun_loop.default(fn);
51213    } else {
51214      return fn();
51215    }
51216  }
51217
51218  _emberApplicationSystemApplication.default.reopen({
51219    /**
51220     This property contains the testing helpers for the current application. These
51221     are created once you call `injectTestHelpers` on your `Ember.Application`
51222     instance. The included helpers are also available on the `window` object by
51223     default, but can be used from this object on the individual application also.
51224       @property testHelpers
51225      @type {Object}
51226      @default {}
51227      @public
51228    */
51229    testHelpers: {},
51230
51231    /**
51232     This property will contain the original methods that were registered
51233     on the `helperContainer` before `injectTestHelpers` is called.
51234      When `removeTestHelpers` is called, these methods are restored to the
51235     `helperContainer`.
51236       @property originalMethods
51237      @type {Object}
51238      @default {}
51239      @private
51240      @since 1.3.0
51241    */
51242    originalMethods: {},
51243
51244    /**
51245    This property indicates whether or not this application is currently in
51246    testing mode. This is set when `setupForTesting` is called on the current
51247    application.
51248     @property testing
51249    @type {Boolean}
51250    @default false
51251    @since 1.3.0
51252    @public
51253    */
51254    testing: false,
51255
51256    /**
51257      This hook defers the readiness of the application, so that you can start
51258      the app when your tests are ready to run. It also sets the router's
51259      location to 'none', so that the window's location will not be modified
51260      (preventing both accidental leaking of state between tests and interference
51261      with your testing framework).
51262       Example:
51263       ```
51264      App.setupForTesting();
51265      ```
51266       @method setupForTesting
51267      @public
51268    */
51269    setupForTesting: function () {
51270      _emberTestingSetup_for_testing.default();
51271
51272      this.testing = true;
51273
51274      this.Router.reopen({
51275        location: 'none'
51276      });
51277    },
51278
51279    /**
51280      This will be used as the container to inject the test helpers into. By
51281      default the helpers are injected into `window`.
51282       @property helperContainer
51283      @type {Object} The object to be used for test helpers.
51284      @default window
51285      @since 1.2.0
51286      @private
51287    */
51288    helperContainer: null,
51289
51290    /**
51291      This injects the test helpers into the `helperContainer` object. If an object is provided
51292      it will be used as the helperContainer. If `helperContainer` is not set it will default
51293      to `window`. If a function of the same name has already been defined it will be cached
51294      (so that it can be reset if the helper is removed with `unregisterHelper` or
51295      `removeTestHelpers`).
51296       Any callbacks registered with `onInjectHelpers` will be called once the
51297      helpers have been injected.
51298       Example:
51299      ```
51300      App.injectTestHelpers();
51301      ```
51302       @method injectTestHelpers
51303      @public
51304    */
51305    injectTestHelpers: function (helperContainer) {
51306      if (helperContainer) {
51307        this.helperContainer = helperContainer;
51308      } else {
51309        this.helperContainer = window;
51310      }
51311
51312      this.reopen({
51313        willDestroy: function () {
51314          this._super.apply(this, arguments);
51315          this.removeTestHelpers();
51316        }
51317      });
51318
51319      this.testHelpers = {};
51320      for (var name in helpers) {
51321        this.originalMethods[name] = this.helperContainer[name];
51322        this.testHelpers[name] = this.helperContainer[name] = helper(this, name);
51323        protoWrap(Test.Promise.prototype, name, helper(this, name), helpers[name].meta.wait);
51324      }
51325
51326      for (var i = 0, l = injectHelpersCallbacks.length; i < l; i++) {
51327        injectHelpersCallbacks[i](this);
51328      }
51329    },
51330
51331    /**
51332      This removes all helpers that have been registered, and resets and functions
51333      that were overridden by the helpers.
51334       Example:
51335       ```javascript
51336      App.removeTestHelpers();
51337      ```
51338       @public
51339      @method removeTestHelpers
51340    */
51341    removeTestHelpers: function () {
51342      if (!this.helperContainer) {
51343        return;
51344      }
51345
51346      for (var name in helpers) {
51347        this.helperContainer[name] = this.originalMethods[name];
51348        delete Test.Promise.prototype[name];
51349        delete this.testHelpers[name];
51350        delete this.originalMethods[name];
51351      }
51352    }
51353  });
51354
51355  // This method is no longer needed
51356  // But still here for backwards compatibility
51357  // of helper chaining
51358  function protoWrap(proto, name, callback, isAsync) {
51359    proto[name] = function () {
51360      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
51361        args[_key2] = arguments[_key2];
51362      }
51363
51364      if (isAsync) {
51365        return callback.apply(this, args);
51366      } else {
51367        return this.then(function () {
51368          return callback.apply(this, args);
51369        });
51370      }
51371    };
51372  }
51373
51374  Test.Promise = function () {
51375    _emberRuntimeExtRsvp.default.Promise.apply(this, arguments);
51376    Test.lastPromise = this;
51377  };
51378
51379  Test.Promise.prototype = Object.create(_emberRuntimeExtRsvp.default.Promise.prototype);
51380  Test.Promise.prototype.constructor = Test.Promise;
51381  Test.Promise.resolve = Test.resolve;
51382
51383  // Patch `then` to isolate async methods
51384  // specifically `Ember.Test.lastPromise`
51385  var originalThen = _emberRuntimeExtRsvp.default.Promise.prototype.then;
51386  Test.Promise.prototype.then = function (onSuccess, onFailure) {
51387    return originalThen.call(this, function (val) {
51388      return isolate(onSuccess, val);
51389    }, onFailure);
51390  };
51391
51392  // This method isolates nested async methods
51393  // so that they don't conflict with other last promises.
51394  //
51395  // 1. Set `Ember.Test.lastPromise` to null
51396  // 2. Invoke method
51397  // 3. Return the last promise created during method
51398  function isolate(fn, val) {
51399    var value, lastPromise;
51400
51401    // Reset lastPromise for nested helpers
51402    Test.lastPromise = null;
51403
51404    value = fn(val);
51405
51406    lastPromise = Test.lastPromise;
51407    Test.lastPromise = null;
51408
51409    // If the method returned a promise
51410    // return that promise. If not,
51411    // return the last async helper's promise
51412    if (value && value instanceof Test.Promise || !lastPromise) {
51413      return value;
51414    } else {
51415      return run(function () {
51416        return Test.resolve(lastPromise).then(function () {
51417          return value;
51418        });
51419      });
51420    }
51421  }
51422
51423  exports.default = Test;
51424});
51425enifed('ember-views/compat/attrs-proxy', ['exports', 'ember-metal/mixin', 'ember-metal/symbol', 'ember-metal/property_events'], function (exports, _emberMetalMixin, _emberMetalSymbol, _emberMetalProperty_events) {
51426  'use strict';
51427
51428  exports.deprecation = deprecation;
51429
51430  function deprecation(key) {
51431    return 'You tried to look up an attribute directly on the component. This is deprecated. Use attrs.' + key + ' instead.';
51432  }
51433
51434  var MUTABLE_CELL = _emberMetalSymbol.default('MUTABLE_CELL');
51435
51436  exports.MUTABLE_CELL = MUTABLE_CELL;
51437  function isCell(val) {
51438    return val && val[MUTABLE_CELL];
51439  }
51440
51441  var AttrsProxyMixin = {
51442    attrs: null,
51443
51444    getAttr: function (key) {
51445      var attrs = this.attrs;
51446      if (!attrs) {
51447        return;
51448      }
51449      return this.getAttrFor(attrs, key);
51450    },
51451
51452    getAttrFor: function (attrs, key) {
51453      var val = attrs[key];
51454      return isCell(val) ? val.value : val;
51455    },
51456
51457    setAttr: function (key, value) {
51458      var attrs = this.attrs;
51459      var val = attrs[key];
51460
51461      if (!isCell(val)) {
51462        throw new Error('You can\'t update attrs.' + key + ', because it\'s not mutable');
51463      }
51464
51465      val.update(value);
51466    },
51467
51468    _propagateAttrsToThis: function (attrs) {
51469      this._isDispatchingAttrs = true;
51470      this.setProperties(attrs);
51471      this._isDispatchingAttrs = false;
51472    }
51473  };
51474
51475  AttrsProxyMixin[_emberMetalProperty_events.PROPERTY_DID_CHANGE] = function (key) {
51476    if (this._isAngleBracket) {
51477      return;
51478    }
51479    if (this._isDispatchingAttrs) {
51480      return;
51481    }
51482
51483    if (this._currentState) {
51484      this._currentState.legacyPropertyDidChange(this, key);
51485    }
51486  };
51487
51488  exports.default = _emberMetalMixin.Mixin.create(AttrsProxyMixin);
51489});
51490enifed('ember-views/compat/metamorph_view', ['exports', 'ember-metal/debug', 'ember-views/views/view', 'ember-metal/mixin'], function (exports, _emberMetalDebug, _emberViewsViewsView, _emberMetalMixin) {
51491  'use strict';
51492
51493  /**
51494   @module ember
51495   @submodule ember-views
51496  */
51497
51498  // The `morph` and `outerHTML` properties are internal only
51499  // and not observable.
51500
51501  /**
51502   @class _Metamorph
51503   @namespace Ember
51504   @private
51505  */
51506  var _Metamorph = _emberMetalMixin.Mixin.create({
51507    tagName: '',
51508    __metamorphType: 'Ember._Metamorph',
51509
51510    instrumentName: 'metamorph',
51511
51512    init: function () {
51513      this._super.apply(this, arguments);
51514      _emberMetalDebug.deprecate('Supplying a tagName to Metamorph views is unreliable and is deprecated. ' + 'You may be setting the tagName on a Handlebars helper that creates a Metamorph.', !this.tagName, { id: 'ember-views.metamorph-tag-name', until: '2.4.0' });
51515
51516      _emberMetalDebug.deprecate('Using ' + this.__metamorphType + ' is deprecated.', false, { id: 'ember-views.metamorph', until: '2.4.0' });
51517    }
51518  });
51519
51520  exports._Metamorph = _Metamorph;
51521  /**
51522   @class _MetamorphView
51523   @namespace Ember
51524   @extends Ember.View
51525   @uses Ember._Metamorph
51526   @private
51527  */
51528  exports.default = _emberViewsViewsView.default.extend(_Metamorph, {
51529    __metamorphType: 'Ember._MetamorphView'
51530  });
51531});
51532enifed('ember-views/component_lookup', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-runtime/system/object', 'ember-htmlbars/system/lookup-helper', 'container/owner'], function (exports, _emberMetalCore, _emberMetalDebug, _emberRuntimeSystemObject, _emberHtmlbarsSystemLookupHelper, _containerOwner) {
51533  'use strict';
51534
51535  exports.default = _emberRuntimeSystemObject.default.extend({
51536    invalidName: function (name) {
51537      if (!_emberHtmlbarsSystemLookupHelper.CONTAINS_DASH_CACHE.get(name)) {
51538        _emberMetalDebug.assert('You cannot use \'' + name + '\' as a component name. Component names must contain a hyphen.');
51539        return true;
51540      }
51541    },
51542
51543    lookupFactory: function (name, owner) {
51544      owner = owner || _containerOwner.getOwner(this);
51545
51546      var fullName = 'component:' + name;
51547      var templateFullName = 'template:components/' + name;
51548      var templateRegistered = owner && owner.hasRegistration(templateFullName);
51549
51550      if (templateRegistered) {
51551        owner.inject(fullName, 'layout', templateFullName);
51552      }
51553
51554      var Component = owner._lookupFactory(fullName);
51555
51556      // Only treat as a component if either the component
51557      // or a template has been registered.
51558      if (templateRegistered || Component) {
51559        if (!Component) {
51560          owner.register(fullName, _emberMetalCore.default.Component);
51561          Component = owner._lookupFactory(fullName);
51562        }
51563        return Component;
51564      }
51565    },
51566
51567    componentFor: function (name, owner, options) {
51568      if (this.invalidName(name)) {
51569        return;
51570      }
51571
51572      var fullName = 'component:' + name;
51573      return owner._lookupFactory(fullName, options);
51574    },
51575
51576    layoutFor: function (name, owner, options) {
51577      if (this.invalidName(name)) {
51578        return;
51579      }
51580
51581      var templateFullName = 'template:components/' + name;
51582      return owner.lookup(templateFullName, options);
51583    }
51584  });
51585});
51586enifed('ember-views/components/component', ['exports', 'ember-metal/debug', 'ember-metal/environment', 'ember-runtime/mixins/target_action_support', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/utils', 'ember-metal/computed', 'ember-views/compat/attrs-proxy', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalEnvironment, _emberRuntimeMixinsTarget_action_support, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalUtils, _emberMetalComputed, _emberViewsCompatAttrsProxy, _containerOwner) {
51587  'use strict';
51588
51589  function validateAction(component, actionName) {
51590    if (actionName && actionName[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) {
51591      actionName = actionName.value;
51592    }
51593    _emberMetalDebug.assert('The default action was triggered on the component ' + component.toString() + ', but the action name (' + actionName + ') was not a string.', _emberMetalIs_none.default(actionName) || typeof actionName === 'string' || typeof actionName === 'function');
51594    return actionName;
51595  }
51596
51597  /**
51598  @module ember
51599  @submodule ember-views
51600  */
51601
51602  /**
51603    An `Ember.Component` is a view that is completely
51604    isolated. Properties accessed in its templates go
51605    to the view object and actions are targeted at
51606    the view object. There is no access to the
51607    surrounding context or outer controller; all
51608    contextual information must be passed in.
51609  
51610    The easiest way to create an `Ember.Component` is via
51611    a template. If you name a template
51612    `components/my-foo`, you will be able to use
51613    `{{my-foo}}` in other templates, which will make
51614    an instance of the isolated component.
51615  
51616    ```handlebars
51617    {{app-profile person=currentUser}}
51618    ```
51619  
51620    ```handlebars
51621    <!-- app-profile template -->
51622    <h1>{{person.title}}</h1>
51623    <img src={{person.avatar}}>
51624    <p class='signature'>{{person.signature}}</p>
51625    ```
51626  
51627    You can use `yield` inside a template to
51628    include the **contents** of any block attached to
51629    the component. The block will be executed in the
51630    context of the surrounding context or outer controller:
51631  
51632    ```handlebars
51633    {{#app-profile person=currentUser}}
51634      <p>Admin mode</p>
51635      {{! Executed in the controller's context. }}
51636    {{/app-profile}}
51637    ```
51638  
51639    ```handlebars
51640    <!-- app-profile template -->
51641    <h1>{{person.title}}</h1>
51642    {{! Executed in the components context. }}
51643    {{yield}} {{! block contents }}
51644    ```
51645  
51646    If you want to customize the component, in order to
51647    handle events or actions, you implement a subclass
51648    of `Ember.Component` named after the name of the
51649    component. Note that `Component` needs to be appended to the name of
51650    your subclass like `AppProfileComponent`.
51651  
51652    For example, you could implement the action
51653    `hello` for the `app-profile` component:
51654  
51655    ```javascript
51656    App.AppProfileComponent = Ember.Component.extend({
51657      actions: {
51658        hello: function(name) {
51659          console.log("Hello", name);
51660        }
51661      }
51662    });
51663    ```
51664  
51665    And then use it in the component's template:
51666  
51667    ```handlebars
51668    <!-- app-profile template -->
51669  
51670    <h1>{{person.title}}</h1>
51671    {{yield}} <!-- block contents -->
51672  
51673    <button {{action 'hello' person.name}}>
51674      Say Hello to {{person.name}}
51675    </button>
51676    ```
51677  
51678    Components must have a `-` in their name to avoid
51679    conflicts with built-in controls that wrap HTML
51680    elements. This is consistent with the same
51681    requirement in web components.
51682  
51683    @class Component
51684    @namespace Ember
51685    @extends Ember.View
51686    @uses Ember.ViewTargetActionSupport
51687    @public
51688  */
51689  var Component = _emberViewsViewsView.default.extend(_emberRuntimeMixinsTarget_action_support.default, {
51690    isComponent: true,
51691    /*
51692      This is set so that the proto inspection in appendTemplatedView does not
51693      think that it should set the components `context` to that of the parent view.
51694    */
51695    controller: null,
51696    context: null,
51697
51698    instrumentName: 'component',
51699    instrumentDisplay: _emberMetalComputed.computed(function () {
51700      if (this._debugContainerKey) {
51701        return '{{' + this._debugContainerKey.split(':')[1] + '}}';
51702      }
51703    }),
51704
51705    init: function () {
51706      var _this = this;
51707
51708      this._super.apply(this, arguments);
51709      _emberMetalProperty_set.set(this, 'controller', this);
51710      _emberMetalProperty_set.set(this, 'context', this);
51711
51712      if (!this.layout && this.layoutName && _containerOwner.getOwner(this)) {
51713        var layoutName = _emberMetalProperty_get.get(this, 'layoutName');
51714
51715        this.layout = this.templateForName(layoutName);
51716      }
51717
51718      // If a `defaultLayout` was specified move it to the `layout` prop.
51719      // `layout` is no longer a CP, so this just ensures that the `defaultLayout`
51720      // logic is supported with a deprecation
51721      if (this.defaultLayout && !this.layout) {
51722        _emberMetalDebug.deprecate('Specifying `defaultLayout` to ' + this + ' is deprecated. Please use `layout` instead.', false, {
51723          id: 'ember-views.component.defaultLayout',
51724          until: '3.0.0',
51725          url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-component-defaultlayout'
51726        });
51727
51728        this.layout = this.defaultLayout;
51729      }
51730
51731      // If in a tagless component, assert that no event handlers are defined
51732      _emberMetalDebug.assert('You can not define a function that handles DOM events in the `' + this + '` tagless component since it doesn\'t have any DOM element.', this.tagName !== '' || !_emberMetalEnvironment.default.hasDOM || !(function () {
51733        var eventDispatcher = _containerOwner.getOwner(_this).lookup('event_dispatcher:main');
51734        var events = eventDispatcher && eventDispatcher._finalEvents || {};
51735
51736        for (var key in events) {
51737          var methodName = events[key];
51738
51739          if (typeof _this[methodName] === 'function') {
51740            return true; // indicate that the assertion should be triggered
51741          }
51742        }
51743      })());
51744    },
51745
51746    template: null,
51747    layoutName: null,
51748    layout: null,
51749
51750    /**
51751      If the component is currently inserted into the DOM of a parent view, this
51752      property will point to the controller of the parent view.
51753       @property targetObject
51754      @type Ember.Controller
51755      @default null
51756      @private
51757    */
51758    targetObject: _emberMetalComputed.computed('controller', function (key) {
51759      if (this._targetObject) {
51760        return this._targetObject;
51761      }
51762      if (this._controller) {
51763        return this._controller;
51764      }
51765      var parentView = _emberMetalProperty_get.get(this, 'parentView');
51766      return parentView ? _emberMetalProperty_get.get(parentView, 'controller') : null;
51767    }),
51768
51769    /**
51770      Calls a action passed to a component.
51771       For example a component for playing or pausing music may translate click events
51772      into action notifications of "play" or "stop" depending on some internal state
51773      of the component:
51774       ```javascript
51775      
51775// app/components/play-button.js
51776      export default Ember.Component.extend({
51777        click() {
51778          if (this.get('isPlaying')) {
51779            this.sendAction('play');
51780          } else {
51781            this.sendAction('stop');
51782          }
51783        }
51784      });
51785      ```
51786       The actions "play" and "stop" must be passed to this `play-button` component:
51787       ```handlebars
51788      {{! app/templates/application.hbs }}
51789      {{play-button play=(action "musicStarted") stop=(action "musicStopped")}}
51790      ```
51791       When the component receives a browser `click` event it translate this
51792      interaction into application-specific semantics ("play" or "stop") and
51793      calls the specified action.
51794       ```javascript
51795      
51795// app/controller/application.js
51796      export default Ember.Controller.extend({
51797        actions: {
51798          musicStarted() {
51799            // called when the play button is clicked
51800            // and the music started playing
51801          },
51802          musicStopped() {
51803            // called when the play button is clicked
51804            // and the music stopped playing
51805          }
51806        }
51807      });
51808      ```
51809       If no action is passed to `sendAction` a default name of "action"
51810      is assumed.
51811       ```javascript
51812      
51812// app/components/next-button.js
51813      export default Ember.Component.extend({
51814        click() {
51815          this.sendAction();
51816        }
51817      });
51818      ```
51819       ```handlebars
51820      {{! app/templates/application.hbs }}
51821      {{next-button action=(action "playNextSongInAlbum")}}
51822      ```
51823       ```javascript
51824      
51824// app/controllers/application.js
51825      App.ApplicationController = Ember.Controller.extend({
51826        actions: {
51827          playNextSongInAlbum() {
51828            ...
51829          }
51830        }
51831      });
51832      ```
51833       @method sendAction
51834      @param [action] {String} the action to call
51835      @param [params] {*} arguments for the action
51836      @public
51837    */
51838    sendAction: function (action) {
51839      for (var _len = arguments.length, contexts = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
51840        contexts[_key - 1] = arguments[_key];
51841      }
51842
51843      var actionName;
51844
51845      // Send the default action
51846      if (action === undefined) {
51847        action = 'action';
51848      }
51849      actionName = _emberMetalProperty_get.get(this, 'attrs.' + action) || _emberMetalProperty_get.get(this, action);
51850      actionName = validateAction(this, actionName);
51851
51852      // If no action name for that action could be found, just abort.
51853      if (actionName === undefined) {
51854        return;
51855      }
51856
51857      if (typeof actionName === 'function') {
51858        actionName.apply(undefined, contexts);
51859      } else {
51860        this.triggerAction({
51861          action: actionName,
51862          actionContext: contexts
51863        });
51864      }
51865    },
51866
51867    send: function (actionName) {
51868      for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
51869        args[_key2 - 1] = arguments[_key2];
51870      }
51871
51872      var target;
51873      var action = this.actions && this.actions[actionName];
51874
51875      if (action) {
51876        var shouldBubble = action.apply(this, args) === true;
51877        if (!shouldBubble) {
51878          return;
51879        }
51880      }
51881
51882      if (target = _emberMetalProperty_get.get(this, 'target')) {
51883        var _target;
51884
51885        _emberMetalDebug.assert('The `target` for ' + this + ' (' + target + ') does not have a `send` method', typeof target.send === 'function');
51886        (_target = target).send.apply(_target, arguments);
51887      } else {
51888        if (!action) {
51889          throw new Error(_emberMetalUtils.inspect(this) + ' had no action handler for: ' + actionName);
51890        }
51891      }
51892    }
51893
51894    /**
51895      Returns true when the component was invoked with a block template.
51896       Example (`hasBlock` will be `false`):
51897       ```hbs
51898      {{! templates/application.hbs }}
51899       {{foo-bar}}
51900       {{! templates/components/foo-bar.hbs }}
51901      {{#if hasBlock}}
51902        This will not be printed, because no block was provided
51903      {{/if}}
51904      ```
51905       Example (`hasBlock` will be `true`):
51906       ```hbs
51907      {{! templates/application.hbs }}
51908       {{#foo-bar}}
51909        Hi!
51910      {{/foo-bar}}
51911       {{! templates/components/foo-bar.hbs }}
51912      {{#if hasBlock}}
51913        This will be printed because a block was provided
51914        {{yield}}
51915      {{/if}}
51916      ```
51917       This helper accepts an argument with the name of the block we want to check the presence of.
51918      This is useful for checking for the presence of the optional inverse block in components.
51919       ```hbs
51920      {{! templates/application.hbs }}
51921       {{#foo-bar}}
51922        Hi!
51923      {{else}}
51924        What's up?
51925      {{/foo-bar}}
51926       {{! templates/components/foo-bar.hbs }}
51927      {{yield}}
51928      {{#if (hasBlock "inverse")}}
51929        {{yield to="inverse"}}
51930      {{else}}
51931        How are you?
51932      {{/if}}
51933      ```
51934       @public
51935      @property hasBlock
51936      @param {String} [blockName="default"] The name of the block to check presence of.
51937      @returns Boolean
51938      @since 1.13.0
51939    */
51940
51941    /**
51942      Returns true when the component was invoked with a block parameter
51943      supplied.
51944       Example (`hasBlockParams` will be `false`):
51945       ```hbs
51946      {{! templates/application.hbs }}
51947       {{#foo-bar}}
51948        No block parameter.
51949      {{/foo-bar}}
51950       {{! templates/components/foo-bar.hbs }}
51951      {{#if hasBlockParams}}
51952        This will not be printed, because no block was provided
51953        {{yield this}}
51954      {{/if}}
51955      ```
51956       Example (`hasBlockParams` will be `true`):
51957       ```hbs
51958      {{! templates/application.hbs }}
51959       {{#foo-bar as |foo|}}
51960        Hi!
51961      {{/foo-bar}}
51962       {{! templates/components/foo-bar.hbs }}
51963      {{#if hasBlockParams}}
51964        This will be printed because a block was provided
51965        {{yield this}}
51966      {{/if}}
51967      ```
51968      @public
51969      @property hasBlockParams
51970      @returns Boolean
51971      @since 1.13.0
51972    */
51973
51974    /**
51975      Enables components to take a list of parameters as arguments
51976       For example a component that takes two parameters with the names
51977      `name` and `age`:
51978       ```javascript
51979      let MyComponent = Ember.Component.extend;
51980      MyComponent.reopenClass({
51981        positionalParams: ['name', 'age']
51982      });
51983      ```
51984       It can then be invoked like this:
51985       ```hbs
51986      {{my-component "John" 38}}
51987      ```
51988       The parameters can be refered to just like named parameters:
51989       ```hbs
51990      Name: {{attrs.name}}, Age: {{attrs.age}}.
51991      ```
51992       Using a string instead of an array allows for an arbitrary number of
51993      parameters:
51994       ```javascript
51995      let MyComponent = Ember.Component.extend;
51996      MyComponent.reopenClass({
51997        positionalParams: 'names'
51998      });
51999      ```
52000       It can then be invoked like this:
52001       ```hbs
52002      {{my-component "John" "Michael" "Scott"}}
52003      ```
52004       The parameters can then be refered to by enumerating over the list:
52005       ```hbs
52006      {{#each attrs.names as |name|}}{{name}}{{/each}}
52007      ```
52008       @static
52009      @public
52010      @property positionalParams
52011      @since 1.13.0
52012    */
52013
52014    /**
52015      Called when the attributes passed into the component have been updated.
52016      Called both during the initial render of a container and during a rerender.
52017      Can be used in place of an observer; code placed here will be executed
52018      every time any attribute updates.
52019       @method didReceiveAttrs
52020      @public
52021      @since 1.13.0
52022    */
52023
52024    /**
52025      Called when the attributes passed into the component have been updated.
52026      Called both during the initial render of a container and during a rerender.
52027      Can be used in place of an observer; code placed here will be executed
52028      every time any attribute updates.
52029       @event didReceiveAttrs
52030      @public
52031      @since 1.13.0
52032    */
52033
52034    /**
52035      Called after a component has been rendered, both on initial render and
52036      in subsequent rerenders.
52037       @method didRender
52038      @public
52039      @since 1.13.0
52040    */
52041
52042    /**
52043      Called after a component has been rendered, both on initial render and
52044      in subsequent rerenders.
52045       @event didRender
52046      @public
52047      @since 1.13.0
52048    */
52049
52050    /**
52051      Called before a component has been rendered, both on initial render and
52052      in subsequent rerenders.
52053       @method willRender
52054      @public
52055      @since 1.13.0
52056    */
52057
52058    /**
52059      Called before a component has been rendered, both on initial render and
52060      in subsequent rerenders.
52061       @event willRender
52062      @public
52063      @since 1.13.0
52064    */
52065
52066    /**
52067      Called when the attributes passed into the component have been changed.
52068      Called only during a rerender, not during an initial render.
52069       @method didUpdateAttrs
52070      @public
52071      @since 1.13.0
52072    */
52073
52074    /**
52075      Called when the attributes passed into the component have been changed.
52076      Called only during a rerender, not during an initial render.
52077       @event didUpdateAttrs
52078      @public
52079      @since 1.13.0
52080    */
52081
52082    /**
52083      Called when the component is about to update and rerender itself.
52084      Called only during a rerender, not during an initial render.
52085       @method willUpdate
52086      @public
52087      @since 1.13.0
52088    */
52089
52090    /**
52091      Called when the component is about to update and rerender itself.
52092      Called only during a rerender, not during an initial render.
52093       @event willUpdate
52094      @public
52095      @since 1.13.0
52096    */
52097
52098    /**
52099      Called when the component has updated and rerendered itself.
52100      Called only during a rerender, not during an initial render.
52101       @event didUpdate
52102      @public
52103      @since 1.13.0
52104    */
52105
52106    /**
52107      Called when the component has updated and rerendered itself.
52108      Called only during a rerender, not during an initial render.
52109       @event didUpdate
52110      @public
52111      @since 1.13.0
52112    */
52113  });
52114
52115  Component.reopenClass({
52116    isComponentFactory: true
52117  });
52118
52119  exports.default = Component;
52120});
52121enifed('ember-views/index', ['exports', 'ember-runtime', 'ember-views/system/jquery', 'ember-views/system/utils', 'ember-views/system/ext', 'ember-views/views/states', 'ember-metal-views', 'ember-views/views/core_view', 'ember-views/views/view', 'ember-views/views/container_view', 'ember-views/views/collection_view', 'ember-views/components/component', 'ember-views/system/event_dispatcher', 'ember-views/mixins/view_target_action_support', 'ember-views/component_lookup', 'ember-views/views/checkbox', 'ember-views/mixins/text_support', 'ember-views/views/text_field', 'ember-views/views/text_area', 'ember-views/views/select', 'ember-views/compat/metamorph_view', 'ember-views/views/legacy_each_view'], function (exports, _emberRuntime, _emberViewsSystemJquery, _emberViewsSystemUtils, _emberViewsSystemExt, _emberViewsViewsStates, _emberMetalViews, _emberViewsViewsCore_view, _emberViewsViewsView, _emberViewsViewsContainer_view, _emberViewsViewsCollection_view, _emberViewsComponentsComponent, _emberViewsSystemEvent_dispatcher, _emberViewsMixinsView_target_action_support, _emberViewsComponent_lookup, _emberViewsViewsCheckbox, _emberViewsMixinsText_support, _emberViewsViewsText_field, _emberViewsViewsText_area, _emberViewsViewsSelect, _emberViewsCompatMetamorph_view, _emberViewsViewsLegacy_each_view) {
52122  /**
52123  @module ember
52124  @submodule ember-views
52125  */
52126
52127  // BEGIN IMPORTS
52128  'use strict';
52129
52130  // END IMPORTS
52131
52132  /**
52133    Alias for jQuery
52134  
52135    @method $
52136    @for Ember
52137   @public
52138  */
52139
52140  // BEGIN EXPORTS
52141  _emberRuntime.default.$ = _emberViewsSystemJquery.default;
52142
52143  _emberRuntime.default.ViewTargetActionSupport = _emberViewsMixinsView_target_action_support.default;
52144
52145  var ViewUtils = _emberRuntime.default.ViewUtils = {};
52146  ViewUtils.isSimpleClick = _emberViewsSystemUtils.isSimpleClick;
52147  ViewUtils.getViewClientRects = _emberViewsSystemUtils.getViewClientRects;
52148  ViewUtils.getViewBoundingClientRect = _emberViewsSystemUtils.getViewBoundingClientRect;
52149
52150  if (_emberRuntime.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
52151    _emberRuntime.default.CoreView = _emberViewsViewsCore_view.DeprecatedCoreView;
52152    _emberRuntime.default.View = _emberViewsViewsView.DeprecatedView;
52153    _emberRuntime.default.View.states = _emberViewsViewsStates.states;
52154    _emberRuntime.default.View.cloneStates = _emberViewsViewsStates.cloneStates;
52155    _emberRuntime.default.View._Renderer = _emberMetalViews.Renderer;
52156    _emberRuntime.default.ContainerView = _emberViewsViewsContainer_view.DeprecatedContainerView;
52157    _emberRuntime.default.CollectionView = _emberViewsViewsCollection_view.default;
52158  }
52159
52160  _emberRuntime.default._Renderer = _emberMetalViews.Renderer;
52161
52162  _emberRuntime.default.Checkbox = _emberViewsViewsCheckbox.default;
52163  _emberRuntime.default.TextField = _emberViewsViewsText_field.default;
52164  _emberRuntime.default.TextArea = _emberViewsViewsText_area.default;
52165
52166  if (_emberRuntime.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
52167    _emberRuntime.default.Select = _emberViewsViewsSelect.Select;
52168  }
52169
52170  _emberRuntime.default.SelectOption = _emberViewsViewsSelect.SelectOption;
52171  _emberRuntime.default.SelectOptgroup = _emberViewsViewsSelect.SelectOptgroup;
52172
52173  _emberRuntime.default.TextSupport = _emberViewsMixinsText_support.default;
52174  _emberRuntime.default.ComponentLookup = _emberViewsComponent_lookup.default;
52175  _emberRuntime.default.Component = _emberViewsComponentsComponent.default;
52176  _emberRuntime.default.EventDispatcher = _emberViewsSystemEvent_dispatcher.default;
52177
52178  // Deprecated:
52179  if (_emberRuntime.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
52180    _emberRuntime.default._Metamorph = _emberViewsCompatMetamorph_view._Metamorph;
52181    _emberRuntime.default._MetamorphView = _emberViewsCompatMetamorph_view.default;
52182    _emberRuntime.default._LegacyEachView = _emberViewsViewsLegacy_each_view.default;
52183  }
52184
52185  // END EXPORTS
52186
52187  exports.default = _emberRuntime.default;
52188});
52189// for the side effect of extending Ember.run.queues
52190enifed('ember-views/mixins/aria_role_support', ['exports', 'ember-metal/mixin'], function (exports, _emberMetalMixin) {
52191  /**
52192   @module ember
52193   @submodule ember-views
52194  */
52195
52196  'use strict';
52197
52198  /**
52199   @class AriaRoleSupport
52200   @namespace Ember
52201   @private
52202  */
52203  exports.default = _emberMetalMixin.Mixin.create({
52204    attributeBindings: ['ariaRole:role'],
52205
52206    /**
52207     The WAI-ARIA role of the control represented by this view. For example, a
52208     button may have a role of type 'button', or a pane may have a role of
52209     type 'alertdialog'. This property is used by assistive software to help
52210     visually challenged users navigate rich web applications.
52211      The full list of valid WAI-ARIA roles is available at:
52212     [http://www.w3.org/TR/wai-aria/roles#roles_categorization](http://www.w3.org/TR/wai-aria/roles#roles_categorization)
52213      @property ariaRole
52214     @type String
52215     @default null
52216     @public
52217    */
52218    ariaRole: null
52219  });
52220});
52221enifed('ember-views/mixins/class_names_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-runtime/system/native_array'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberRuntimeSystemNative_array) {
52222  /**
52223  @module ember
52224  @submodule ember-views
52225  */
52226  'use strict';
52227
52228  var EMPTY_ARRAY = [];
52229
52230  /**
52231    @class ClassNamesSupport
52232    @namespace Ember
52233    @private
52234  */
52235  exports.default = _emberMetalMixin.Mixin.create({
52236    concatenatedProperties: ['classNames', 'classNameBindings'],
52237
52238    init: function () {
52239      this._super.apply(this, arguments);
52240
52241      _emberMetalDebug.assert('Only arrays are allowed for \'classNameBindings\'', Array.isArray(this.classNameBindings)
52241);
52242      this.classNameBindings = _emberRuntimeSystemNative_array.A(this.classNameBindings.slice());
52243
52244      _emberMetalDebug.assert('Only arrays of static class strings are allowed for \'classNames\'. For dynamic classes, use \'classNameBindings\'.', Array.isArray(this.classNames));
52245      this.classNames = _emberRuntimeSystemNative_array.A(this.classNames.slice());
52246    },
52247
52248    /**
52249      Standard CSS class names to apply to the view's outer element. This
52250      property automatically inherits any class names defined by the view's
52251      superclasses as well.
52252       @property classNames
52253      @type Array
52254      @default ['ember-view']
52255      @public
52256    */
52257    classNames: ['ember-view'],
52258
52259    /**
52260      A list of properties of the view to apply as class names. If the property
52261      is a string value, the value of that string will be applied as a class
52262      name.
52263       ```javascript
52264      // Applies the 'high' class to the view element
52265      Ember.View.extend({
52266        classNameBindings: ['priority'],
52267        priority: 'high'
52268      });
52269      ```
52270       If the value of the property is a Boolean, the name of that property is
52271      added as a dasherized class name.
52272       ```javascript
52273      // Applies the 'is-urgent' class to the view element
52274      Ember.View.extend({
52275        classNameBindings: ['isUrgent'],
52276        isUrgent: true
52277      });
52278      ```
52279       If you would prefer to use a custom value instead of the dasherized
52280      property name, you can pass a binding like this:
52281       ```javascript
52282      // Applies the 'urgent' class to the view element
52283      Ember.View.extend({
52284        classNameBindings: ['isUrgent:urgent'],
52285        isUrgent: true
52286      });
52287      ```
52288       This list of properties is inherited from the view's superclasses as well.
52289       @property classNameBindings
52290      @type Array
52291      @default []
52292      @public
52293    */
52294    classNameBindings: EMPTY_ARRAY
52295  });
52296});
52297enifed('ember-views/mixins/empty_view_support', ['exports', 'ember-metal/mixin', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/computed'], function (exports, _emberMetalMixin, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalComputed) {
52298  /**
52299   @module ember
52300   @submodule ember-views
52301  */
52302
52303  'use strict';
52304
52305  /**
52306   @class EmptyViewSupport
52307   @namespace Ember
52308   @private
52309  */
52310  exports.default = _emberMetalMixin.Mixin.create({
52311    /**
52312     This provides metadata about what kind of empty view class this
52313     collection would like if it is being instantiated from another
52314     system (like Handlebars)
52315      @private
52316     @property emptyViewClass
52317    */
52318    emptyViewClass: _emberViewsViewsView.default,
52319
52320    /**
52321     An optional view to display if content is set to an empty array.
52322      @property emptyView
52323     @type Ember.View
52324     @default null
52325     @private
52326    */
52327    emptyView: null,
52328
52329    _emptyView: _emberMetalComputed.computed('emptyView', 'attrs.emptyViewClass', 'emptyViewClass', function () {
52330      var emptyView = _emberMetalProperty_get.get(this, 'emptyView');
52331      var attrsEmptyViewClass = this.getAttr('emptyViewClass');
52332      var emptyViewClass = _emberMetalProperty_get.get(this, 'emptyViewClass');
52333      var inverse = _emberMetalProperty_get.get(this, '_itemViewInverse');
52334      var actualEmpty = emptyView || attrsEmptyViewClass;
52335
52336      // Somehow, our previous semantics differed depending on whether the
52337      // `emptyViewClass` was provided on the JavaScript class or via the
52338      // Handlebars template.
52339      // In Glimmer, we disambiguate between the two by checking first (and
52340      // preferring) the attrs-supplied class.
52341      // If not present, we fall back to the class's `emptyViewClass`, but only
52342      // if an inverse has been provided via an `{{else}}`.
52343      if (inverse && actualEmpty) {
52344        if (actualEmpty.extend) {
52345          return actualEmpty.extend({ template: inverse });
52346        } else {
52347          _emberMetalProperty_set.set(actualEmpty, 'template', inverse);
52348        }
52349      } else if (inverse && emptyViewClass) {
52350        return emptyViewClass.extend({ template: inverse });
52351      }
52352
52353      return actualEmpty;
52354    })
52355  });
52356});
52357enifed('ember-views/mixins/instrumentation_support', ['exports', 'ember-metal/mixin', 'ember-metal/computed', 'ember-metal/property_get'], function (exports, _emberMetalMixin, _emberMetalComputed, _emberMetalProperty_get) {
52358  /**
52359  @module ember
52360  @submodule ember-views
52361  */
52362  'use strict';
52363
52364  /**
52365    @class InstrumentationSupport
52366    @namespace Ember
52367    @public
52368  */
52369  var InstrumentationSupport = _emberMetalMixin.Mixin.create({
52370    /**
52371      Used to identify this view during debugging
52372       @property instrumentDisplay
52373      @type String
52374      @public
52375    */
52376    instrumentDisplay: _emberMetalComputed.computed(function () {
52377      if (this.helperName) {
52378        return '{{' + this.helperName + '}}';
52379      }
52380    }),
52381
52382    instrumentName: 'view',
52383
52384    instrumentDetails: function (hash) {
52385      hash.template = _emberMetalProperty_get.get(this, 'templateName');
52386      this._super(hash);
52387    }
52388  });
52389
52390  exports.default = InstrumentationSupport;
52391});
52392enifed('ember-views/mixins/legacy_child_views_support', ['exports', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/property_set', 'container/owner'], function (exports, _emberMetalMixin, _emberMetalProperty_get, _emberMetalProperty_set, _containerOwner) {
52393  'use strict';
52394
52395  exports.default = _emberMetalMixin.Mixin.create({
52396    linkChild: function (instance) {
52397      if (!instance[_containerOwner.OWNER]) {
52398        _containerOwner.setOwner(instance, _containerOwner.getOwner(this));
52399      }
52400
52401      if (_emberMetalProperty_get.get(instance, 'parentView') !== this) {
52402        // linkChild should be idempotent
52403        _emberMetalProperty_set.set(instance, 'parentView', this);
52404        instance.trigger('parentViewDidChange');
52405      }
52406      instance.ownerView = this.ownerView;
52407    },
52408
52409    unlinkChild: function (instance) {
52410      _emberMetalProperty_set.set(instance, 'parentView', null);
52411      instance.trigger('parentViewDidChange');
52412    }
52413  });
52414});
52415enifed('ember-views/mixins/legacy_view_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-metal/property_get'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberMetalProperty_get) {
52416  /**
52417  @module ember
52418  @submodule ember-views
52419  */
52420  'use strict';
52421
52422  /**
52423    @class LegacyViewSupport
52424    @namespace Ember
52425    @private
52426  */
52427  var LegacyViewSupport = _emberMetalMixin.Mixin.create({
52428    beforeRender: function (buffer) {},
52429
52430    afterRender: function (buffer) {},
52431
52432    mutateChildViews: function (callback) {
52433      var childViews = _emberMetalProperty_get.get(this, 'childViews');
52434      var idx = childViews.length;
52435      var view;
52436
52437      while (--idx >= 0) {
52438        view = childViews[idx];
52439        callback(this, view, idx);
52440      }
52441
52442      return this;
52443    },
52444
52445    /**
52446      Removes all children from the `parentView`.
52447       @method removeAllChildren
52448      @return {Ember.View} receiver
52449      @private
52450    */
52451    removeAllChildren: function () {
52452      return this.mutateChildViews(function (parentView, view) {
52453        parentView.removeChild(view);
52454      });
52455    },
52456
52457    destroyAllChildren: function () {
52458      return this.mutateChildViews(function (parentView, view) {
52459        view.destroy();
52460      });
52461    },
52462
52463    /**
52464      Return the nearest ancestor whose parent is an instance of
52465      `klass`.
52466       @method nearestChildOf
52467      @param {Class} klass Subclass of Ember.View (or Ember.View itself)
52468      @return Ember.View
52469      @deprecated
52470      @private
52471    */
52472    nearestChildOf: function (klass) {
52473      _emberMetalDebug.deprecate('nearestChildOf has been deprecated.', false, { id: 'ember-views.nearest-child-of', until: '3.0.0' });
52474
52475      var view = _emberMetalProperty_get.get(this, 'parentView');
52476
52477      while (view) {
52478        if (_emberMetalProperty_get.get(view, 'parentView') instanceof klass) {
52479          return view;
52480        }
52481        view = _emberMetalProperty_get.get(view, 'parentView');
52482      }
52483    },
52484
52485    /**
52486      Return the nearest ancestor that is an instance of the provided
52487      class.
52488       @method nearestInstanceOf
52489      @param {Class} klass Subclass of Ember.View (or Ember.View itself)
52490      @return Ember.View
52491      @deprecated
52492      @private
52493    */
52494    nearestInstanceOf: function (klass) {
52495      _emberMetalDebug.deprecate('nearestInstanceOf is deprecated and will be removed from future releases. Use nearestOfType.', false, { id: 'ember-views.nearest-instance-of', until: '3.0.0' });
52496
52497      var view = _emberMetalProperty_get.get(this, 'parentView');
52498
52499      while (view) {
52500        if (view instanceof klass) {
52501          return view;
52502        }
52503        view = _emberMetalProperty_get.get(view, 'parentView');
52504      }
52505    },
52506
52507    /**
52508      If a value that affects template rendering changes, the view should be
52509      re-rendered to reflect the new value.
52510       @method _contextDidChange
52511      @private
52512      @private
52513    */
52514    _contextDidChange: _emberMetalMixin.observer('context', function () {
52515      this.rerender();
52516    })
52517  });
52518
52519  exports.default = LegacyViewSupport;
52520});
52521enifed('ember-views/mixins/template_rendering_support', ['exports', 'ember-metal/mixin'], function (exports, _emberMetalMixin) {
52522  /**
52523  @module ember
52524  @submodule ember-views
52525  */
52526  'use strict';
52527
52528  // Circular dep
52529  var _renderView;
52530
52531  /**
52532    @class TemplateRenderingSupport
52533    @namespace Ember
52534    @private
52535  */
52536  var TemplateRenderingSupport = _emberMetalMixin.Mixin.create({
52537    /**
52538      Called on your view when it should push strings of HTML into a
52539      `Ember.RenderBuffer`. Most users will want to override the `template`
52540      or `templateName` properties instead of this method.
52541       By default, `Ember.View` will look for a function in the `template`
52542      property and invoke it with the value of `context`. The value of
52543      `context` will be the view's controller unless you overri
52543de it.
52544       @method renderBlock
52545      @param {Ember.RenderBuffer} buffer The render buffer
52546      @private
52547    */
52548
52549    renderBlock: function (block, renderNode) {
52550      if (_renderView === undefined) {
52551        _renderView = require('ember-htmlbars/system/render-view');
52552      }
52553
52554      return _renderView.renderHTMLBarsBlock(this, block, renderNode);
52555    }
52556  });
52557
52558  exports.default = TemplateRenderingSupport;
52559});
52560enifed('ember-views/mixins/text_support', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/mixin', 'ember-runtime/mixins/target_action_support'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalMixin, _emberRuntimeMixinsTarget_action_support) {
52561  /**
52562  @module ember
52563  @submodule ember-views
52564  */
52565
52566  'use strict';
52567
52568  var KEY_EVENTS = {
52569    13: 'insertNewline',
52570    27: 'cancel'
52571  };
52572
52573  /**
52574    `TextSupport` is a shared mixin used by both `Ember.TextField` and
52575    `Ember.TextArea`. `TextSupport` adds a number of methods that allow you to
52576    specify a controller action to invoke when a certain event is fired on your
52577    text field or textarea. The specifed controller action would get the current
52578    value of the field passed in as the only argument unless the value of
52579    the field is empty. In that case, the instance of the field itself is passed
52580    in as the only argument.
52581  
52582    Let's use the pressing of the escape key as an example. If you wanted to
52583    invoke a controller action when a user presses the escape key while on your
52584    field, you would use the `escape-press` attribute on your field like so:
52585  
52586    ```handlebars
52587      {{! application.hbs}}
52588  
52589      {{input escape-press='alertUser'}}
52590    ```
52591  
52592    ```javascript
52593        App = Ember.Application.create();
52594  
52595        App.ApplicationController = Ember.Controller.extend({
52596          actions: {
52597            alertUser: function ( currentValue ) {
52598              alert( 'escape pressed, current value: ' + currentValue );
52599            }
52600          }
52601        });
52602    ```
52603  
52604    The following chart is a visual representation of what takes place when the
52605    escape key is pressed in this scenario:
52606  
52607    ```
52608    The Template
52609    +---------------------------+
52610    |                           |
52611    | escape-press='alertUser'  |
52612    |                           |          TextSupport Mixin
52613    +----+----------------------+          +-------------------------------+
52614         |                                 | cancel method                 |
52615         |      escape button pressed      |                               |
52616         +-------------------------------> | checks for the `escape-press` |
52617                                           | attribute and pulls out the   |
52618         +-------------------------------+ | `alertUser` value             |
52619         |     action name 'alertUser'     +-------------------------------+
52620         |     sent to controller
52621         v
52622    Controller
52623    +------------------------------------------ +
52624    |                                           |
52625    |  actions: {                               |
52626    |     alertUser: function( currentValue ){  |
52627    |       alert( 'the esc key was pressed!' ) |
52628    |     }                                     |
52629    |  }                                        |
52630    |                                           |
52631    +-------------------------------------------+
52632    ```
52633  
52634    Here are the events that we currently support along with the name of the
52635    attribute you would need to use on your field. To reiterate, you would use the
52636    attribute name like so:
52637  
52638    ```handlebars
52639      {{input attribute-name='controllerAction'}}
52640    ```
52641  
52642    ```
52643    +--------------------+----------------+
52644    |                    |                |
52645    | event              | attribute name |
52646    +--------------------+----------------+
52647    | new line inserted  | insert-newline |
52648    |                    |                |
52649    | enter key pressed  | insert-newline |
52650    |                    |                |
52651    | cancel key pressed | escape-press   |
52652    |                    |                |
52653    | focusin            | focus-in       |
52654    |                    |                |
52655    | focusout           | focus-out      |
52656    |                    |                |
52657    | keypress           | key-press      |
52658    |                    |                |
52659    | keyup              | key-up         |
52660    |                    |                |
52661    | keydown            | key-down       |
52662    +--------------------+----------------+
52663    ```
52664  
52665    @class TextSupport
52666    @namespace Ember
52667    @uses Ember.TargetActionSupport
52668    @extends Ember.Mixin
52669    @private
52670  */
52671  var TextSupport = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsTarget_action_support.default, {
52672    value: '',
52673
52674    attributeBindings: ['autocapitalize', 'autocorrect', 'autofocus', 'disabled', 'form', 'maxlength', 'placeholder', 'readonly', 'required', 'selectionDirection', 'spellcheck', 'tabindex', 'title'],
52675    placeholder: null,
52676    disabled: false,
52677    maxlength: null,
52678
52679    init: function () {
52680      this._super.apply(this, arguments);
52681      this.on('paste', this, this._elementValueDidChange);
52682      this.on('cut', this, this._elementValueDidChange);
52683      this.on('input', this, this._elementValueDidChange);
52684    },
52685
52686    /**
52687      The action to be sent when the user presses the return key.
52688       This is similar to the `{{action}}` helper, but is fired when
52689      the user presses the return key when editing a text field, and sends
52690      the value of the field as the context.
52691       @property action
52692      @type String
52693      @default null
52694      @private
52695    */
52696    action: null,
52697
52698    /**
52699      The event that should send the action.
52700       Options are:
52701       * `enter`: the user pressed enter
52702      * `keyPress`: the user pressed a key
52703       @property onEvent
52704      @type String
52705      @default enter
52706      @private
52707    */
52708    onEvent: 'enter',
52709
52710    /**
52711      Whether the `keyUp` event that triggers an `action` to be sent continues
52712      propagating to other views.
52713       By default, when the user presses the return key on their keyboard and
52714      the text field has an `action` set, the action will be sent to the view's
52715      controller and the key event will stop propagating.
52716       If you would like parent views to receive the `keyUp` event even after an
52717      action has been dispatched, set `bubbles` to true.
52718       @property bubbles
52719      @type Boolean
52720      @default false
52721      @private
52722    */
52723    bubbles: false,
52724
52725    interpretKeyEvents: function (event) {
52726      var map = KEY_EVENTS;
52727      var method = map[event.keyCode];
52728
52729      this._elementValueDidChange();
52730      if (method) {
52731        return this[method](event);
52732      }
52733    },
52734
52735    _elementValueDidChange: function () {
52736      // Using readDOMAttr will ensure that HTMLBars knows the last
52737      // value.
52738      _emberMetalProperty_set.set(this, 'value', this.readDOMAttr('value'));
52739    },
52740
52741    change: function (event) {
52742      this._elementValueDidChange(event);
52743    },
52744
52745    /**
52746      Allows you to specify a controller action to invoke when either the `enter`
52747      key is pressed or, in the case of the field being a textarea, when a newline
52748      is inserted. To use this method, give your field an `insert-newline`
52749      attribute. The value of that attribute should be the name of the action
52750      in your controller that you wish to invoke.
52751       For an example on how to use the `insert-newline` attribute, please
52752      reference the example near the top of this file.
52753       @method insertNewline
52754      @param {Event} event
52755      @private
52756    */
52757    insertNewline: function (event) {
52758      sendAction('enter', this, event);
52759      sendAction('insert-newline', this, event);
52760    },
52761
52762    /**
52763      Allows you to specify a controller action to invoke when the escape button
52764      is pressed. To use this method, give your field an `escape-press`
52765      attribute. The value of that attribute should be the name of the action
52766      in your controller that you wish to invoke.
52767       For an example on how to use the `escape-press` attribute, please reference
52768      the example near the top of this file.
52769       @method cancel
52770      @param {Event} event
52771      @private
52772    */
52773    cancel: function (event) {
52774      sendAction('escape-press', this, event);
52775    },
52776
52777    /**
52778      Allows you to specify a controller action to invoke when a field receives
52779      focus. To use this method, give your field a `focus-in` attribute. The value
52780      of that attribute should be the name of the action in your controller
52781      that you wish to invoke.
52782       For an example on how to use the `focus-in` attribute, please reference the
52783      example near the top of this file.
52784       @method focusIn
52785      @param {Event} event
52786      @private
52787    */
52788    focusIn: function (event) {
52789      sendAction('focus-in', this, event);
52790    },
52791
52792    /**
52793      Allows you to specify a controller action to invoke when a field loses
52794      focus. To use this method, give your field a `focus-out` attribute. The value
52795      of that attribute should be the name of the action in your controller
52796      that you wish to invoke.
52797       For an example on how to use the `focus-out` attribute, please reference the
52798      example near the top of this file.
52799       @method focusOut
52800      @param {Event} event
52801      @private
52802    */
52803    focusOut: function (event) {
52804      this._elementValueDidChange(event);
52805      sendAction('focus-out', this, event);
52806    },
52807
52808    /**
52809      Allows you to specify a controller action to invoke when a key is pressed.
52810      To use this method, give your field a `key-press` attribute. The value of
52811      that attribute should be the name of the action in your controller you
52812      that wish to invoke.
52813       For an example on how to use the `key-press` attribute, please reference the
52814      example near the top of this file.
52815       @method keyPress
52816      @param {Event} event
52817      @private
52818    */
52819    keyPress: function (event) {
52820      sendAction('key-press', this, event);
52821    },
52822
52823    /**
52824      Allows you to specify a controller action to invoke when a key-up event is
52825      fired. To use this method, give your field a `key-up` attribute. The value
52826      of that attribute should be the name of the action in your controller
52827      that you wish to invoke.
52828       For an example on how to use the `key-up` attribute, please reference the
52829      example near the top of this file.
52830       @method keyUp
52831      @param {Event} event
52832      @private
52833    */
52834    keyUp: function (event) {
52835      this.interpretKeyEvents(event);
52836
52837      this.sendAction('key-up', _emberMetalProperty_get.get(this, 'value'), event);
52838    },
52839
52840    /**
52841      Allows you to specify a controller action to invoke when a key-down event is
52842      fired. To use this method, give your field a `key-down` attribute. The value
52843      of that attribute should be the name of the action in your controller that
52844      you wish to invoke.
52845       For an example on how to use the `key-down` attribute, please reference the
52846      example near the top of this file.
52847       @method keyDown
52848      @param {Event} event
52849      @private
52850    */
52851    keyDown: function (event) {
52852      this.sendAction('key-down', _emberMetalProperty_get.get(this, 'value'), event);
52853    }
52854  });
52855
52856  // In principle, this shouldn't be necessary, but the legacy
52857  // sendAction semantics for TextField are different from
52858  // the component semantics so this method normalizes them.
52859  function sendAction(eventName, view, event) {
52860    var action = _emberMetalProperty_get.get(view, 'attrs.' + eventName) || _emberMetalProperty_get.get(view, eventName);
52861    var on = _emberMetalProperty_get.get(view, 'onEvent');
52862    var value = _emberMetalProperty_get.get(view, 'value');
52863
52864    // back-compat support for keyPress as an event name even though
52865    // it's also a method name that consumes the event (and therefore
52866    // incompatible with sendAction semantics).
52867    if (on === eventName || on === 'keyPress' && eventName === 'key-press') {
52868      view.sendAction('action', value);
52869    }
52870
52871    view.sendAction(eventName, value);
52872
52873    if (action || on === eventName) {
52874      if (!_emberMetalProperty_get.get(view, 'bubbles')) {
52875        event.stopPropagation();
52876      }
52877    }
52878  }
52879
52880  exports.default = TextSupport;
52881});
52882enifed('ember-views/mixins/view_child_views_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/set_properties', 'ember-runtime/system/native_array', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalSet_properties, _emberRuntimeSystemNative_array, _containerOwner) {
52883  /**
52884  @module ember
52885  @submodule ember-views
52886  */
52887  'use strict';
52888
52889  var EMPTY_ARRAY = [];
52890
52891  exports.default = _emberMetalMixin.Mixin.create({
52892    /**
52893      Array of child views. You should never edit this array directly.
52894      Instead, use `appendChild` and `removeFromParent`.
52895       @property childViews
52896      @type Array
52897      @default []
52898      @private
52899    */
52900    childViews: EMPTY_ARRAY,
52901
52902    init: function () {
52903      this._super.apply(this, arguments);
52904
52905      // setup child views. be sure to clone the child views array first
52906      // 2.0TODO: Remove Ember.A() here
52907      this.childViews = _emberRuntimeSystemNative_array.A(this.childViews.slice());
52908      this.ownerView = this.ownerView || this;
52909    },
52910
52911    appendChild: function (view) {
52912      this.linkChild(view);
52913      this.childViews.push(view);
52914    },
52915
52916    destroyChild: function (view) {
52917      view.destroy();
52918    },
52919
52920    /**
52921      Removes the child view from the parent view.
52922       @method removeChild
52923      @param {Ember.View} view
52924      @return {Ember.View} receiver
52925      @private
52926    */
52927    removeChild: function (view) {
52928      // If we're destroying, the entire subtree will be
52929      // freed, and the DOM will be handled separately,
52930      // so no need to mess with childViews.
52931      if (this.isDestroying) {
52932        return;
52933      }
52934
52935      // update parent node
52936      this.unlinkChild(view);
52937
52938      // remove view from childViews array.
52939      var childViews = _emberMetalProperty_get.get(this, 'childViews');
52940
52941      var index = childViews.indexOf(view);
52942      if (index !== -1) {
52943        childViews.splice(index, 1);
52944      }
52945
52946      return this;
52947    },
52948
52949    /**
52950      Instantiates a view to be added to the childViews array during view
52951      initialization. You generally will not call this method directly unless
52952      you are overriding `createChildViews()`. Note that this method will
52953      automatically configure the correct settings on the new view instance to
52954      act as a child of the parent.
52955       @method createChildView
52956      @param {Class|String} viewClass
52957      @param {Object} [attrs] Attributes to add
52958      @return {Ember.View} new instance
52959      @private
52960    */
52961    createChildView: function (maybeViewClass) {
52962      var attrs = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
52963
52964      if (!maybeViewClass) {
52965        throw new TypeError('createChildViews first argument must exist');
52966      }
52967
52968      var owner = _containerOwner.getOwner(this);
52969
52970      if (maybeViewClass.isView && maybeViewClass.parentView === this && _containerOwner.getOwner(maybeViewClass) === owner) {
52971        return maybeViewClass;
52972      }
52973
52974      var view;
52975
52976      attrs.parentView = this;
52977      attrs.renderer = this.renderer;
52978      attrs._viewRegistry = this._viewRegistry;
52979
52980      if (maybeViewClass.isViewFactory) {
52981        _containerOwner.setOwner(attrs, owner);
52982
52983        view = maybeViewClass.create(attrs);
52984
52985        if (view.viewName) {
52986          _emberMetalProperty_set.set(this, view.viewName, view);
52987        }
52988      } else if ('string' === typeof maybeViewClass) {
52989        var fullName = 'view:' + maybeViewClass;
52990        var ViewKlass = owner._lookupFactory(fullName);
52991
52992        _emberMetalDebug.assert('Could not find view: \'' + fullName + '\'', !!ViewKlass);
52993
52994        view = ViewKlass.create(attrs);
52995      } else {
52996        view = maybeViewClass;
52997        _emberMetalDebug.assert('You must pass instance or subclass of View', view.isView);
52998
52999        _containerOwner.setOwner(attrs, owner);
53000        _emberMetalSet_properties.default(view, attrs);
53001      }
53002
53003      this.linkChild(view);
53004
53005      return view;
53006    },
53007
53008    linkChild: function (instance) {
53009      if (!instance[_containerOwner.OWNER]) {
53010        _containerOwner.setOwner(instance, _containerOwner.getOwner(this));
53011      }
53012
53013      instance.parentView = this;
53014      instance.ownerView = this.ownerView;
53015    },
53016
53017    unlinkChild: function (instance) {
53018      instance.parentView = null;
53019    }
53020  });
53021});
53022enifed('ember-views/mixins/view_context_support', ['exports', 'ember-metal/mixin', 'ember-metal/computed', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/mixins/legacy_view_support', 'ember-metal/events'], function (exports, _emberMetalMixin, _emberMetalComputed, _emberMetalProperty_get, _emberMetalProperty_set, _emberViewsMixinsLegacy_view_support, _emberMetalEvents) {
53023  /**
53024  @module ember
53025  @submodule ember-views
53026  */
53027  'use strict';
53028
53029  var ViewContextSupport = _emberMetalMixin.Mixin.create(_emberViewsMixinsLegacy_view_support.default, {
53030    /**
53031      The object from which templates should access properties.
53032       This object will be passed to the template function each time the render
53033      method is called, but it is up to the individual function to decide what
53034      to do with it.
53035       By default, this will be the view's controller.
53036       @property context
53037      @type Object
53038      @private
53039    */
53040    context: _emberMetalComputed.computed({
53041      get: function () {
53042        return _emberMetalProperty_get.get(this, '_context');
53043      },
53044      set: function (key, value) {
53045        _emberMetalProperty_set.set(this, '_context', value);
53046        return value;
53047      }
53048    }),
53049
53050    /**
53051      Private copy of the view's template context. This can be set directly
53052      by Handlebars without triggering the observer that causes the view
53053      to be re-rendered.
53054       The context of a view is looked up as follows:
53055       1. Supplied context (usually by Handlebars)
53056      2. Specified controller
53057      3. `parentView`'s context (for a child of a ContainerView)
53058       The code in Handlebars that overrides the `_context` property first
53059      checks to see whether the view has a specified controller. This is
53060      something of a hack and should be revisited.
53061       @property _context
53062      @private
53063    */
53064    _context: _emberMetalComputed.computed({
53065      get: function () {
53066        var parentView, controller;
53067
53068        if (controller = _emberMetalProperty_get.get(this, 'controller')) {
53069          return controller;
53070        }
53071
53072        parentView = this.parentView;
53073        if (parentView) {
53074          return _emberMetalProperty_get.get(parentView, '_context');
53075        }
53076        return null;
53077      },
53078      set: function (key, value) {
53079        return value;
53080      }
53081    }),
53082
53083    _controller: null,
53084
53085    /**
53086      The controller managing this view. If this property is set, it will be
53087      made available for use by the template.
53088       @property controller
53089      @type Object
53090      @private
53091    */
53092    controller: _emberMetalComputed.computed({
53093      get: function () {
53094        if (this._controller) {
53095          return this._controller;
53096        }
53097
53098        return this.parentView ? _emberMetalProperty_get.get(this.parentView, 'controller') : null;
53099      },
53100      set: function (_, value) {
53101        this._controller = value;
53102        return value;
53103      }
53104    }),
53105
53106    _legacyControllerDidChange: _emberMetalMixin.observer('controller', function () {
53107      this.childViews.forEach(function (view) {
53108        return view.notifyPropertyChange('controller');
53109      });
53110    }),
53111
53112    _notifyControllerChange: _emberMetalEvents.on('parentViewDidChange', function () {
53113      this.notifyPropertyChange('controller');
53114    })
53115  });
53116
53117  exports.default = ViewContextSupport;
53118});
53119enifed('ember-views/mixins/view_state_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin'], function (exports, _emberMetalDebug, _emberMetalMixin) {
53120  'use strict';
53121
53122  var ViewStateSupport = _emberMetalMixin.Mixin.create({
53123    transitionTo: function (state) {
53124      _emberMetalDebug.deprecate('Ember.View#transitionTo has been deprecated, it is for internal use only', false, { id: 'ember-views.view-transition-to', until: '2.4.0' });
53125      this._transitionTo(state);
53126    },
53127
53128    _transitionTo: function (state) {
53129      var priorState = this._currentState;
53130      var currentState = this._currentState = this._states[state];
53131      this._state = state;
53132
53133      if (priorState && priorState.exit) {
53134        priorState.exit(this);
53135      }
53136      if (currentState.enter) {
53137        currentState.enter(this);
53138      }
53139    }
53140  });
53141
53142  exports.default = ViewStateSupport;
53143});
53144enifed('ember-views/mixins/view_support', ['exports', 'ember-metal/debug', 'ember-metal/error', 'ember-metal/property_get', 'ember-metal/run_loop', 'ember-metal/observer', 'ember-metal/utils', 'ember-metal/computed', 'ember-metal/mixin', 'ember-runtime/system/core_object', 'ember-metal/features', 'ember-metal/symbol', 'container/owner', 'ember-views/system/jquery'], function (exports, _emberMetalDebug, _emberMetalError, _emberMetalProperty_get, _emberMetalRun_loop, _emberMetalObserver, _emberMetalUtils, _emberMetalComputed, _emberMetalMixin, _emberRuntimeSystemCore_object, _emberMetalFeatures, _emberMetalSymbol, _containerOwner, _emberViewsSystemJquery) {
53145  'use strict';
53146
53147  var _Mixin$create;
53148
53149  var INIT_WAS_CALLED = _emberMetalSymbol.default('INIT_WAS_CALLED');
53150
53151  function K() {
53152    return this;
53153  }
53154
53155  exports.default = _emberMetalMixin.Mixin.create((_Mixin$create = {
53156    concatenatedProperties: ['attributeBindings'],
53157
53158    /**
53159      @property isView
53160      @type Boolean
53161      @default true
53162      @static
53163      @private
53164    */
53165    isView: true,
53166
53167    // ..........................................................
53168    // TEMPLATE SUPPORT
53169    //
53170
53171    /**
53172      The name of the template to lookup if no template is provided.
53173       By default `Ember.View` will lookup a template with this name in
53174      `Ember.TEMPLATES` (a shared global object).
53175       @property templateName
53176      @type String
53177      @default null
53178      @private
53179    */
53180    templateName: null,
53181
53182    /**
53183      The name of the layout to lookup if no layout is provided.
53184       By default `Ember.View` will lookup a template with this name in
53185      `Ember.TEMPLATES` (a shared global object).
53186       @property layoutName
53187      @type String
53188      @default null
53189      @private
53190    */
53191    layoutName: null,
53192
53193    /**
53194      The template used to render the view. This should be a function that
53195      accepts an optional context parameter and returns a string of HTML that
53196      will be inserted into the DOM relative to its parent view.
53197       In general, you should set the `templateName` property instead of setting
53198      the template yourself.
53199       @property template
53200      @type Function
53201      @private
53202    */
53203    template: _emberMetalComputed.computed({
53204      get: function () {
53205        var templateName = _emberMetalProperty_get.get(this, 'templateName');
53206        var template = this.templateForName(templateName, 'template');
53207        _emberMetalDebug.assert('You specified the templateName ' + templateName + ' for ' + this + ', but it did not exist.', !templateName || !!template);
53208        return template || _emberMetalProperty_get.get(this, 'defaultTemplate');
53209      },
53210      set: function (key, value) {
53211        if (value !== undefined) {
53212          return value;
53213        }
53214        return _emberMetalProperty_get.get(this, key);
53215      }
53216    }),
53217
53218    /**
53219      A view may contain a layout. A layout is a regular template but
53220      supersedes the `template` property during rendering. It is the
53221      responsibility of the layout template to retrieve the `template`
53222      property from the view (or alternatively, call `Handlebars.helpers.yield`,
53223      `{{yield}}`) to render it in the correct location.
53224       This is useful for a view that has a shared wrapper, but which delegates
53225      the rendering of the contents of the wrapper to the `template` property
53226      on a subclass.
53227       @property layout
53228      @type Function
53229      @private
53230    */
53231    layout: _emberMetalComputed.computed({
53232      get: function (key) {
53233        var layoutName = _emberMetalProperty_get.get(this, 'layoutName');
53234        var layout = this.templateForName(layoutName, 'layout');
53235
53236        _emberMetalDebug.assert('You specified the layoutName ' + layoutName + ' for ' + this + ', but it did not exist.', !layoutName || !!layout);
53237
53238        return layout || _emberMetalProperty_get.get(this, 'defaultLayout');
53239      },
53240
53241      set: function (key, value) {
53242        return value;
53243      }
53244    }),
53245
53246    templateForName: function (name, type) {
53247      if (!name) {
53248        return;
53249      }
53250      _emberMetalDebug.assert('templateNames are not allowed to contain periods: ' + name, name.indexOf('.') === -1);
53251
53252      var owner = _containerOwner.getOwner(this);
53253
53254      if (!owner) {
53255        throw new _emberMetalError.default('Container was not found when looking up a views template. ' + 'This is most likely due to manually instantiating an Ember.View. ' + 'See: http://git.io/EKPpnA');
53256      }
53257
53258      return owner.lookup('template:' + name);
53259    },
53260
53261    /**
53262      Return the nearest ancestor that is an instance of the provided
53263      class or mixin.
53264       @method nearestOfType
53265      @param {Class,Mixin} klass Subclass of Ember.View (or Ember.View itself),
53266             or an instance of Ember.Mixin.
53267      @return Ember.View
53268      @private
53269    */
53270    nearestOfType: function (klass) {
53271      var view = _emberMetalProperty_get.get(this, 'parentView');
53272      var isOfType = klass instanceof _emberMetalMixin.Mixin ? function (view) {
53273        return klass.detect(view);
53274      } : function (view) {
53275        return klass.detect(view.constructor);
53276      };
53277
53278      while (view) {
53279        if (isOfType(view)) {
53280          return view;
53281        }
53282        view = _emberMetalProperty_get.get(view, 'parentView');
53283      }
53284    },
53285
53286    /**
53287      Return the nearest ancestor that has a given property.
53288       @method nearestWithProperty
53289      @param {String} property A property name
53290      @return Ember.View
53291      @private
53292    */
53293    nearestWithProperty: function (property) {
53294      var view = _emberMetalProperty_get.get(this, 'parentView');
53295
53296      while (view) {
53297        if (property in view) {
53298          return view;
53299        }
53300        view = _emberMetalProperty_get.get(view, 'parentView');
53301      }
53302    },
53303
53304    /**
53305      Renders the view again. This will work regardless of whether the
53306      view is already in the DOM or not. If the view is in the DOM, the
53307      rendering process will be deferred to give bindings a chance
53308      to synchronize.
53309       If children were added during the rendering process using `appendChild`,
53310      `rerender` will remove them, because they will be added again
53311      if needed by the next `render`.
53312       In general, if the display of your view changes, you should modify
53313      the DOM element directly instead of manually calling `rerender`, which can
53314      be slow.
53315       @method rerender
53316      @public
53317    */
53318    rerender: function () {
53319      return this._currentState.rerender(this);
53320    },
53321
53322    // ..........................................................
53323    // ELEMENT SUPPORT
53324    //
53325
53326    /**
53327      Returns the current DOM element for the view.
53328       @property element
53329      @type DOMElement
53330      @public
53331    */
53332    element: null,
53333
53334    /**
53335      Returns a jQuery object for this view's element. If you pass in a selector
53336      string, this method will return a jQuery object, using the current element
53337      as its buffer.
53338       For example, calling `view.$('li')` will return a jQuery object containing
53339      all of the `li` elements inside the DOM element of this view.
53340       @method $
53341      @param {String} [selector] a jQuery-compatible selector string
53342      @return {jQuery} the jQuery object for the DOM node
53343      @public
53344    */
53345    $: function (sel) {
53346      _emberMetalDebug.assert('You cannot access this.$() on a component with `tagName: \'\'` specified.', this.tagName !== '');
53347      return this._currentState.$(this, sel);
53348    },
53349
53350    forEachChildView: function (callback) {
53351      var childViews = this.childViews;
53352
53353      if (!childViews) {
53354        return this;
53355      }
53356
53357      var len = childViews.length;
53358      var view, idx;
53359
53360      for (idx = 0; idx < len; idx++) {
53361        view = childViews[idx];
53362        callback(view);
53363      }
53364
53365      return this;
53366    },
53367
53368    /**
53369      Appends the view's element to the specified parent element.
53370       If the view does not have an HTML representation yet, `createElement()`
53371      will be called automatically.
53372       Note that this method just schedules the view to be appended; the DOM
53373      element will not be appended to the given element until all bindings have
53374      finished synchronizing.
53375       This is not typically a function that you will need to call directly when
53376      building your application. You might consider using `Ember.ContainerView`
53377      instead. If you do need to use `appendTo`, be sure that the target element
53378      you are providing is associated with an `Ember.Application` and does not
53379      have an ancestor element that is associated with an Ember view.
53380       @method appendTo
53381      @param {String|DOMElement|jQuery} A selector, element, HTML string, or jQuery object
53382      @return {Ember.View} receiver
53383      @private
53384    */
53385    appendTo: function (selector) {
53386      var $ = this._environment ? this._environment.options.jQuery : _emberViewsSystemJquery.default;
53387
53388      if ($) {
53389        var target = $(selector);
53390
53391        _emberMetalDebug.assert('You tried to append to (' + selector + ') but that isn\'t in the DOM', target.length > 0);
53392        _emberMetalDebug.assert('You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead.', !target.is('.ember-view') && !target.parents().is('.ember-view'));
53393
53394        this.renderer.appendTo(this, target[0]);
53395      } else {
53396        var target = selector;
53397
53398        _emberMetalDebug.assert('You tried to append to a selector string (' + selector + ') in an environment without jQuery', typeof target !== 'string');
53399        _emberMetalDebug.assert('You tried to append to a non-Element (' + selector + ') in an environment without jQuery', typeof selector.appendChild === 'function');
53400
53401        this.renderer.appendTo(this, target);
53402      }
53403
53404      return this;
53405    },
53406
53407    /**
53408      @private
53409       Creates a new DOM element, renders the view into it, then returns the
53410      element.
53411       By default, the element created and rendered into will be a `BODY` element,
53412      since this is the default context that views are rendered into when being
53413      inserted directly into the DOM.
53414       ```js
53415      var element = view.renderToElement();
53416      element.tagName; // => "BODY"
53417      ```
53418       You can override the kind of element rendered into and returned by
53419      specifying an optional tag name as the first argument.
53420       ```js
53421      var element = view.renderToElement('table');
53422      element.tagName; // => "TABLE"
53423      ```
53424       This method is useful if you want to render the view into an element that
53425      is not in the document's body. Instead, a new `body` element, detached from
53426      the DOM is returned. FastBoot uses this to serialize the rendered view into
53427      a string for transmission over the network.
53428       ```js
53429      app.visit('/').then(function(instance) {
53430        var element;
53431        Ember.run(function() {
53432          element = renderToElement(instance);
53433        });
53434         res.send(serialize(element));
53435      });
53436      ```
53437       @method renderToElement
53438      @param {String} tagName The tag of the element to create and render into. Defaults to "body".
53439      @return {HTMLBodyElement} element
53440      @private
53441    */
53442    renderToElement: function (tagName) {
53443      tagName = tagName || 'body';
53444
53445      var element = this.renderer._dom.createElement(tagName);
53446
53447      this.renderer.appendTo(this, element);
53448      return element;
53449    },
53450
53451    /**
53452      Replaces the content of the specified parent element with this view's
53453      element. If the view does not have an HTML representation yet,
53454      the element will be generated automatically.
53455       Note that this method just schedules the view to be appended; the DOM
53456      element will not be appended to the given element until all bindings have
53457      finished synchronizing
53458       @method replaceIn
53459      @param {String|DOMElement|jQuery} target A selector, element, HTML string, or jQuery object
53460      @return {Ember.View} received
53461      @private
53462    */
53463    replaceIn: function (selector) {
53464      var target = _emberViewsSystemJquery.default(selector);
53465
53466      _emberMetalDebug.assert('You tried to replace in (' + selector + ') but that isn\'t in the DOM', target.length > 0);
53467      _emberMetalDebug.assert('You cannot replace an existing Ember.View. Consider using Ember.ContainerView instead.', !target.is('.ember-view') && !target.parents().is('.ember-view'));
53468
53469      this.renderer.replaceIn(this, target[0]);
53470
53471      return this;
53472    },
53473
53474    /**
53475      Appends the view's element to the document body. If the view does
53476      not have an HTML representation yet
53477      the element will be generated automatically.
53478       If your application uses the `rootElement` property, you must append
53479      the view within that element. Rendering views outside of the `rootElement`
53480      is not supported.
53481       Note that this method just schedules the view to be appended; the DOM
53482      element will not be appended to the document body until all bindings have
53483      finished synchronizing.
53484       @method append
53485      @return {Ember.View} receiver
53486      @private
53487    */
53488    append: function () {
53489      return this.appendTo(document.body);
53490    },
53491
53492    /**
53493      Removes the view's element from the element to which it is attached.
53494       @method remove
53495      @return {Ember.View} receiver
53496      @private
53497    */
53498    remove: function () {
53499      // What we should really do here is wait until the end of the run loop
53500      // to determine if the element has been re-appended to a different
53501      // element.
53502      // In the interim, we will just re-render if that happens. It is more
53503      // important than elements get garbage collected.
53504      if (!this.removedFromDOM) {
53505        this.destroyElement();
53506      }
53507
53508      // Set flag to avoid future renders
53509      this._willInsert = false;
53510    },
53511
53512    /**
53513      The HTML `id` of the view's element in the DOM. You can provide this
53514      value yourself but it must be unique (just as in HTML):
53515       ```handlebars
53516        {{my-component elementId="a-really-cool-id"}}
53517      ```
53518       If not manually set a default value will be provided by the framework.
53519       Once rendered an element's `elementId` is considered immutable and you
53520      should never change it. If you need to compute a dynamic value for the
53521      `elementId`, you should do this when the component or element is being
53522      instantiated:
53523       ```javascript
53524        export default Ember.Component.extend({
53525          setElementId: Ember.on('init', function() {
53526            var index = this.get('index');
53527            this.set('elementId', 'component-id' + index);
53528          })
53529        });
53530      ```
53531       @property elementId
53532      @type String
53533      @public
53534    */
53535    elementId: null,
53536
53537    /**
53538      Attempts to discover the element in the parent element. The default
53539      implementation looks for an element with an ID of `elementId` (or the
53540      view's guid if `elementId` is null). You can override this method to
53541      provide your own form of lookup. For example, if you want to discover your
53542      element using a CSS class name instead of an ID.
53543       @method findElementInParentElement
53544      @param {DOMElement} parentElement The parent's DOM element
53545      @return {DOMElement} The discovered element
53546      @private
53547    */
53548    findElementInParentElement: function (parentElem) {
53549      var id = '#' + this.elementId;
53550      return _emberViewsSystemJquery.default(id)[0] || _emberViewsSystemJquery.default(id, parentElem)[0];
53551    },
53552
53553    /**
53554      Creates a DOM representation of the view and all of its child views by
53555      recursively calling the `render()` method. Once the element is created,
53556      it sets the `element` property of the view to the rendered element.
53557       After the element has been inserted into the DOM, `didInsertElement` will
53558      be called on this view and all of its child views.
53559       @method createElement
53560      @return {Ember.View} receiver
53561      @private
53562    */
53563    createElement: function () {
53564      if (this.element) {
53565        return this;
53566      }
53567
53568      this.renderer.createElement(this);
53569
53570      return this;
53571    },
53572
53573    /**
53574      Called when a view is going to insert an element into the DOM.
53575       @event willInsertElement
53576      @public
53577    */
53578    willInsertElement: K,
53579
53580    /**
53581      Called when the element of the view has been inserted into the DOM
53582      or after the view was re-rendered. Override this function to do any
53583      set up that requires an element in the document body.
53584       When a view has children, didInsertElement will be called on the
53585      child view(s) first, bubbling upwards through the hierarchy.
53586       @event didInsertElement
53587      @public
53588    */
53589    didInsertElement: K,
53590
53591    /**
53592      Called when the view is about to rerender, but before anything has
53593      been torn down. This is a good opportunity to tear down any manual
53594      observers you have installed based on the DOM state
53595       @event willClearRender
53596      @public
53597    */
53598    willClearRender: K,
53599
53600    /**
53601      Destroys any existing element along with the element for any child views
53602      as well. If the view does not currently have a element, then this method
53603      will do nothing.
53604       If you implement `willDestroyElement()` on your view, then this method will
53605      be invoked on your view before your element is destroyed to give you a
53606      chance to clean up any event handlers, etc.
53607       If you write a `willDestroyElement()` handler, you can assume that your
53608      `didInsertElement()` handler was called earlier for the same element.
53609       You should not call or override this method yourself, but you may
53610      want to implement the above callbacks.
53611       @method destroyElement
53612      @return {Ember.View} receiver
53613      @private
53614    */
53615    destroyElement: function () {
53616      return this._currentState.destroyElement(this);
53617    },
53618
53619    /**
53620      Called when the element of the view is going to be destroyed. Override
53621      this function to do any teardown that requires an element, like remov
53621ing
53622      event listeners.
53623       Please note: any property changes made during this event will have no
53624      effect on object observers.
53625       @event willDestroyElement
53626      @public
53627    */
53628    willDestroyElement: K,
53629
53630    /**
53631      Called when the parentView property has changed.
53632       @event parentViewDidChange
53633      @private
53634    */
53635    parentViewDidChange: K,
53636
53637    // ..........................................................
53638    // STANDARD RENDER PROPERTIES
53639    //
53640
53641    /**
53642      Tag name for the view's outer element. The tag name is only used when an
53643      element is first created. If you change the `tagName` for an element, you
53644      must destroy and recreate the view element.
53645       By default, the render buffer will use a `<div>` tag for views.
53646       @property tagName
53647      @type String
53648      @default null
53649      @public
53650    */
53651
53652    // We leave this null by default so we can tell the difference between
53653    // the default case and a user-specified tag.
53654    tagName: null,
53655
53656    /*
53657      Used to specify a default tagName that can be overridden when extending
53658      or invoking from a template.
53659       @property _defaultTagName
53660      @private
53661    */
53662
53663    /**
53664      Normally, Ember's component model is "write-only". The component takes a
53665      bunch of attributes that it got passed in, and uses them to render its
53666      template.
53667       One nice thing about this model is that if you try to set a value to the
53668      same thing as last time, Ember (through HTMLBars) will avoid doing any
53669      work on the DOM.
53670       This is not just a performance optimization. If an attribute has not
53671      changed, it is important not to clobber the element's "hidden state".
53672      For example, if you set an input's `value` to the same value as before,
53673      it will clobber selection state and cursor position. In other words,
53674      setting an attribute is not **always** idempotent.
53675       This method provides a way to read an element's attribute and also
53676      update the last value Ember knows about at the same time. This makes
53677      setting an attribute idempotent.
53678       In particular, what this means is that if you get an `<input>` element's
53679      `value` attribute and then re-render the template with the same value,
53680      it will avoid clobbering the cursor and selection position.
53681       Since most attribute sets are idempotent in the browser, you typically
53682      can get away with reading attributes using jQuery, but the most reliable
53683      way to do so is through this method.
53684       @method readDOMAttr
53685      @param {String} name the name of the attribute
53686      @return String
53687      @public
53688    */
53689    readDOMAttr: function (name) {
53690      var attr = this._renderNode.childNodes.filter(function (node) {
53691        return node.attrName === name;
53692      })[0];
53693      if (!attr) {
53694        return null;
53695      }
53696      return attr.getContent();
53697    },
53698
53699    // .......................................................
53700    // CORE DISPLAY METHODS
53701    //
53702
53703    /**
53704      Setup a view, but do not finish waking it up.
53705       * configure `childViews`
53706      * register the view with the global views hash, which is used for event
53707        dispatch
53708       @method init
53709      @private
53710    */
53711    init: function () {
53712      this._super.apply(this, arguments);
53713
53714      if (!this.elementId) {
53715        this.elementId = _emberMetalUtils.guidFor(this);
53716      }
53717
53718      this.scheduledRevalidation = false;
53719
53720      this[INIT_WAS_CALLED] = true;
53721
53722      _emberMetalDebug.assert('Using a custom `.render` function is no longer supported.', !this.render);
53723    }
53724
53725  }, _Mixin$create[_emberRuntimeSystemCore_object.POST_INIT] = function () {
53726    this._super.apply(this, arguments);
53727
53728    _emberMetalDebug.assert('You must call `this._super(...arguments);` when implementing `init` in a component. Please update ' + this + ' to call `this._super` from `init`.', this[INIT_WAS_CALLED]);
53729
53730    this.renderer.componentInitAttrs(this, this.attrs || {});
53731  }, _Mixin$create.__defineNonEnumerable = function (property) {
53732    this[property.name] = property.descriptor.value;
53733  }, _Mixin$create.revalidate = function () {
53734    this.renderer.revalidateTopLevelView(this);
53735    this.scheduledRevalidation = false;
53736  }, _Mixin$create.scheduleRevalidate = function (node, label, manualRerender) {
53737    if (node && !this._dispatching && this.env.renderedNodes.has(node)) {
53738      if (manualRerender) {
53739        _emberMetalDebug.deprecate('You manually rerendered ' + label + ' (a parent component) from a child component during the rendering process. This rarely worked in Ember 1.x and will be removed in Ember 3.0', false, { id: 'ember-views.manual-parent-rerender', until: '3.0.0' });
53740      } else {
53741        _emberMetalDebug.deprecate('You modified ' + label + ' twice in a single render. This was unreliable in Ember 1.x and will be removed in Ember 3.0', false, { id: 'ember-views.render-double-modify', until: '3.0.0' });
53742      }
53743      _emberMetalRun_loop.default.scheduleOnce('render', this, this.revalidate);
53744      return;
53745    }
53746
53747    _emberMetalDebug.deprecate('A property of ' + this + ' was modified inside the ' + this._dispatching + ' hook. You should never change properties on components, services or models during ' + this._dispatching + ' because it causes significant performance degradation.', !this._dispatching, { id: 'ember-views.dispatching-modify-property', until: '3.0.0' });
53748
53749    if (!this.scheduledRevalidation || this._dispatching) {
53750      this.scheduledRevalidation = true;
53751      _emberMetalRun_loop.default.scheduleOnce('render', this, this.revalidate);
53752    }
53753  }, _Mixin$create.templateRenderer = null, _Mixin$create.removeFromParent = function () {
53754    var parent = this.parentView;
53755
53756    // Remove DOM element from parent
53757    this.remove();
53758
53759    if (parent) {
53760      parent.removeChild(this);
53761    }
53762    return this;
53763  }, _Mixin$create.destroy = function () {
53764    // get parentView before calling super because it'll be destroyed
53765    var parentView = this.parentView;
53766    var viewName = this.viewName;
53767
53768    if (!this._super.apply(this, arguments)) {
53769      return;
53770    }
53771
53772    // remove from non-virtual parent view if viewName was specified
53773    if (viewName && parentView) {
53774      parentView.set(viewName, null);
53775    }
53776
53777    // Destroy HTMLbars template
53778    if (this.lastResult) {
53779      this.lastResult.destroy();
53780    }
53781
53782    return this;
53783  }, _Mixin$create.handleEvent = function (eventName, evt) {
53784    return this._currentState.handleEvent(this, eventName, evt);
53785  }, _Mixin$create._register = function () {
53786    _emberMetalDebug.assert('Attempted to register a view with an id already in use: ' + this.elementId, !this._viewRegistry[this.elementId]);
53787    this._viewRegistry[this.elementId] = this;
53788  }, _Mixin$create._unregister = function () {
53789    delete this._viewRegistry[this.elementId];
53790  }, _Mixin$create.registerObserver = function (root, path, target, observer) {
53791    if (!observer && 'function' === typeof target) {
53792      observer = target;
53793      target = null;
53794    }
53795
53796    if (!root || typeof root !== 'object') {
53797      return;
53798    }
53799
53800    var scheduledObserver = this._wrapAsScheduled(observer);
53801
53802    _emberMetalObserver.addObserver(root, path, target, scheduledObserver);
53803
53804    this.one('willClearRender', function () {
53805      _emberMetalObserver.removeObserver(root, path, target, scheduledObserver);
53806    });
53807  }, _Mixin$create._wrapAsScheduled = function (fn) {
53808    var view = this;
53809    var stateCheckedFn = function () {
53810      view._currentState.invokeObserver(this, fn);
53811    };
53812    var scheduledFn = function () {
53813      _emberMetalRun_loop.default.scheduleOnce('render', this, stateCheckedFn);
53814    };
53815    return scheduledFn;
53816  }, _Mixin$create));
53817});
53818/*
53819 This is a special hook implemented in CoreObject, that allows Views/Components
53820 to have a way to ensure that `init` fires before `didInitAttrs` / `didReceiveAttrs`
53821 (so that `this._super` in init does not trigger `didReceiveAttrs` before the classes
53822 own `init` is finished).
53823  @method __postInitInitialization
53824 @private
53825 */
53826
53827/**
53828  Removes the view from its `parentView`, if one is found. Otherwise
53829  does nothing.
53830   @method removeFromParent
53831  @return {Ember.View} receiver
53832  @private
53833*/
53834
53835/**
53836  You must call `destroy` on a view to destroy the view (and all of its
53837  child views). This will remove the view from any parent node, then make
53838  sure that the DOM element managed by the view can be released by the
53839  memory manager.
53840   @method destroy
53841  @private
53842*/
53843
53844// .......................................................
53845// EVENT HANDLING
53846//
53847
53848/**
53849  Handle events from `Ember.EventDispatcher`
53850   @method handleEvent
53851  @param eventName {String}
53852  @param evt {Event}
53853  @private
53854*/
53855
53856/**
53857  Registers the view in the view registry, keyed on the view's `elementId`.
53858  This is used by the EventDispatcher to locate the view in response to
53859  events.
53860   This method should only be called once the view has been inserted into the
53861  DOM.
53862   @method _register
53863  @private
53864*/
53865
53866/**
53867  Removes the view from the view registry. This should be called when the
53868  view is removed from DOM.
53869   @method _unregister
53870  @private
53871*/
53872enifed('ember-views/mixins/view_target_action_support', ['exports', 'ember-metal/mixin', 'ember-runtime/mixins/target_action_support', 'ember-metal/alias'], function (exports, _emberMetalMixin, _emberRuntimeMixinsTarget_action_support, _emberMetalAlias) {
53873  'use strict';
53874
53875  /**
53876  `Ember.ViewTargetActionSupport` is a mixin that can be included in a
53877  view class to add a `triggerAction` method with semantics similar to
53878  the Handlebars `{{action}}` helper. It provides intelligent defaults
53879  for the action's target: the view's controller; and the context that is
53880  sent with the action: the view's context.
53881  
53882  Note: In normal Ember usage, the `{{action}}` helper is usually the best
53883  choice. This mixin is most often useful when you are doing more complex
53884  event handling in custom View subclasses.
53885  
53886  For example:
53887  
53888  ```javascript
53889  App.SaveButtonView = Ember.View.extend(Ember.ViewTargetActionSupport, {
53890    action: 'save',
53891    click: function() {
53892      this.triggerAction(); // Sends the `save` action, along with the current context
53893                            // to the current controller
53894    }
53895  });
53896  ```
53897  
53898  The `action` can be provided as properties of an optional object argument
53899  to `triggerAction` as well.
53900  
53901  ```javascript
53902  App.SaveButtonView = Ember.View.extend(Ember.ViewTargetActionSupport, {
53903    click: function() {
53904      this.triggerAction({
53905        action: 'save'
53906      }); // Sends the `save` action, along with the current context
53907          // to the current controller
53908    }
53909  });
53910  ```
53911  
53912  @class ViewTargetActionSupport
53913  @namespace Ember
53914  @extends Ember.TargetActionSupport
53915  @private
53916  */
53917  exports.default = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsTarget_action_support.default, {
53918    /**
53919     @property target
53920     @private
53921    */
53922    target: _emberMetalAlias.default('controller'),
53923    /**
53924     @property actionContext
53925     @private
53926    */
53927    actionContext: _emberMetalAlias.default('context')
53928  });
53929});
53930enifed('ember-views/mixins/visibility_support', ['exports', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/run_loop'], function (exports, _emberMetalMixin, _emberMetalProperty_get, _emberMetalRun_loop) {
53931  /**
53932   @module ember
53933   @submodule ember-views
53934  */
53935  'use strict';
53936
53937  function K() {
53938    return this;
53939  }
53940
53941  /**
53942   @class VisibilitySupport
53943   @namespace Ember
53944   @public
53945  */
53946  var VisibilitySupport = _emberMetalMixin.Mixin.create({
53947    /**
53948      If `false`, the view will appear hidden in DOM.
53949       @property isVisible
53950      @type Boolean
53951      @default null
53952      @public
53953    */
53954    isVisible: true,
53955
53956    becameVisible: K,
53957    becameHidden: K,
53958
53959    /**
53960      When the view's `isVisible` property changes, toggle the visibility
53961      element of the actual DOM element.
53962       @method _isVisibleDidChange
53963      @private
53964    */
53965    _isVisibleDidChange: _emberMetalMixin.observer('isVisible', function () {
53966      if (this._isVisible === _emberMetalProperty_get.get(this, 'isVisible')) {
53967        return;
53968      }
53969      _emberMetalRun_loop.default.scheduleOnce('render', this, this._toggleVisibility);
53970    }),
53971
53972    _toggleVisibility: function () {
53973      var $el = this.$();
53974      var isVisible = _emberMetalProperty_get.get(this, 'isVisible');
53975
53976      if (this._isVisible === isVisible) {
53977        return;
53978      }
53979
53980      // It's important to keep these in sync, even if we don't yet have
53981      // an element in the DOM to manipulate:
53982      this._isVisible = isVisible;
53983
53984      if (!$el) {
53985        return;
53986      }
53987
53988      $el.toggle(isVisible);
53989
53990      if (this._isAncestorHidden()) {
53991        return;
53992      }
53993
53994      if (isVisible) {
53995        this._notifyBecameVisible();
53996      } else {
53997        this._notifyBecameHidden();
53998      }
53999    },
54000
54001    _notifyBecameVisible: function () {
54002      this.trigger('becameVisible');
54003
54004      this.forEachChildView(function (view) {
54005        var isVisible = _emberMetalProperty_get.get(view, 'isVisible');
54006
54007        if (isVisible || isVisible === null) {
54008          view._notifyBecameVisible();
54009        }
54010      });
54011    },
54012
54013    _notifyBecameHidden: function () {
54014      this.trigger('becameHidden');
54015      this.forEachChildView(function (view) {
54016        var isVisible = _emberMetalProperty_get.get(view, 'isVisible');
54017
54018        if (isVisible || isVisible === null) {
54019          view._notifyBecameHidden();
54020        }
54021      });
54022    },
54023
54024    _isAncestorHidden: function () {
54025      var parent = _emberMetalProperty_get.get(this, 'parentView');
54026
54027      while (parent) {
54028        if (_emberMetalProperty_get.get(parent, 'isVisible') === false) {
54029          return true;
54030        }
54031
54032        parent = _emberMetalProperty_get.get(parent, 'parentView');
54033      }
54034
54035      return false;
54036    }
54037  });
54038
54039  exports.default = VisibilitySupport;
54040});
54041enifed('ember-views/streams/class_name_binding', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/utils', 'ember-metal/streams/utils', 'ember-runtime/system/string'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalUtils, _emberMetalStreamsUtils, _emberRuntimeSystemString) {
54042  'use strict';
54043
54044  exports.parsePropertyPath = parsePropertyPath;
54045  exports.classStringForValue = classStringForValue;
54046  exports.streamifyClassNameBinding = streamifyClassNameBinding;
54047
54048  /**
54049    Parse a path and return an object which holds the parsed properties.
54050  
54051    For example a path like "content.isEnabled:enabled:disabled" will return the
54052    following object:
54053  
54054    ```javascript
54055    {
54056      path: "content.isEnabled",
54057      className: "enabled",
54058      falsyClassName: "disabled",
54059      classNames: ":enabled:disabled"
54060    }
54061    ```
54062  
54063    @method parsePropertyPath
54064    @static
54065    @private
54066  */
54067
54068  function parsePropertyPath(path) {
54069    var split = path.split(':');
54070    var propertyPath = split[0];
54071    var classNames = '';
54072    var className, falsyClassName;
54073
54074    // check if the property is defined as prop:class or prop:trueClass:falseClass
54075    if (split.length > 1) {
54076      className = split[1];
54077      if (split.length === 3) {
54078        falsyClassName = split[2];
54079      }
54080
54081      classNames = ':' + className;
54082      if (falsyClassName) {
54083        classNames += ':' + falsyClassName;
54084      }
54085    }
54086
54087    return {
54088      path: propertyPath,
54089      classNames: classNames,
54090      className: className === '' ? undefined : className,
54091      falsyClassName: falsyClassName
54092    };
54093  }
54094
54095  /**
54096    Get the class name for a given value, based on the path, optional
54097    `className` and optional `falsyClassName`.
54098  
54099    - if a `className` or `falsyClassName` has been specified:
54100      - if the value is truthy and `className` has been specified,
54101        `className` is returned
54102      - if the value is falsy and `falsyClassName` has been specified,
54103        `falsyClassName` is returned
54104      - otherwise `null` is returned
54105    - if the value is `true`, the dasherized last part of the supplied path
54106      is returned
54107    - if the value is not `false`, `undefined` or `null`, the `value`
54108      is returned
54109    - if none of the above rules apply, `null` is returned
54110  
54111    @method classStringForValue
54112    @param path
54113    @param val
54114    @param className
54115    @param falsyClassName
54116    @static
54117    @private
54118  */
54119
54120  function classStringForValue(path, val, className, falsyClassName) {
54121    if (_emberMetalUtils.isArray(val)) {
54122      val = _emberMetalProperty_get.get(val, 'length') !== 0;
54123    }
54124
54125    // When using the colon syntax, evaluate the truthiness or falsiness
54126    // of the value to determine which className to return
54127    if (className || falsyClassName) {
54128      if (className && !!val) {
54129        return className;
54130      } else if (falsyClassName && !val) {
54131        return falsyClassName;
54132      } else {
54133        return null;
54134      }
54135
54136      // If value is a Boolean and true, return the dasherized property
54137      // name.
54138    } else if (val === true) {
54139        // Normalize property path to be suitable for use
54140        // as a class name. For exaple, content.foo.barBaz
54141        // becomes bar-baz.
54142        var parts = path.split('.');
54143        return _emberRuntimeSystemString.dasherize(parts[parts.length - 1]);
54144
54145        // If the value is not false, undefined, or null, return the current
54146        // value of the property.
54147      } else if (val !== false && val != null) {
54148          return val;
54149
54150          // Nothing to display. Return null so that the old class is removed
54151          // but no new class is added.
54152        } else {
54153            return null;
54154          }
54155  }
54156
54157  function streamifyClassNameBinding(view, classNameBinding, prefix) {
54158    prefix = prefix || '';
54159    _emberMetalDebug.assert('classNameBindings must not have spaces in them. Multiple class name bindings can be provided as elements of an array, e.g. [\'foo\', \':bar\']', classNameBinding.indexOf(' ') === -1);
54160    var parsedPath = parsePropertyPath(classNameBinding);
54161    if (parsedPath.path === '') {
54162      return classStringForValue(parsedPath.path, true, parsedPath.className, parsedPath.falsyClassName);
54163    } else {
54164      var pathValue = view.getStream(prefix + parsedPath.path);
54165      return _emberMetalStreamsUtils.chain(pathValue, function () {
54166        return classStringForValue(parsedPath.path, _emberMetalStreamsUtils.read(pathValue), parsedPath.className, parsedPath.falsyClassName);
54167      });
54168    }
54169  }
54170});
54171enifed('ember-views/streams/should_display', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-runtime/utils', 'ember-metal/stream
54171s/stream', 'ember-metal/streams/utils'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberRuntimeUtils, _emberMetalStreamsStream, _emberMetalStreamsUtils) {
54172  'use strict';
54173
54174  exports.default = shouldDisplay;
54175
54176  var ShouldDisplayStream = _emberMetalStreamsStream.default.extend({
54177    init: function (predicate) {
54178      _emberMetalDebug.assert('ShouldDisplayStream error: predicate must be a stream', _emberMetalStreamsUtils.isStream(predicate));
54179
54180      var isTruthy = predicate.get('isTruthy');
54181
54182      this.init();
54183      this.predicate = predicate;
54184      this.isTruthy = isTruthy;
54185      this.lengthDep = null;
54186
54187      this.addDependency(predicate);
54188      this.addDependency(isTruthy);
54189    },
54190
54191    compute: function () {
54192      var truthy = _emberMetalStreamsUtils.read(this.isTruthy);
54193
54194      if (typeof truthy === 'boolean') {
54195        return truthy;
54196      }
54197
54198      if (this.lengthDep) {
54199        return this.lengthDep.getValue() !== 0;
54200      } else {
54201        return !!_emberMetalStreamsUtils.read(this.predicate);
54202      }
54203    },
54204
54205    revalidate: function () {
54206      if (_emberRuntimeUtils.isArray(_emberMetalStreamsUtils.read(this.predicate))) {
54207        if (!this.lengthDep) {
54208          this.lengthDep = this.addMutableDependency(this.predicate.get('length'));
54209        }
54210      } else {
54211        if (this.lengthDep) {
54212          this.lengthDep.destroy();
54213          this.lengthDep = null;
54214        }
54215      }
54216    }
54217  });
54218
54219  function shouldDisplay(predicate) {
54220    if (_emberMetalStreamsUtils.isStream(predicate)) {
54221      return new ShouldDisplayStream(predicate);
54222    }
54223
54224    var type = typeof predicate;
54225
54226    if (type === 'boolean') {
54227      return predicate;
54228    }
54229
54230    if (type && type === 'object' && predicate !== null) {
54231      var isTruthy = _emberMetalProperty_get.get(predicate, 'isTruthy');
54232      if (typeof isTruthy === 'boolean') {
54233        return isTruthy;
54234      }
54235    }
54236
54237    if (_emberRuntimeUtils.isArray(predicate)) {
54238      return _emberMetalProperty_get.get(predicate, 'length') !== 0;
54239    } else {
54240      return !!predicate;
54241    }
54242  }
54243});
54244enifed('ember-views/streams/utils', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/streams/utils', 'ember-runtime/mixins/controller'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalStreamsUtils, _emberRuntimeMixinsController) {
54245  'use strict';
54246
54247  exports.readViewFactory = readViewFactory;
54248  exports.readComponentFactory = readComponentFactory;
54249  exports.readUnwrappedModel = readUnwrappedModel;
54250
54251  function readViewFactory(object, owner) {
54252    var value = _emberMetalStreamsUtils.read(object);
54253    var viewClass;
54254
54255    if (typeof value === 'string') {
54256      _emberMetalDebug.assert('View requires an owner to resolve views not passed in through the context', !!owner);
54257      viewClass = owner._lookupFactory('view:' + value);
54258    } else {
54259      viewClass = value;
54260    }
54261
54262    _emberMetalDebug.assert(value + ' must be a subclass or an instance of Ember.View, not ' + viewClass, (function (viewClass) {
54263      return viewClass && (viewClass.isViewFactory || viewClass.isView || viewClass.isComponentFactory || viewClass.isComponent);
54264    })(viewClass));
54265
54266    return viewClass;
54267  }
54268
54269  function readComponentFactory(nameOrStream, owner) {
54270    var name = _emberMetalStreamsUtils.read(nameOrStream);
54271    var componentLookup = owner.lookup('component-lookup:main');
54272    _emberMetalDebug.assert('Could not find \'component-lookup:main\' on the provided container, ' + 'which is necessary for performing component lookups', componentLookup);
54273
54274    return componentLookup.lookupFactory(name, owner);
54275  }
54276
54277  function readUnwrappedModel(object) {
54278    if (_emberMetalStreamsUtils.isStream(object)) {
54279      var result = object.value();
54280
54281      // If the path is exactly `controller` then we don't unwrap it.
54282      if (object.label !== 'controller') {
54283        while (_emberRuntimeMixinsController.default.detect(result)) {
54284          result = _emberMetalProperty_get.get(result, 'model');
54285        }
54286      }
54287
54288      return result;
54289    } else {
54290      return object;
54291    }
54292  }
54293});
54294enifed("ember-views/system/action_manager", ["exports"], function (exports) {
54295  /**
54296  @module ember
54297  @submodule ember-views
54298  */
54299
54300  "use strict";
54301
54302  function ActionManager() {}
54303
54304  /**
54305    Global action id hash.
54306  
54307    @private
54308    @property registeredActions
54309    @type Object
54310  */
54311  ActionManager.registeredActions = {};
54312
54313  exports.default = ActionManager;
54314});
54315enifed('ember-views/system/build-component-template', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/assign', 'htmlbars-runtime', 'ember-htmlbars/hooks/get-value', 'ember-metal/stream
54315s/utils'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalAssign, _htmlbarsRuntime, _emberHtmlbarsHooksGetValue, _emberMetalStreamsUtils) {
54316  'use strict';
54317
54318  exports.default = buildComponentTemplate;
54319  exports.buildHTMLTemplate = buildHTMLTemplate;
54320
54321  function buildComponentTemplate(_ref, attrs, content) {
54322    var component = _ref.component;
54323    var tagName = _ref.tagName;
54324    var layout = _ref.layout;
54325    var isAngleBracket = _ref.isAngleBracket;
54326    var isComponentElement = _ref.isComponentElement;
54327    var outerAttrs = _ref.outerAttrs;
54328
54329    var blockToRender, meta;
54330
54331    if (component === undefined) {
54332      component = null;
54333    }
54334
54335    if (layout && layout.raw) {
54336      var yieldTo = createContentBlocks(content.templates, content.scope, content.self, component);
54337      blockToRender = createLayoutBlock(layout.raw, yieldTo, content.self, component, attrs);
54338      meta = layout.raw.meta;
54339    } else if (content.templates && content.templates.default) {
54340      blockToRender = createContentBlock(content.templates.default, content.scope, content.self, component);
54341      meta = content.templates.default.meta;
54342    }
54343
54344    if (component && !component._isAngleBracket || isComponentElement) {
54345      tagName = tagName || tagNameFor(component);
54346
54347      // If this is not a tagless component, we need to create the wrapping
54348      // element. We use `manualElement` to create a template that represents
54349      // the wrapping element and yields to the previous block.
54350      if (tagName !== '') {
54351        if (isComponentElement) {
54352          attrs = mergeAttrs(attrs, outerAttrs);
54353        }
54354        var attributes = normalizeComponentAttributes(component, isAngleBracket, attrs);
54355        var elementTemplate = _htmlbarsRuntime.internal.manualElement(tagName, attributes);
54356        elementTemplate.meta = meta;
54357
54358        blockToRender = createElementBlock(elementTemplate, blockToRender, component);
54359      } else {
54360        validateTaglessComponent(component);
54361      }
54362    }
54363
54364    // tagName is one of:
54365    //   * `undefined` if no component is present
54366    //   * the falsy value "" if set explicitly on the component
54367    //   * an actual tagName set explicitly on the component
54368    return { createdElement: !!tagName, block: blockToRender };
54369  }
54370
54371  function buildHTMLTemplate(tagName, _attrs, content) {
54372    var attrs = {};
54373
54374    for (var prop in _attrs) {
54375      var val = _attrs[prop];
54376
54377      if (typeof val === 'string') {
54378        attrs[prop] = val;
54379      } else {
54380        attrs[prop] = ['value', val];
54381      }
54382    }
54383
54384    var childTemplate = content.templates.default;
54385    var elementTemplate = _htmlbarsRuntime.internal.manualElement(tagName, attrs, childTemplate.isEmpty);
54386
54387    if (childTemplate.isEmpty) {
54388      return blockFor(elementTemplate, { scope: content.scope });
54389    } else {
54390      var blockToRender = blockFor(content.templates.default, content);
54391      return blockFor(elementTemplate, { yieldTo: blockToRender, scope: content.scope });
54392    }
54393  }
54394
54395  function mergeAttrs(innerAttrs, outerAttrs) {
54396    var result = _emberMetalAssign.default({}, innerAttrs, outerAttrs);
54397
54398    if (innerAttrs.class && outerAttrs.class) {
54399      result.class = ['subexpr', '-join-classes', [['value', innerAttrs.class], ['value', outerAttrs.class]], []];
54400    }
54401
54402    return result;
54403  }
54404
54405  function blockFor(template, options) {
54406    _emberMetalDebug.assert('BUG: Must pass a template to blockFor', !!template);
54407    return _htmlbarsRuntime.internal.blockFor(_htmlbarsRuntime.render, template, options);
54408  }
54409
54410  function createContentBlock(template, scope, self, component) {
54411    _emberMetalDebug.assert('BUG: buildComponentTemplate can take a scope or a self, but not both', !(scope && self));
54412
54413    return blockFor(template, {
54414      scope: scope,
54415      self: self,
54416      options: { view: component }
54417    });
54418  }
54419
54420  function createContentBlocks(templates, scope, self, component) {
54421    if (!templates) {
54422      return;
54423    }
54424    var output = {};
54425    for (var name in templates) {
54426      if (templates.hasOwnProperty(name)) {
54427        var template = templates[name];
54428        if (template) {
54429          output[name] = createContentBlock(templates[name], scope, self, component);
54430        }
54431      }
54432    }
54433    return output;
54434  }
54435
54436  function createLayoutBlock(template, yieldTo, self, component, attrs) {
54437    return blockFor(template, {
54438      yieldTo: yieldTo,
54439
54440      // If we have an old-style Controller with a template it will be
54441      // passed as our `self` argument, and it should be the context for
54442      // the template. Otherwise, we must have a real Component and it
54443      // should be its own template context.
54444      self: self || component,
54445
54446      options: { view: component, attrs: attrs }
54447    });
54448  }
54449
54450  function createElementBlock(template, yieldTo, component) {
54451    return blockFor(template, {
54452      yieldTo: yieldTo,
54453      self: component,
54454      options: { view: component }
54455    });
54456  }
54457
54458  function tagNameFor(view) {
54459    var tagName = view.tagName;
54460
54461    if (tagName !== null && typeof tagName === 'object' && tagName.isDescriptor) {
54462      tagName = _emberMetalProperty_get.get(view, 'tagName');
54463      _emberMetalDebug.deprecate('In the future using a computed property to define tagName will not be permitted. That value will be respected, but changing it will not update the element.', !tagName, { id: 'ember-views.computed-tag-name', until: '2.0.0' });
54464    }
54465
54466    if (tagName === null || tagName === undefined) {
54467      tagName = view._defaultTagName || 'div';
54468    }
54469
54470    return tagName;
54471  }
54472
54473  // Takes a component and builds a normalized set of attribute
54474  // bindings consumable by HTMLBars' `attribute` hook.
54475  function normalizeComponentAttributes(component, isAngleBracket, attrs) {
54476    var normalized = {};
54477    var attributeBindings = component.attributeBindings;
54478    var streamBasePath = component.isComponent ? '' : 'view.';
54479    var i, l;
54480
54481    if (attrs.id && _emberHtmlbarsHooksGetValue.default(attrs.id)) {
54482      // Do not allow binding to the `id`
54483      normalized.id = _emberHtmlbarsHooksGetValue.default(attrs.id);
54484      component.elementId = normalized.id;
54485    } else {
54486      normalized.id = component.elementId;
54487    }
54488
54489    if (attributeBindings) {
54490      for (i = 0, l = attributeBindings.length; i < l; i++) {
54491        var attr = attributeBindings[i];
54492        var colonIndex = attr.indexOf(':');
54493
54494        var attrName, expression;
54495        if (colonIndex !== -1) {
54496          var attrProperty = attr.substring(0, colonIndex);
54497          attrName = attr.substring(colonIndex + 1);
54498          expression = ['get', '' + streamBasePath + attrProperty];
54499        } else if (attrs[attr]) {
54500          // TODO: For compatibility with 1.x, we probably need to `set`
54501          // the component's attribute here if it is a CP, but we also
54502          // probably want to suspend observers and allow the
54503          // willUpdateAttrs logic to trigger observers at the correct time.
54504          attrName = attr;
54505          expression = ['value', attrs[attr]];
54506        } else {
54507          attrName = attr;
54508          expression = ['get', '' + streamBasePath + attr];
54509        }
54510
54511        _emberMetalDebug.assert('You cannot use class as an attributeBinding, use classNameBindings instead.', attrName !== 'class');
54512
54513        normalized[attrName] = expression;
54514      }
54515    }
54516
54517    if (isAngleBracket) {
54518      for (var prop in attrs) {
54519        var val = attrs[prop];
54520        if (!val) {
54521          continue;
54522        }
54523
54524        if (typeof val === 'string' || val.isConcat) {
54525          normalized[prop] = ['value', val];
54526        }
54527      }
54528    }
54529
54530    if (attrs.tagName) {
54531      component.tagName = attrs.tagName;
54532    }
54533
54534    var normalizedClass = normalizeClass(component, attrs, streamBasePath);
54535
54536    if (normalizedClass) {
54537      normalized.class = normalizedClass;
54538    }
54539
54540    if (_emberMetalProperty_get.get(component, 'isVisible') === false) {
54541      var hiddenStyle = ['subexpr', '-html-safe', ['display: none;'], []];
54542      var existingStyle = normalized.style;
54543
54544      if (existingStyle) {
54545        normalized.style = ['subexpr', 'concat', [existingStyle, ' ', hiddenStyle], []];
54546      } else {
54547        normalized.style = hiddenStyle;
54548      }
54549    }
54550
54551    return normalized;
54552  }
54553
54554  function normalizeClass(component, attrs, streamBasePath) {
54555    var i, l;
54556    var normalizedClass = [];
54557    var classNames = _emberMetalProperty_get.get(component, 'classNames');
54558    var classNameBindings = _emberMetalProperty_get.get(component, 'classNameBindings');
54559
54560    if (attrs.class) {
54561      if (_emberMetalStreamsUtils.isStream(attrs.class)) {
54562        normalizedClass.push(['subexpr', '-normalize-class', [['value', attrs.class.path], ['value', attrs.class]], []]);
54563      } else {
54564        normalizedClass.push(attrs.class);
54565      }
54566    }
54567
54568    if (attrs.classBinding) {
54569      normalizeClasses(attrs.classBinding.split(' '), normalizedClass, streamBasePath);
54570    }
54571
54572    if (classNames) {
54573      for (i = 0, l = classNames.length; i < l; i++) {
54574        normalizedClass.push(classNames[i]);
54575      }
54576    }
54577
54578    if (classNameBindings) {
54579      normalizeClasses(classNameBindings, normalizedClass, streamBasePath);
54580    }
54581
54582    if (normalizeClass.length) {
54583      return ['subexpr', '-join-classes', normalizedClass, []];
54584    }
54585  }
54586
54587  function normalizeClasses(classes, output, streamBasePath) {
54588    var i, l;
54589
54590    for (i = 0, l = classes.length; i < l; i++) {
54591      var className = classes[i];
54592      _emberMetalDebug.assert('classNameBindings must not have spaces in them. Multiple class name bindings can be provided as elements of an array, e.g. [\'foo\', \':bar\']', className.indexOf(' ') === -1);
54593
54594      var _className$split = className.split(':');
54595
54596      var propName = _className$split[0];
54597      var activeClass = _className$split[1];
54598      var inactiveClass = _className$split[2];
54599
54600      // Legacy :class microsyntax for static class names
54601      if (propName === '') {
54602        output.push(activeClass);
54603        continue;
54604      }
54605
54606      var prop = '' + streamBasePath + propName;
54607
54608      output.push(['subexpr', '-normalize-class', [
54609      // params
54610      ['value', propName], ['get', prop]], [
54611      // hash
54612      'activeClass', activeClass, 'inactiveClass', inactiveClass]]);
54613    }
54614  }
54615
54616  function validateTaglessComponent(component) {
54617    _emberMetalDebug.assert('You cannot use `classNameBindings` on a tag-less component: ' + component.toString(), (function () {
54618      var classNameBindings = component.classNameBindings;
54619      return !classNameBindings || classNameBindings.length === 0;
54620    })());
54621  }
54622});
54623enifed('ember-views/system/event_dispatcher', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-views/system/jquery', 'ember-views/system/action_manager', 'ember-views/views/view', 'ember-metal/assign', 'container/owner', 'ember-metal/environment'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberViewsSystemJquery, _emberViewsSystemAction_manager, _emberViewsViewsView, _emberMetalAssign, _containerOwner, _emberMetalEnvironment) {
54624  /**
54625  @module ember
54626  @submodule ember-views
54627  */
54628
54629  'use strict';
54630
54631  var ROOT_ELEMENT_CLASS = 'ember-application';
54632  var ROOT_ELEMENT_SELECTOR = '.' + ROOT_ELEMENT_CLASS;
54633
54634  /**
54635    `Ember.EventDispatcher` handles delegating browser events to their
54636    corresponding `Ember.Views.` For example, when you click on a view,
54637    `Ember.EventDispatcher` ensures that that view's `mouseDown` method gets
54638    called.
54639  
54640    @class EventDispatcher
54641    @namespace Ember
54642    @private
54643    @extends Ember.Object
54644  */
54645  exports.default = _emberRuntimeSystemObject.default.extend({
54646
54647    /**
54648      The set of events names (and associated handler function names) to be setup
54649      and dispatched by the `EventDispatcher`. Modifications to this list can be done
54650      at setup time, generally via the `Ember.Application.customEvents` hash.
54651       To add new events to be listened to:
54652       ```javascript
54653      var App = Ember.Application.create({
54654        customEvents: {
54655          paste: 'paste'
54656        }
54657      });
54658      ```
54659       To prevent default events from being listened to:
54660       ```javascript
54661      var App = Ember.Application.create({
54662        customEvents: {
54663          mouseenter: null,
54664          mouseleave: null
54665        }
54666      });
54667      ```
54668      @property events
54669      @type Object
54670      @private
54671    */
54672    events: {
54673      touchstart: 'touchStart',
54674      touchmove: 'touchMove',
54675      touchend: 'touchEnd',
54676      touchcancel: 'touchCancel',
54677      keydown: 'keyDown',
54678      keyup: 'keyUp',
54679      keypress: 'keyPress',
54680      mousedown: 'mouseDown',
54681      mouseup: 'mouseUp',
54682      contextmenu: 'contextMenu',
54683      click: 'click',
54684      dblclick: 'doubleClick',
54685      mousemove: 'mouseMove',
54686      focusin: 'focusIn',
54687      focusout: 'focusOut',
54688      mouseenter: 'mouseEnter',
54689      mouseleave: 'mouseLeave',
54690      submit: 'submit',
54691      input: 'input',
54692      change: 'change',
54693      dragstart: 'dragStart',
54694      drag: 'drag',
54695      dragenter: 'dragEnter',
54696      dragleave: 'dragLeave',
54697      dragover: 'dragOver',
54698      drop: 'drop',
54699      dragend: 'dragEnd'
54700    },
54701
54702    /**
54703      The root DOM element to which event listeners should be attached. Event
54704      listeners will be attached to the document unless this is overridden.
54705       Can be specified as a DOMElement or a selector string.
54706       The default body is a string since this may be evaluated before document.body
54707      exists in the DOM.
54708       @private
54709      @property rootElement
54710      @type DOMElement
54711      @default 'body'
54712    */
54713    rootElement: 'body',
54714
54715    /**
54716      It enables events to be dispatched to the view's `eventManager.` When present,
54717      this object takes precedence over handling of events on the view itself.
54718       Note that most Ember applications do not use this feature. If your app also
54719      does not use it, consider setting this property to false to gain some performance
54720      improvement by allowing the EventDispatcher to skip the search for the
54721      `eventManager` on the view tree.
54722       ```javascript
54723      var EventDispatcher = Em.EventDispatcher.extend({
54724        events: {
54725            click       : 'click',
54726            focusin     : 'focusIn',
54727            focusout    : 'focusOut',
54728            change      : 'change'
54729        },
54730        canDispatchToEventManager: false
54731      });
54732      container.register('event_dispatcher:main', EventDispatcher);
54733      ```
54734       @property canDispatchToEventManager
54735      @type boolean
54736      @default 'true'
54737      @since 1.7.0
54738      @private
54739    */
54740    canDispatchToEventManager: true,
54741
54742    init: function () {
54743      this._super();
54744      _emberMetalDebug.assert('EventDispatcher should never be instantiated in fastboot mode. Please report this as an Ember bug.', _emberMetalEnvironment.default.hasDOM);
54745    },
54746
54747    /**
54748      Sets up event listeners for standard browser events.
54749       This will be called after the browser sends a `DOMContentReady` event. By
54750      default, it will set up all of the listeners on the document body. If you
54751      would like to register the listeners on a different element, set the event
54752      dispatcher's `root` property.
54753       @private
54754      @method setup
54755      @param addedEvents {Object}
54756    */
54757    setup: function (addedEvents, rootElement) {
54758      var event;
54759      var events = this._finalEvents = _emberMetalAssign.default({}, _emberMetalProperty_get.get(this, 'events'), addedEvents);
54760
54761      if (!_emberMetalIs_none.default(rootElement)) {
54762        _emberMetalProperty_set.set(this, 'rootElement', rootElement);
54763      }
54764
54765      rootElement = _emberViewsSystemJquery.default(_emberMetalProperty_get.get(this, 'rootElement'));
54766
54767      _emberMetalDebug.assert('You cannot use the same root element (' + (rootElement.selector || rootElement[0].tagName) + ') multiple times in an Ember.Application', !rootElement.is(ROOT_ELEMENT_SELECTOR));
54768      _emberMetalDebug.assert('You cannot make a new Ember.Application using a root element that is a descendent of an existing Ember.Application', !rootElement.closest(ROOT_ELEMENT_SELECTOR).length);
54769      _emberMetalDebug.assert('You cannot make a new Ember.Application using a root element that is an ancestor of an existing Ember.Application', !rootElement.find(ROOT_ELEMENT_SELECTOR).length);
54770
54771      rootElement.addClass(ROOT_ELEMENT_CLASS);
54772
54773      _emberMetalDebug.assert('Unable to add \'' + ROOT_ELEMENT_CLASS + '\' class to rootElement. Make sure you set rootElement to the body or an element in the body.', rootElement.is(ROOT_ELEMENT_SELECTOR));
54774
54775      for (event in events) {
54776        if (events.hasOwnProperty(event)) {
54777          this.setupHandler(rootElement, event, events[event]);
54778        }
54779      }
54780    },
54781
54782    /**
54783      Registers an event listener on the rootElement. If the given event is
54784      triggered, the provided event handler will be triggered on the target view.
54785       If the target view does not implement the event handler, or if the handler
54786      returns `false`, the parent view will be called. The event will continue to
54787      bubble to each successive parent view until it reaches the top.
54788       @private
54789      @method setupHandler
54790      @param {Element} rootElement
54791      @param {String} event the browser-originated event to listen to
54792      @param {String} eventName the name of the method to call on the view
54793    */
54794    setupHandler: function (rootElement, event, eventName) {
54795      var self = this;
54796
54797      var owner = _containerOwner.getOwner(this);
54798      var viewRegistry = owner && owner.lookup('-view-registry:main') || _emberViewsViewsView.default.views;
54799
54800      if (eventName === null) {
54801        return;
54802      }
54803
54804      rootElement.on(event + '.ember', '.ember-view', function (evt, triggeringManager) {
54805        var view = viewRegistry[this.id];
54806        var result = true;
54807
54808        var manager = self.canDispatchToEventManager ? self._findNearestEventManager(view, eventName) : null;
54809
54810        if (manager && manager !== triggeringManager) {
54811          result = self._dispatchEvent(manager, evt, eventName, view);
54812        } else if (view) {
54813          result = self._bubbleEvent(view, evt, eventName);
54814        }
54815
54816        return result;
54817      });
54818
54819      rootElement.on(event + '.ember', '[data-ember-action]', function (evt) {
54820        var actionId = _emberViewsSystemJquery.default(evt.currentTarget).attr('data-ember-action');
54821        var actions = _emberViewsSystemAction_manager.default.registeredActions[actionId];
54822
54823        // We have to check for actions here since in some cases, jQuery will trigger
54824        // an event on `removeChild` (i.e. focusout) after we've already torn down the
54825        // action handlers for the view.
54826        if (!actions) {
54827          return;
54828        }
54829
54830        for (var index = 0, _length = actions.length; index < _length; index++) {
54831          var action = actions[index];
54832
54833          if (action && action.eventName === eventName) {
54834            return action.handler(evt);
54835          }
54836        }
54837      });
54838    },
54839
54840    _findNearestEventManager: function (view, eventName) {
54841      var manager = null;
54842
54843      while (view) {
54844        manager = _emberMetalProperty_get.get(view, 'eventManager');
54845        if (manager && manager[eventName]) {
54846          break;
54847        }
54848
54849        view = _emberMetalProperty_get.get(view, 'parentView');
54850      }
54851
54852      return manager;
54853    },
54854
54855    _dispatchEvent: function (object, evt, eventName, view) {
54856      var result = true;
54857
54858      var handler = object[eventName];
54859      if (typeof handler === 'function') {
54860        result = _emberMetalRun_loop.default(object, handler, evt, view);
54861        // Do not preventDefault in eventManagers.
54862        evt.stopPropagation();
54863      } else {
54864        result = this._bubbleEvent(view, evt, eventName);
54865      }
54866
54867      return result;
54868    },
54869
54870    _bubbleEvent: function (view, evt, eventName) {
54871      return view.handleEvent(eventName, evt);
54872    },
54873
54874    destroy: function () {
54875      var rootElement = _emberMetalProperty_get.get(this, 'rootElement');
54876      _emberViewsSystemJquery.default(rootElement).off('.ember', '**').removeClass(ROOT_ELEMENT_CLASS);
54877      return this._super.apply(this, arguments);
54878    },
54879
54880    toString: function () {
54881      return '(EventDispatcher)';
54882    }
54883  });
54884});
54885enifed('ember-views/system/ext', ['exports', 'ember-metal/run_loop'], function (exports, _emberMetalRun_loop) {
54886  /**
54887  @module ember
54888  @submodule ember-views
54889  */
54890
54891  'use strict';
54892
54893  // Add a new named queue for rendering views that happens
54894  // after bindings have synced, and a queue for scheduling actions
54895  // that should occur after view rendering.
54896  _emberMetalRun_loop.default._addQueue('render', 'actions');
54897  _emberMetalRun_loop.default._addQueue('afterRender', 'render');
54898});
54899enifed('ember-views/system/jquery', ['exports', 'ember-metal/core', 'ember-metal/environment'], function (exports, _emberMetalCore, _emberMetalEnvironment) {
54900  'use strict';
54901
54902  var jQuery;
54903
54904  if (_emberMetalEnvironment.default.hasDOM) {
54905    // mainContext is set in `package/loader/lib/main.js` to the `this` context before entering strict mode
54906    jQuery = _emberMetalCore.default.imports && _emberMetalCore.default.imports.jQuery || mainContext && mainContext.jQuery; //jshint ignore:line
54907    if (!jQuery && typeof require === 'function') {
54908      jQuery = require('jquery');
54909    }
54910
54911    if (jQuery) {
54912      // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents
54913      var dragEvents = ['dragstart', 'drag', 'dragenter', 'dragleave', 'dragover', 'drop', 'dragend'];
54914
54915      // Copies the `dataTransfer` property from a browser event object onto the
54916      // jQuery event object for the specified events
54917      dragEvents.forEach(function (eventName) {
54918        jQuery.event.fixHooks[eventName] = {
54919          props: ['dataTransfer']
54920        };
54921      });
54922    }
54923  }
54924
54925  exports.default = jQuery;
54926});
54927
54928// ES6TODO: the functions on EnumerableUtils need their own exports
54929enifed('ember-views/system/lookup_partial', ['exports', 'ember-metal/debug', 'ember-metal/error'], function (exports, _emberMetalDebug, _emberMetalError) {
54930  'use strict';
54931
54932  exports.default = lookupPartial;
54933
54934  function lookupPartial(env, templateName) {
54935    if (templateName == null) {
54936      return;
54937    }
54938
54939    var nameParts = templateName.split('/');
54940    var lastPart = nameParts[nameParts.length - 1];
54941
54942    nameParts[nameParts.length - 1] = '_' + lastPart;
54943
54944    var underscoredName = nameParts.join('/');
54945    var template = templateFor(env, underscoredName, templateName);
54946
54947    _emberMetalDebug.assert('Unable to find partial with name "' + templateName + '"', !!template);
54948
54949    return template;
54950  }
54951
54952  function templateFor(env, underscored, name) {
54953    if (!name) {
54954      return;
54955    }
54956    _emberMetalDebug.assert('templateNames are not allowed to contain periods: ' + name, name.indexOf('.') === -1);
54957
54958    if (!env.owner) {
54959      throw new _emberMetalError.default('Container was not found when looking up a views template. ' + 'This is most likely due to manually instantiating an Ember.View. ' + 'See: http://git.io/EKPpnA');
54960    }
54961
54962    return env.owner.lookup('template:' + underscored) || env.owner.lookup('template:' + name);
54963  }
54964});
54965enifed('ember-views/system/platform', ['exports', 'ember-metal/environment'], function (exports, _emberMetalEnvironment) {
54966  'use strict';
54967
54968  // IE 6/7 have bugs around setting names on inputs during creation.
54969  // From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
54970  // "To include the NAME attribute at run time on objects created with the createElement method, use the eTag."
54971  var canSetNameOnInputs = _emberMetalEnvironment.default.hasDOM && (function () {
54972    var div = document.createElement('div');
54973    var el = document.createElement('input');
54974
54975    el.setAttribute('name', 'foo');
54976    div.appendChild(el);
54977
54978    return !!div.innerHTML.match('foo');
54979  })();
54980  exports.canSetNameOnInputs = canSetNameOnInputs;
54981});
54982enifed("ember-views/system/utils", ["exports"], function (exports) {
54983  /**
54984  @module ember
54985  @submodule ember-views
54986  */
54987
54988  "use strict";
54989
54990  exports.isSimpleClick = isSimpleClick;
54991  exports.getViewClientRects = getViewClientRects;
54992  exports.getViewBoundingClientRect = getViewBoundingClientRect;
54993
54994  function isSimpleClick(event) {
54995    var modifier = event.shiftKey || event.metaKey || event.altKey || event.ctrlKey;
54996    var secondaryClick = event.which > 1; // IE9 may return undefined
54997
54998    return !modifier && !secondaryClick;
54999  }
55000
55001  /**
55002    @private
55003    @method getViewRange
55004    @param {Ember.View} view
55005  */
55006  function getViewRange(view) {
55007    var range = document.createRange();
55008    range.setStartBefore(view._renderNode.firstNode);
55009    range.setEndAfter(view._renderNode.lastNode);
55010    return range;
55011  }
55012
55013  /**
55014    `getViewClientRects` provides information about the position of the border
55015    box edges of a view relative to the viewport.
55016  
55017    It is only intended to be used by development tools like the Ember Inspector
55018    and may not work on older browsers.
55019  
55020    @private
55021    @method getViewClientRects
55022    @param {Ember.View} view
55023  */
55024
55025  function getViewClientRects(view) {
55026    var range = getViewRange(view);
55027    return range.getClientRects();
55028  }
55029
55030  /**
55031    `getViewBoundingClientRect` provides information about the position of the
55032    bounding border box edges of a view relative to the viewport.
55033  
55034    It is only intended to be used by development tools like the Ember Inpsector
55035    and may not work on older browsers.
55036  
55037    @private
55038    @method getViewBoundingClientRect
55039    @param {Ember.View} view
55040  */
55041
55042  function getViewBoundingClientRect(view) {
55043    var range = getViewRange(view);
55044    return range.getBoundingClientRect();
55045  }
55046});
55047enifed('ember-views/views/checkbox', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/components/component'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberViewsComponentsComponent) {
55048  'use strict';
55049
55050  /**
55051  @module ember
55052  @submodule ember-views
55053  */
55054
55055  /**
55056    The internal class used to create text inputs when the `{{input}}`
55057    helper is used with `type` of `checkbox`.
55058  
55059    See [Ember.Templates.helpers.input](/api/classes/Ember.Templates.helpers.html#method_input)  for usage details.
55060  
55061    ## Direct manipulation of `checked`
55062  
55063    The `checked` attribute of an `Ember.Checkbox` object should always be set
55064    through the Ember object or by interacting with its rendered element
55065    representation via the mouse, keyboard, or touch. Updating the value of the
55066    checkbox via jQuery will result in the checked value of the object and its
55067    element losing synchronization.
55068  
55069    ## Layout and LayoutName properties
55070  
55071    Because HTML `input` elements are self closing `layout` and `layoutName`
55072    properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s
55073    layout section for more information.
55074  
55075    @class Checkbox
55076    @namespace Ember
55077    @extends Ember.Component
55078    @public
55079  */
55080  exports.default = _emberViewsComponentsComponent.default.extend({
55081    instrumentDisplay: '{{input type="checkbox"}}',
55082
55083    classNames: ['ember-checkbox'],
55084
55085    tagName: 'input',
55086
55087    attributeBindings: ['type', 'checked', 'indeterminate', 'disabled', 'tabindex', 'name', 'autofocus', 'required', 'form'],
55088
55089    type: 'checkbox',
55090    checked: false,
55091    disabled: false,
55092    indeterminate: false,
55093
55094    didInsertElement: function () {
55095      this._super.apply(this, arguments);
55096      _emberMetalProperty_get.get(this, 'element').indeterminate = !!_emberMetalProperty_get.get(this, 'indeterminate');
55097    },
55098
55099    change: function () {
55100      _emberMetalProperty_set.set(this, 'checked', this.$().prop('checked'));
55101    }
55102  });
55103});
55104enifed('ember-views/views/collection_view', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-views/views/container_view', 'ember-views/views/view', 'ember-runtime/mixins/array', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/computed', 'ember-metal/mixin', 'ember-views/streams/utils', 'ember-views/mixins/empty_view_support', 'container/owner'], function (exports, _emberMetalCore, _emberMetalDebug, _emberViewsViewsContainer_view, _emberViewsViewsView, _emberRuntimeMixinsArray, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalComputed, _emberMetalMixin, _emberViewsStreamsUtils, _emberViewsMixinsEmpty_view_support, _containerOwner) {
55105  /**
55106  @module ember
55107  @submodule ember-views
55108  */
55109
55110  'use strict';
55111
55112  /**
55113    `Ember.CollectionView` is an `Ember.View` descendent responsible for managing
55114    a collection (an array or array-like object) by maintaining a child view object
55115    and associated DOM representation for each item in the array and ensuring
55116    that child views and their associated rendered HTML are updated when items in
55117    the array are added, removed, or replaced.
55118  
55119    ## Setting content
55120  
55121    The managed collection of objects is referenced as the `Ember.CollectionView`
55122    instance's `content` property.
55123  
55124    ```javascript
55125    someItemsView = Ember.CollectionView.create({
55126      content: ['A', 'B','C']
55127    })
55128    ```
55129  
55130    The view for each item in the collection will have its `content` property set
55131    to the item.
55132  
55133    ## Specifying `itemViewClass`
55134  
55135    By default the view class for each item in the managed collection will be an
55136    instance of `Ember.View`. You can supply a different class by setting the
55137    `CollectionView`'s `itemViewClass` property.
55138  
55139    Given the following application code:
55140  
55141    ```javascript
55142    var App = Ember.Application.create();
55143    App.ItemListView = Ember.CollectionView.extend({
55144      classNames: ['a-collection'],
55145      content: ['A','B','C'],
55146      itemViewClass: Ember.View.extend({
55147        template: Ember.HTMLBars.compile("the letter: {{view.content}}")
55148      })
55149    });
55150    ```
55151  
55152    And a simple application template:
55153  
55154    ```handlebars
55155    {{view 'item-list'}}
55156    ```
55157  
55158    The following HTML will result:
55159  
55160    ```html
55161    <div class="ember-view a-collection">
55162      <div class="ember-view">the letter: A</div>
55163      <div class="ember-view">the letter: B</div>
55164      <div class="ember-view">the letter: C</div>
55165    </div>
55166    ```
55167  
55168    ## Automatic matching of parent/child tagNames
55169  
55170    Setting the `tagName` property of a `CollectionView` to any of
55171    "ul", "ol", "table", "thead", "tbody", "tfoot", "tr", or "select" will result
55172    in the item views receiving an appropriately matched `tagName` property.
55173  
55174    Given the following application code:
55175  
55176    ```javascript
55177    var App = Ember.Application.create();
55178    App.UnorderedListView = Ember.CollectionView.create({
55179      tagName: 'ul',
55180      content: ['A','B','C'],
55181      itemViewClass: Ember.View.extend({
55182        template: Ember.HTMLBars.compile("the letter: {{view.content}}")
55183      })
55184    });
55185    ```
55186  
55187    And a simple application template:
55188  
55189    ```handlebars
55190    {{view 'unordered-list-view'}}
55191    ```
55192  
55193    The following HTML will result:
55194  
55195    ```html
55196    <ul class="ember-view a-collection">
55197      <li class="ember-view">the letter: A</li>
55198      <li class="ember-view">the letter: B</li>
55199      <li class="ember-view">the letter: C</li>
55200    </ul>
55201    ```
55202  
55203    Additional `tagName` pairs can be provided by adding to
55204    `Ember.CollectionView.CONTAINER_MAP`. For example:
55205  
55206    ```javascript
55207    Ember.CollectionView.CONTAINER_MAP['article'] = 'section'
55208    ```
55209  
55210    ## Programmatic creation of child views
55211  
55212    For cases where additional customization beyond the use of a single
55213    `itemViewClass` or `tagName` matching is required CollectionView's
55214    `createChildView` method can be overridden:
55215  
55216    ```javascript
55217    App.CustomCollectionView = Ember.CollectionView.extend({
55218      createChildView: function(viewClass, attrs) {
55219        if (attrs.content.kind == 'album') {
55220          viewClass = App.AlbumView;
55221        } else {
55222          viewClass = App.SongView;
55223        }
55224        return this._super(viewClass, attrs);
55225      }
55226    });
55227    ```
55228  
55229    ## Empty View
55230  
55231    You can provide an `Ember.View` subclass to the `Ember.CollectionView`
55232    instance as its `emptyView` property. If the `content` property of a
55233    `CollectionView` is set to `null` or an empty array, an instance of this view
55234    will be the `CollectionView`s only child.
55235  
55236    ```javascript
55237    var App = Ember.Application.create();
55238    App.ListWithNothing = Ember.CollectionView.create({
55239      classNames: ['nothing'],
55240      content: null,
55241      emptyView: Ember.View.extend({
55242        template: Ember.HTMLBars.compile("The collection is empty")
55243      })
55244    });
55245    ```
55246  
55247    And a simple application template:
55248  
55249    ```handlebars
55250    {{view 'list-with-nothing'}}
55251    ```
55252  
55253    The following HTML will result:
55254  
55255    ```html
55256    <div class="ember-view nothing">
55257      <div class="ember-view">
55258        The collection is empty
55259      </div>
55260    </div>
55261    ```
55262  
55263    ## Adding and Removing items
55264  
55265    The `childViews` property of a `CollectionView` should not be directly
55266    manipulated. Instead, add, remove, replace items from its `content` property.
55267    This will trigger appropriate changes to its rendered HTML.
55268  
55269  
55270    @class CollectionView
55271    @namespace Ember
55272    @extends Ember.ContainerView
55273    @uses Ember.EmptyViewSupport
55274    @since Ember 0.9
55275    @private
55276  */
55277  var CollectionView = _emberViewsViewsContainer_view.default.extend(_emberViewsMixinsEmpty_view_support.default, {
55278
55279    /**
55280      A list of items to be displayed by the `Ember.CollectionView`.
55281       @property content
55282      @type Ember.Array
55283      @default null
55284      @private
55285    */
55286    content: null,
55287
55288    /**
55289      @property itemViewClass
55290      @type Ember.View
55291      @default Ember.View
55292      @private
55293    */
55294    itemViewClass: _emberViewsViewsView.default,
55295
55296    /**
55297      Setup a CollectionView
55298       @method init
55299      @private
55300    */
55301    init: function () {
55302      var ret = this._super.apply(this, arguments);
55303      this._contentDidChange();
55304      return ret;
55305    },
55306
55307    /**
55308      Check to make sure that the content has changed, and if so,
55309      update the children directly. This is always scheduled
55310      asynchronously, to allow the element to be created before
55311      bindings have synchronized and vice versa.
55312       @private
55313      @method _contentDidChange
55314    */
55315    _contentDidChange: _emberMetalMixin.observer('content', function () {
55316      var prevContent = this._prevContent;
55317      if (prevContent) {
55318        _emberRuntimeMixinsArray.removeArrayObserver(prevContent, this);
55319      }
55320      var len = prevContent ? _emberMetalProperty_get.get(prevContent, 'length') : 0;
55321      this.arrayWillChange(prevContent, 0, len);
55322
55323      var content = _emberMetalProperty_get.get(this, 'content');
55324
55325      if (content) {
55326        this._prevContent = content;
55327        this._assertArrayLike(content);
55328        _emberRuntimeMixinsArray.addArrayObserver(content, this);
55329      }
55330
55331      len = content ? _emberMetalProperty_get.get(content, 'length') : 0;
55332      this.arrayDidChange(content, 0, null, len);
55333    }),
55334
55335    /**
55336      Ensure that the content implements Ember.Array
55337       @private
55338      @method _assertArrayLike
55339    */
55340    _assertArrayLike: function (content) {
55341      _emberMetalDebug.assert('an Ember.CollectionView\'s content must implement Ember.Array. You passed ' + content, _emberRuntimeMixinsArray.default.detect(content));
55342    },
55343
55344    /**
55345      Removes the content and content observers.
55346       @method destroy
55347      @private
55348    */
55349    destroy: function () {
55350      if (!this._super.apply(this, arguments)) {
55351        return;
55352      }
55353
55354      var content = _emberMetalProperty_get.get(this, 'content');
55355      if (content) {
55356        _emberRuntimeMixinsArray.removeArrayObserver(content, this);
55357      }
55358
55359      if (this._createdEmptyView) {
55360        this._createdEmptyView.destroy();
55361      }
55362
55363      return this;
55364    },
55365
55366    /**
55367      Called when a mutation to the underlying content array will occur.
55368       This method will remove any views that are no longer in the underlying
55369      content array.
55370       Invokes whenever the content array itself will change.
55371       @method arrayWillChange
55372      @param {Array} content the managed collection of objects
55373      @param {Number} start the index at which the changes will occur
55374      @param {Number} removed number of object to be removed from content
55375      @private
55376    */
55377    arrayWillChange: function (content, start, removedCount) {
55378      this.replace(start, removedCount, []);
55379    },
55380
55381    /**
55382      Called when a mutation to the underlying content array occurs.
55383       This method will replay that mutation against the views that compose the
55384      `Ember.CollectionView`, ensuring that the view reflects the model.
55385       This array observer is added in `contentDidChange`.
55386       @method arrayDidChange
55387      @param {Array} content the managed collection of objects
55388      @param {Number} start the index at which the changes occurred
55389      @param {Number} removed number of object removed from content
55390      @param {Number} added number of object added to content
55391      @private
55392    */
55393    arrayDidChange: function (content, start, removed, added) {
55394      var addedViews = [];
55395      var view, item, idx, len, itemViewClass, itemViewProps;
55396
55397      len = content ? _emberMetalProperty_get.get(content, 'length') : 0;
55398
55399      if (len) {
55400        itemViewProps = this._itemViewProps || {};
55401        itemViewClass = this.getAttr('itemViewClass') || _emberMetalProperty_get.get(this, 'itemViewClass');
55402
55403        itemViewClass = _emberViewsStreamsUtils.readViewFactory(itemViewClass, _containerOwner.getOwner(this));
55404
55405        for (idx = start; idx < start + added; idx++) {
55406          item = _emberRuntimeMixinsArray.objectAt(content, idx);
55407          itemViewProps._context = this.keyword ? this.get('context') : item;
55408          itemViewProps.content = item;
55409          itemViewProps.contentIndex = idx;
55410
55411          view = this.createChildView(itemViewClass, itemViewProps);
55412
55413          addedViews.push(view);
55414        }
55415
55416        this.replace(start, 0, addedViews);
55417      }
55418    },
55419
55420    /**
55421      Instantiates a view to be added to the childViews array during view
55422      initialization. You generally will not call this method directly unless
55423      you are overriding `createChildViews()`. Note that this method will
55424      automatically configure the correct settings on the new view instance to
55425      act as a child of the parent.
55426       The tag name for the view will be set to the tagName of the viewClass
55427      passed in.
55428       @method createChildView
55429      @param {Class} viewClass
55430      @param {Object} [attrs] Attributes to add
55431      @return {Ember.View} new instance
55432      @private
55433    */
55434    createChildView: function (_view, attrs) {
55435      var view = this._super(_view, attrs);
55436
55437      var itemTagName = _emberMetalProperty_get.get(view, 'tagName');
55438
55439      if (itemTagName === null || itemTagName === undefined) {
55440        itemTagName = CollectionView.CONTAINER_MAP[_emberMetalProperty_get.get(this, 'tagName')];
55441        _emberMetalProperty_set.set(view, 'tagName', itemTagName);
55442      }
55443
55444      return view;
55445    },
55446
55447    _willRender: function () {
55448      var attrs = this.attrs;
55449      var itemProps = buildItemViewProps(this._itemViewTemplate, attrs);
55450      this._itemViewProps = itemProps;
55451      var childViews = _emberMetalProperty_get.get(this, 'childViews');
55452
55453      for (var i = 0, l = childViews.length; i < l; i++) {
55454        childViews[i].setProperties(itemProps);
55455      }
55456
55457      if ('content' in attrs) {
55458        _emberMetalProperty_set.set(this, 'content', this.getAttr('content'));
55459      }
55460
55461      if ('emptyView' in attrs) {
55462        _emberMetalProperty_set.set(this, 'emptyView', this.getAttr('emptyView'));
55463      }
55464    },
55465
55466    _emptyViewTagName: _emberMetalComputed.computed('tagName', function () {
55467      var tagName = _emberMetalProperty_get.get(this, 'tagName');
55468      return CollectionView.CONTAINER_MAP[tagName] || 'div';
55469    })
55470  });
55471
55472  /**
55473    A map of parent tags to their default child tags. You can add
55474    additional parent tags if you want collection views that use
55475    a particular parent tag to default to a child tag.
55476  
55477    @property CONTAINER_MAP
55478    @type Object
55479    @static
55480    @final
55481    @private
55482  */
55483  CollectionView.CONTAINER_MAP = {
55484    ul: 'li',
55485    ol: 'li',
55486    table: 'tr',
55487    thead: 'tr',
55488    tbody: 'tr',
55489    tfoot: 'tr',
55490    tr: 'td',
55491    select: 'option'
55492  };
55493
55494  var CONTAINER_MAP = CollectionView.CONTAINER_MAP;
55495
55496  exports.CONTAINER_MAP = CONTAINER_MAP;
55497  function buildItemViewProps(template, attrs) {
55498    var props = {};
55499
55500    // Go through options passed to the {{collection}} helper and extract options
55501    // that configure item views instead of the collection itself.
55502    for (var prop in attrs) {
55503      if (prop === 'itemViewClass' || prop === 'itemController' || prop === 'itemClassBinding') {
55504        continue;
55505      }
55506      if (attrs.hasOwnProperty(prop)) {
55507        var match = prop.match(/^item(.)(.*)$/);
55508        if (match) {
55509          var childProp = match[1].toLowerCase() + match[2];
55510
55511          if (childProp === 'class' || childProp === 'classNames') {
55512            props.classNames = [attrs[prop]];
55513          } else {
55514            props[childProp] = attrs[prop];
55515          }
55516
55517          delete attrs[prop];
55518        }
55519      }
55520    }
55521
55522    if (template) {
55523      props.template = template;
55524    }
55525
55526    return props;
55527  }
55528
55529  function viewDeprecationMessage() {
55530    _emberMetalDebug.deprecate('Ember.CollectionView is deprecated. Consult the Deprecations Guide for a migration strategy.', !!_emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT, {
55531      url: 'http://emberjs.com/deprecations/v1.x/#toc_ember-collectionview',
55532      id: 'ember-views.collection-view-deprecated',
55533      until: '2.4.0'
55534    });
55535  }
55536
55537  var DeprecatedCollectionView = CollectionView.extend({
55538    init: function () {
55539      viewDeprecationMessage();
55540      this._super.apply(this, arguments);
55541    }
55542  });
55543
55544  DeprecatedCollectionView.reopen = function () {
55545    viewDeprecationMessage();
55546    CollectionView.reopen.apply(CollectionView, arguments);
55547    return this;
55548  };
55549
55550  DeprecatedCollectionView.CONTAINER_MAP = CONTAINER_MAP;
55551
55552  exports.default = CollectionView;
55553  exports.DeprecatedCollectionView = DeprecatedCollectionView;
55554});
55555enifed('ember-views/views/container_view', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-runtime/mixins/mutable_array', 'ember-runtime/system/native_array', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/mixin', 'ember-metal/events', 'ember-htmlbars/templates/container-view'], function (exports, _emberMetalCore, _emberMetalDebug, _emberRuntimeMixinsMutable_array, _emberRuntimeSystemNative_array, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalMixin, _emberMetalEvents, _emberHtmlbarsTemplatesContainerView) {
55556  'use strict';
55557
55558  _emberHtmlbarsTemplatesContainerView.default.meta.revision = '[email protected]';
55559
55560  /**
55561  @module ember
55562  @submodule ember-views
55563  */
55564
55565  /**
55566    A `ContainerView` is an `Ember.View` subclass that implements `Ember.MutableArray`
55567    allowing programmatic management of its child views.
55568  
55569    ## Setting Initial Child Views
55570  
55571    The initial array of child views can be set in one of two ways. You can
55572    provide a `childViews` property at creation time that contains instance of
55573    `Ember.View`:
55574  
55575    ```javascript
55576    aContainer = Ember.ContainerView.create({
55577      childViews: [Ember.View.create(), Ember.View.create()]
55578    });
55579    ```
55580  
55581    You can also provide a list of property names whose values are instances of
55582    `Ember.View`:
55583  
55584    ```javascript
55585    aContainer = Ember.ContainerView.create({
55586      childViews: ['aView', 'bView', 'cView'],
55587      aView: Ember.View.create(),
55588      bView: Ember.View.create(),
55589      cView: Ember.View.create()
55590    });
55591    ```
55592  
55593    The two strategies can be combined:
55594  
55595    ```javascript
55596    aContainer = Ember.ContainerView.create({
55597      childViews: ['aView', Ember.View.create()],
55598      aView: Ember.View.create()
55599    });
55600    ```
55601  
55602    Each child view's rendering will be inserted into the container's rendered
55603    HTML in the same order as its position in the `childViews` property.
55604  
55605    ## Adding and Removing Child Views
55606  
55607    The container view implements `Ember.MutableArray` allowing programmatic management of its child views.
55608  
55609    To remove a view, pass that view into a `removeObject` call on the container view.
55610  
55611    Given an empty `<body>` the following code
55612  
55613    ```javascript
55614    aContainer = Ember.ContainerView.create({
55615      classNames: ['the-container'],
55616      childViews: ['aView', 'bView'],
55617      aView: Ember.View.create({
55618        template: Ember.HTMLBars.compile("A")
55619      }),
55620      bView: Ember.View.create({
55621        template: Ember.HTMLBars.compile("B")
55622      })
55623    });
55624  
55625    aContainer.appendTo('body');
55626    ```
55627  
55628    Results in the HTML
55629  
55630    ```html
55631    <div class="ember-view the-container">
55632      <div class="ember-view">A</div>
55633      <div class="ember-view">B</div>
55634    </div>
55635    ```
55636  
55637    Removing a view
55638  
55639    ```javascript
55640    aContainer.toArray();  // [aContainer.aView, aContainer.bView]
55641    aContainer.removeObject(aContainer.get('bView'));
55642    aContainer.toArray();  // [aContainer.aView]
55643    ```
55644  
55645    Will result in the following HTML
55646  
55647    ```html
55648    <div class="ember-view the-container">
55649      <div class="ember-view">A</div>
55650    </div>
55651    ```
55652  
55653    Similarly, adding a child view is accomplished by adding `Ember.View` instances to the
55654    container view.
55655  
55656    Given an empty `<body>` the following code
55657  
55658    ```javascript
55659    aContainer = Ember.ContainerView.create({
55660      classNames: ['the-container'],
55661      childViews: ['aView', 'bView'],
55662      aView: Ember.View.create({
55663        template: Ember.HTMLBars.compile("A")
55664      }),
55665      bView: Ember.View.create({
55666        template: Ember.HTMLBars.compile("B")
55667      })
55668    });
55669  
55670    aContainer.appendTo('body');
55671    ```
55672  
55673    Results in the HTML
55674  
55675    ```html
55676    <div class="ember-view the-container">
55677      <div class="ember-view">A</div>
55678      <div class="ember-view">B</div>
55679    </div>
55680    ```
55681  
55682    Adding a view
55683  
55684    ```javascript
55685    AnotherViewClass = Ember.View.extend({
55686      template: Ember.HTMLBars.compile("Another view")
55687    });
55688  
55689    aContainer.toArray();  // [aContainer.aView, aContainer.bView]
55690    aContainer.pushObject(AnotherViewClass.create());
55691    aContainer.toArray(); // [aContainer.aView, aContainer.bView, <AnotherViewClass instance>]
55692    ```
55693  
55694    Will result in the following HTML
55695  
55696    ```html
55697    <div class="ember-view the-container">
55698      <div class="ember-view">A</div>
55699      <div class="ember-view">B</div>
55700      <div class="ember-view">Another view</div>
55701    </div>
55702    ```
55703  
55704    ## Templates and Layout
55705  
55706    A `template`, `templateName`, `defaultTemplate`, `layout`, `layoutName` or
55707    `defaultLayout` property on a container view will not result in the template
55708    or layout being rendered. The HTML contents of a `Ember.ContainerView`'s DOM
55709    representation will only be the rendered HTML of its child views.
55710  
55711    @class ContainerView
55712    @namespace Ember
55713    @extends Ember.View
55714    @deprecated See http://emberjs.com/deprecations/v1.x/#toc_ember-containerview
55715    @private
55716  */
55717  var ContainerView = _emberViewsViewsView.default.extend(_emberRuntimeMixinsMutable_array.default, {
55718    willWatchProperty: function (prop) {
55719      _emberMetalDebug.deprecate('ContainerViews should not be observed as arrays. This behavior will change in future implementations of ContainerView.', !prop.match(/\[]/) && prop.indexOf('@') !== 0, { id: 'ember-views.container-views-array-observed', until: '2.4.0' });
55720    },
55721
55722    init: function () {
55723      var _this = this;
55724
55725      this._super.apply(this, arguments);
55726      this._prevCurrentView = undefined;
55727      var userChildViews = _emberMetalProperty_get.get(this, 'childViews');
55728      _emberMetalDebug.deprecate('Setting `childViews` on a Container is deprecated.', _emberMetalCore.default.isEmpty(userChildViews), { id: 'ember-views.container-child-views', until: '2.4.0' });
55729
55730      // redefine view's childViews property that was obliterated
55731      // 2.0TODO: Don't Ember.A() this so users disabling prototype extensions
55732      // don't pay a penalty.
55733      var childViews = this.childViews = _emberRuntimeSystemNative_array.A();
55734
55735      userChildViews.forEach(function (viewName, idx) {
55736        var view;
55737
55738        if ('string' === typeof viewName) {
55739          view = _emberMetalProperty_get.get(_this, viewName);
55740          view = _this.createChildView(view);
55741          _emberMetalProperty_set.set(_this, viewName, view);
55742        } else {
55743          view = _this.createChildView(viewName);
55744        }
55745
55746        childViews[idx] = view;
55747      });
55748
55749      var currentView = _emberMetalProperty_get.get(this, 'currentView');
55750      if (currentView) {
55751        if (!childViews.length) {
55752          childViews = this.childViews = _emberRuntimeSystemNative_array.A(this.childViews.slice());
55753        }
55754        childViews.push(this.createChildView(currentView));
55755      }
55756
55757      _emberMetalProperty_set.set(this, 'length', childViews.length);
55758    },
55759
55760    // Normally parentView and childViews are managed at render time.  However,
55761    // the ContainerView is an unusual legacy case. People expect to be able to
55762    // push a child view into the ContainerView and have its parentView set
55763    // appropriately. As a result, we link the child nodes ahead of time and
55764    // ignore render-time linking.
55765    appendChild: function (view) {
55766      // This occurs if the view being appended is the empty view, rather than
55767      // a view eagerly inserted into the childViews array.
55768      if (view.parentView !== this) {
55769        this.linkChild(view);
55770      }
55771    },
55772
55773    _currentViewDidChange: _emberMetalMixin.observer('currentView', function () {
55774      var prevView = this._prevCurrentView;
55775      if (prevView) {
55776        prevView.destroy();
55777      }
55778      var currentView = _emberMetalProperty_get.get(this, 'currentView');
55779      this._prevCurrentView = currentView;
55780      if (currentView) {
55781        _emberMetalDebug.assert('You tried to set a current view that already has a parent. Make sure you don\'t have multiple outlets in the same view.', !currentView.parentView);
55782        this.pushObject(currentView);
55783      }
55784    }),
55785
55786    layout: _emberHtmlbarsTemplatesContainerView.default,
55787
55788    replace: function (idx, removedCount) {
55789      var _this2 = this;
55790
55791      var addedViews = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];
55792
55793      var addedCount = _emberMetalProperty_get.get(addedViews, 'length');
55794      var childViews = _emberMetalProperty_get.get(this, 'childViews');
55795
55796      _emberMetalDebug.assert('You can\'t add a child to a container - the child is already a child of another view', (function () {
55797        for (var i = 0, l = addedViews.length; i < l; i++) {
55798          var item = addedViews[i];
55799          if (item.parentView && item.parentView !== _this2) {
55800            return false;
55801          }
55802        }
55803        return true;
55804      })());
55805
55806      this.arrayContentWillChange(idx, removedCount, addedCount);
55807
55808      // Normally parentView and childViews are managed at render time.  However,
55809      // the ContainerView is an unusual legacy case. People expect to be able to
55810      // push a child view into the ContainerView and have its parentView set
55811      // appropriately.
55812      //
55813      // Because of this, we synchronously fix up the parentView/childViews tree
55814      // as soon as views are added or removed, despite the fact that this will
55815      // happen automatically when we render.
55816      var removedViews = childViews.slice(idx, idx + removedCount);
55817      removedViews.forEach(function (view) {
55818        return _this2.unlinkChild(view);
55819      });
55820      addedViews.forEach(function (view) {
55821        return _this2.linkChild(view);
55822      });
55823
55824      childViews.splice.apply(childViews, [idx, removedCount].concat(addedViews));
55825
55826      this.notifyPropertyChange('childViews');
55827      this.arrayContentDidChange(idx, removedCount, addedCount);
55828
55829      // assert("You can't add a child to a container - the child is already a child of another view", emberA(addedViews).every(function(item) { return !item.parentView || item.parentView === self; }));
55830
55831      _emberMetalProperty_set.set(this, 'length', childViews.length);
55832
55833      return this;
55834    },
55835
55836    objectAt: function (idx) {
55837      return this.childViews[idx];
55838    },
55839
55840    _triggerChildWillDestroyElement: _emberMetalEvents.on('willDestroyElement', function () {
55841      var childViews = this.childViews;
55842      if (childViews) {
55843        for (var i = 0; i < childViews.length; i++) {
55844          this.renderer.willDestroyElement(childViews[i]);
55845        }
55846      }
55847    }),
55848
55849    _triggerChildDidDestroyElement: _emberMetalEvents.on('didDestroyElement', function () {
55850      var childViews = this.childViews;
55851      if (childViews) {
55852        for (var i = 0; i < childViews.length; i++) {
55853          this.renderer.didDestroyElement(childViews[i]);
55854        }
55855      }
55856    })
55857  });
55858
55859  function containerViewDeprecationMessage() {
55860    _emberMetalDebug.deprecate('Ember.ContainerView is deprecated.', !!_emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT, {
55861      url: 'http://emberjs.com/deprecations/v1.x/#toc_ember-containerview',
55862      id: 'ember-views.container-view',
55863      until: '2.4.0'
55864    });
55865  }
55866
55867  var DeprecatedContainerView = ContainerView.extend({
55868    init: function () {
55869      containerViewDeprecationMessage();
55870      this._super.apply(this, arguments);
55871    }
55872  });
55873
55874  exports.DeprecatedContainerView = DeprecatedContainerView;
55875  DeprecatedContainerView.reopen = function () {
55876    containerViewDeprecationMessage();
55877    ContainerView.reopen.apply(ContainerView, arguments);
55878    return this;
55879  };
55880
55881  exports.default = ContainerView;
55882});
55883enifed('ember-views/views/core_view', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-runtime/system/object', 'ember-runtime/mixins/evented', 'ember-runtime/mixins/action_handler', 'ember-runtime/utils', 'ember-metal-views', 'ember-views/views/states', 'htmlbars-runtime', 'require'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberRuntimeSystemObject, _emberRuntimeMixinsEvented, _emberRuntimeMixinsAction_handler, _emberRuntimeUtils, _emberMetalViews, _emberViewsViewsStates, _htmlbarsRuntime, _require) {
55884  'use strict';
55885
55886  function K() {
55887    return this;
55888  }
55889
55890  // Normally, the renderer is injected by the container when the view is looked
55891  // up. However, if someone creates a view without looking it up via the
55892  // container (e.g. `Ember.View.create().append()`) then we create a fallback
55893  // DOM renderer that is shared. In general, this path should be avoided since
55894  // views created this way cannot run in a node environment.
55895  var renderer;
55896
55897  /**
55898    `Ember.CoreView` is an abstract class that exists to give view-like behavior
55899    to both Ember's main view class `Ember.View` and other classes that don't need
55900    the fully functionaltiy of `Ember.View`.
55901  
55902    Unless you have specific needs for `CoreView`, you will use `Ember.View`
55903    in your applications.
55904  
55905    @class CoreView
55906    @namespace Ember
55907    @extends Ember.Object
55908    @deprecated Use `Ember.View` instead.
55909    @uses Ember.Evented
55910    @uses Ember.ActionHandler
55911    @private
55912  */
55913  var CoreView = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsEvented.default, _emberRuntimeMixinsAction_handler.default, {
55914    isView: true,
55915
55916    _states: _emberViewsViewsStates.cloneStates(_emberViewsViewsStates.states),
55917
55918    init: function () {
55919      this._super.apply(this, arguments);
55920      this._state = 'preRender';
55921      this._currentState = this._states.preRender;
55922      this._isVisible = _emberMetalProperty_get.get(this, 'isVisible');
55923
55924      // Fallback for legacy cases where the view was created directly
55925      // via `create()` instead of going through the container.
55926      if (!this.renderer) {
55927        var DOMHelper = domHelper();
55928        renderer = renderer || new _emberMetalViews.Renderer(new DOMHelper());
55929        this.renderer = renderer;
55930      }
55931
55932      this._destroyingSubtreeForView = null;
55933      this._dispatching = null;
55934    },
55935
55936    /**
55937      If the view is currently inserted into the DOM of a parent view, this
55938      property will point to the parent of the view.
55939       @property parentView
55940      @type Ember.View
55941      @default null
55942      @private
55943    */
55944    parentView: null,
55945
55946    _state: null,
55947
55948    instrumentName: 'core_view',
55949
55950    instrumentDetails: function (hash) {
55951      hash.object = this.toString();
55952      hash.containerKey = this._debugContainerKey;
55953      hash.view = this;
55954    },
55955
55956    /**
55957      Override the default event firing from `Ember.Evented` to
55958      also call methods with the given name.
55959       @method trigger
55960      @param name {String}
55961      @private
55962    */
55963    trigger: function () {
55964      this._super.apply(this, arguments);
55965      var name = arguments[0];
55966      var method = this[name];
55967      if (method) {
55968        var length = arguments.length;
55969        var args = new Array(length - 1);
55970        for (var i = 1; i < length; i++) {
55971          args[i - 1] = arguments[i];
55972        }
55973        return method.apply(this, args);
55974      }
55975    },
55976
55977    has: function (name) {
55978      return _emberRuntimeUtils.typeOf(this[name]) === 'function' || this._super(name);
55979    },
55980
55981    destroy: function () {
55982      if (!this._super.apply(this, arguments)) {
55983        return;
55984      }
55985
55986      this._currentState.cleanup(this);
55987
55988      // If the destroyingSubtreeForView property is not set but we have an
55989      // associated render node, it means this view is being destroyed from user
55990      // code and not via a change in the templating layer (like an {{if}}
55991      // becoming falsy, for example).  In this case, it is our responsibility to
55992      // make sure that any render nodes created as part of the rendering process
55993      // are cleaned up.
55994      if (!this.ownerView._destroyingSubtreeForView && this._renderNode) {
55995        _emberMetalDebug.assert('BUG: Render node exists without concomitant env.', this.ownerView.env);
55996        _htmlbarsRuntime.internal.clearMorph(this._renderNode, this.ownerView.env, true);
55997      }
55998
55999      return this;
56000    },
56001
56002    clearRenderedChildren: K,
56003    _transitionTo: K,
56004    destroyElement: K
56005  });
56006
56007  _emberRuntimeMixinsAction_handler.deprecateUnderscoreActions(CoreView);
56008
56009  CoreView.reopenClass({
56010    isViewFactory: true
56011  });
56012
56013  var DeprecatedCoreView = CoreView.extend({
56014    init: function () {
56015      _emberMetalDebug.deprecate('Ember.CoreView is deprecated. Please use Ember.View.', false, { id: 'ember-views.core-view', until: '2.4.0' });
56016      this._super.apply(this, arguments);
56017    }
56018  });
56019
56020  exports.DeprecatedCoreView = DeprecatedCoreView;
56021  var _domHelper;
56022  function domHelper() {
56023    return _domHelper = _domHelper || _require.default('ember-htmlbars/system/dom-helper').default;
56024  }
56025
56026  exports.default = CoreView;
56027});
56028enifed('ember-views/views/legacy_each_view', ['exports', 'ember-htmlbars/templates/legacy-each', 'ember-metal/property_get', 'ember-metal/computed', 'ember-views/views/view', 'ember-views/views/collection_view', 'ember-views/mixins/empty_view_support'], function (exports, _emberHtmlbarsTemplatesLegacyEach, _emberMetalProperty_get, _emberMetalComputed, _emberViewsViewsView, _emberViewsViewsCollection_view, _emberViewsMixinsEmpty_view_support) {
56029  //2.0TODO: Remove this in 2.0
56030  //This is a fallback path for the `{{#each}}` helper that supports deprecated
56031  //behavior such as itemController.
56032
56033  'use strict';
56034
56035  exports.default = _emberViewsViewsView.default.extend(_emberViewsMixinsEmpty_view_support.default, {
56036    template: _emberHtmlbarsTemplatesLegacyEach.default,
56037    tagName: '',
56038
56039    /*
56040      Support for ArrayController has been extracted to the ember-legacy-controllers addon.
56041    */
56042
56043    _arrangedContent: _emberMetalComputed.computed('attrs.content', function () {
56044      return this.getAttr('content');
56045    }),
56046
56047    _itemTagName: _emberMetalComputed.computed(function () {
56048      var tagName = _emberMetalProperty_get.get(this, 'tagName');
56049      return _emberViewsViewsCollection_view.CONTAINER_MAP[tagName];
56050    })
56051  });
56052});
56053enifed('ember-views/views/select', ['exports', 'ember-metal/replace', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/views/view', 'ember-runtime/utils', 'ember-metal/is_none', 'ember-metal/computed', 'ember-runtime/system/native_array', 'ember-metal/mixin', 'ember-metal/properties', 'ember-htmlbars/templates/select', 'ember-htmlbars/templates/select-option', 'ember-htmlbars/templates/select-optgroup', 'ember-runtime/mixins/array'], function (exports, _emberMetalReplace, _emberMetalProperty_get, _emberMetalProperty_set, _emberViewsViewsView, _emberRuntimeUtils, _emberMetalIs_none, _emberMetalComputed, _emberRuntimeSystemNative_array, _emberMetalMixin, _emberMetalProperties, _emberHtmlbarsTemplatesSelect, _emberHtmlbarsTemplatesSelectOption, _emberHtmlbarsTemplatesSelectOptgroup, _emberRuntimeMixinsArray) {
56054  /**
56055  @module ember
56056  @submodule ember-views
56057  */
56058
56059  'use strict';
56060
56061  var defaultTemplate = _emberHtmlbarsTemplatesSelect.default;
56062
56063  var SelectOption = _emberViewsViewsView.default.extend({
56064    instrumentDisplay: 'Ember.SelectOption',
56065
56066    tagName: 'option',
56067    attributeBindings: ['value', 'selected'],
56068
56069    defaultTemplate: _emberHtmlbarsTemplatesSelectOption.default,
56070
56071    content: null,
56072
56073    _willRender: function () {
56074      this.labelPathDidChange();
56075      this.valuePathDidChange();
56076    },
56077
56078    selected: _emberMetalComputed.computed('attrs.content', 'attrs.selection', function () {
56079      var value = _emberMetalProperty_get.get(this, 'value');
56080      var selection = _emberMetalProperty_get.get(this, 'attrs.selection');
56081      if (_emberMetalProperty_get.get(this, 'attrs.multiple')) {
56082        return selection && selection.indexOf(value) > -1;
56083      } else {
56084        // Primitives get passed through bindings as objects... since
56085        // `new Number(4) !== 4`, we use `==` below
56086        return value == _emberMetalProperty_get.get(this, 'attrs.parentValue'); // jshint ignore:line
56087      }
56088    }),
56089
56090    labelPathDidChange: _emberMetalMixin.observer('attrs.optionLabelPath', function () {
56091      var labelPath = _emberMetalProperty_get.get(this, 'attrs.optionLabelPath');
56092      _emberMetalProperties.defineProperty(this, 'label', _emberMetalComputed.computed.alias(labelPath));
56093    }),
56094
56095    valuePathDidChange: _emberMetalMixin.observer('attrs.optionValuePath', function () {
56096      var valuePath = _emberMetalProperty_get.get(this, 'attrs.optionValuePath');
56097      _emberMetalProperties.defineProperty(this, 'value', _emberMetalComputed.computed.alias(valuePath));
56098    })
56099  });
56100
56101  var SelectOptgroup = _emberViewsViewsView.default.extend({
56102    instrumentDisplay: 'Ember.SelectOptgroup',
56103
56104    tagName: 'optgroup',
56105    defaultTemplate: _emberHtmlbarsTemplatesSelectOptgroup.default,
56106    attributeBindings: ['label']
56107  });
56108
56109  /**
56110    The `Ember.Select` view class renders a
56111    [select](https://developer.mozilla.org/en/HTML/Element/select) HTML element,
56112    allowing the user to choose from a list of options.
56113  
56114    The text and `value` property of each `<option>` element within the
56115    `<select>` element are populated from the objects in the `Element.Select`'s
56116    `content` property. The underlying data object of the selected `<option>` is
56117    stored in the `Element.Select`'s `value` property.
56118  
56119    ## The Content Property (array of strings)
56120  
56121    The simplest version of an `Ember.Select` takes an array of strings as its
56122    `content` property. The string will be used as both the `value` property and
56123    the inner text of each `<option>` element inside the rendered `<select>`.
56124  
56125    Example:
56126  
56127    ```javascript
56128    App.ApplicationController = Ember.Controller.extend({
56129      names: ["Yehuda", "Tom"]
56130    });
56131    ```
56132  
56133    ```handlebars
56134    {{view "select" content=names}}
56135    ```
56136  
56137    Would result in the following HTML:
56138  
56139    ```html
56140    <select class="ember-select">
56141      <option value="Yehuda">Yehuda</option>
56142      <option value="Tom">Tom</option>
56143    </select>
56144    ```
56145  
56146    You can control which `<option>` is selected through the `Ember.Select`'s
56147    `value` property:
56148  
56149    ```javascript
56150    App.ApplicationController = Ember.Controller.extend({
56151      selectedName: 'Tom',
56152      names: ["Yehuda", "Tom"]
56153    });
56154    ```
56155  
56156    ```handlebars
56157    {{view "select" content=names value=selectedName}}
56158    ```
56159  
56160    Would result in the following HTML with the `<option>` for 'Tom' selected:
56161  
56162    ```html
56163    <select class="ember-select">
56164      <option value="Yehuda">Yehuda</option>
56165      <option value="Tom" selected="selected">Tom</option>
56166    </select>
56167    ```
56168  
56169    A user interacting with the rendered `<select>` to choose "Yehuda" would
56170    update the value of `selectedName` to "Yehuda".
56171  
56172    ## The Content Property (array of Objects)
56173  
56174    An `Ember.Select` can also take an array of JavaScript or Ember objects as
56175    its `content` property.
56176  
56177    When using objects you need to tell the `Ember.Select` which property should
56178    be accessed on each object to supply the `value` attribute of the `<option>`
56179    and which property should be used to supply the element text.
56180  
56181    The `optionValuePath` option is used to specify the path on each object to
56182    the desired property for the `value` attribute. The `optionLabelPath`
56183    specifies the path on each object to the desired property for the
56184    element's text. Both paths must reference each object itself as `content`:
56185  
56186    ```javascript
56187    App.ApplicationController = Ember.Controller.extend({
56188      programmers: [
56189        {firstName: "Yehuda", id: 1},
56190        {firstName: "Tom",    id: 2}
56191      ]
56192    });
56193    ```
56194  
56195    ```handlebars
56196    {{view "select"
56197           content=programmers
56198           optionValuePath="content.id"
56199           optionLabelPath="content.firstName"}}
56200    ```
56201  
56202    Would result in the following HTML:
56203  
56204    ```html
56205    <select class="ember-select">
56206      <option value="1">Yehuda</option>
56207      <option value="2">Tom</option>
56208    </select>
56209    ```
56210  
56211    The `value` attribute of the selected `<option>` within an `Ember.Select`
56212    can be bound to a property on another object:
56213  
56214    ```javascript
56215    App.ApplicationController = Ember.Controller.extend({
56216      programmers: [
56217        {firstName: "Yehuda", id: 1},
56218        {firstName: "Tom",    id: 2}
56219      ],
56220      currentProgrammer: {
56221        id: 2
56222      }
56223    });
56224    ```
56225  
56226    ```handlebars
56227    {{view "select"
56228           content=programmers
56229           optionValuePath="content.id"
56230           optionLabelPath="content.firstName"
56231           value=currentProgrammer.id}}
56232    ```
56233  
56234    Would result in the following HTML with a selected option:
56235  
56236    ```html
56237    <select class="ember-select">
56238      <option value="1">Yehuda</option>
56239      <option value="2" selected="selected">Tom</option>
56240    </select>
56241    ```
56242  
56243    Interacting with the rendered element by selecting the first option
56244    ('Yehuda') will update the `id` of `currentProgrammer`
56245    to match the `value` property of the newly selected `<option>`.
56246  
56247    Alternatively, you can control selection through the underlying objects
56248    used to render each object by binding the `selection` option. When the selected
56249    `<option>` is changed, the property path provided to `selection`
56250    will be updated to match the content object of the rendered `<option>`
56251    element:
56252  
56253    ```javascript
56254  
56255    var yehuda = {firstName: "Yehuda", id: 1, bff4eva: 'tom'}
56256    var tom = {firstName: "Tom", id: 2, bff4eva: 'yehuda'};
56257  
56258    App.ApplicationController = Ember.Controller.extend({
56259      selectedPerson: tom,
56260      programmers: [ yehuda, tom ]
56261    });
56262    ```
56263  
56264    ```handlebars
56265    {{view "select"
56266           content=programmers
56267           optionValuePath="content.id"
56268           optionLabelPath="content.firstName"
56269           selection=selectedPerson}}
56270    ```
56271  
56272    Would result in the following HTML with a selected option:
56273  
56274    ```html
56275    <select class="ember-select">
56276      <option value="1">Yehuda</option>
56277      <option value="2" selected="selected">Tom</option>
56278    </select>
56279    ```
56280  
56281    Interacting with the rendered element by selecting the first option
56282    ('Yehuda') will update the `selectedPerson` to match the object of
56283    the newly selected `<option>`. In this case it is the first object
56284    in the `programmers`
56285  
56286    ## Supplying a Prompt
56287  
56288    A `null` value for the `Ember.Select`'s `value` or `selection` property
56289    results in there being no `<option>` with a `selected` attribute:
56290  
56291    ```javascript
56292    App.ApplicationController = Ember.Controller.extend({
56293      selectedProgrammer: null,
56294      programmers: ["Yehuda", "Tom"]
56295    });
56296    ```
56297  
56298    ``` handlebars
56299    {{view "select"
56300           content=programmers
56301           value=selectedProgrammer
56302    }}
56303    ```
56304  
56305    Would result in the following HTML:
56306  
56307    ```html
56308    <select class="ember-select">
56309      <option value="Yehuda">Yehuda</option>
56310      <option value="Tom">Tom</option>
56311    </select>
56312    ```
56313  
56314    Although `selectedProgrammer` is `null` and no `<option>`
56315    has a `selected` attribute the rendered HTML will display the
56316    first item as though it were selected. You can supply a string
56317    value for the `Ember.Select` to display when there is no selection
56318    with the `prompt` option:
56319  
56320    ```javascript
56321    App.ApplicationController = Ember.Controller.extend({
56322      selectedProgrammer: null,
56323      programmers: [ "Yehuda", "Tom" ]
56324    });
56325    ```
56326  
56327    ```handlebars
56328    {{view "select"
56329           content=programmers
56330           value=selectedProgrammer
56331           prompt="Please select a name"
56332    }}
56333    ```
56334  
56335    Would result in the following HTML:
56336  
56337    ```html
56338    <select class="ember-select">
56339      <option>Please select a name</option>
56340      <option value="Yehuda">Yehuda</option>
56341      <option value="Tom">Tom</option>
56342    </select>
56343    ```
56344  
56345    @class Select
56346    @namespace Ember
56347    @extends Ember.View
56348    @public
56349    @deprecated See http://emberjs.com/deprecations/v1.x/#toc_ember-select
56350  */
56351  var Select = _emberViewsViewsView.default.extend({
56352    instrumentDisplay: 'Ember.Select',
56353
56354    tagName: 'select',
56355    classNames: ['ember-select'],
56356    defaultTemplate: defaultTemplate,
56357    attributeBindings: ['autofocus', 'autocomplete', 'disabled', 'form', 'multiple', 'name', 'required', 'size', 'tabindex'],
56358
56359    /**
56360      The `multiple` attribute of the select element. Indicates whether multiple
56361      options can be selected.
56362       @property multiple
56363      @type Boolean
56364      @default false
56365      @public
56366    */
56367    multiple: false,
56368
56369    /**
56370      The `disabled` attribute of the select element. Indicates whether
56371      the element is disabled from interactions.
56372       @property disabled
56373      @type Boolean
56374      @default false
56375      @public
56376    */
56377    disabled: false,
56378
56379    /**
56380      The `required` attribute of the select element. Indicates whether
56381      a selected option is required for form validation.
56382       @property required
56383      @type Boolean
56384      @default false
56385      @since 1.5.0
56386      @public
56387    */
56388    required: false,
56389
56390    /**
56391      The list of options.
56392       If `optionLabelPath` and `optionValuePath` are not overridden, this should
56393      be a list of strings, which will serve simultaneously as labels and values.
56394       Otherwise, this should be a list of objects. For instance:
56395       ```javascript
56396      var App = Ember.Application.create();
56397      var App.MySelect = Ember.Select.extend({
56398        content: Ember.A([
56399            { id: 1, firstName: 'Yehuda' },
56400            { id: 2, firstName: 'Tom' }
56401          ]),
56402        optionLabelPath: 'content.firstName',
56403        optionValuePath: 'content.id'
56404      });
56405      ```
56406       @property content
56407      @type Array
56408      @default null
56409      @public
56410    */
56411    content: null,
56412
56413    /**
56414      When `multiple` is `false`, the element of `content` that is currently
56415      selected, if any.
56416       When `multiple` is `true`, an array of such elements.
56417       @property selection
56418      @type Object or Array
56419      @default null
56420      @public
56421    */
56422    selection: null,
56423
56424    /**
56425      In single selection mode (when `multiple` is `false`), value can be used to
56426      get the current selection's value or set the selection by its value.
56427       It is not currently supported in multiple selection mode.
56428       @property value
56429      @type String
56430      @default null
56431      @public
56432    */
56433    value: _emberMetalComputed.computed('_valuePath', 'selection', {
56434      get: function (key) {
56435        var valuePath = _emberMetalProperty_get.get(this, '_valuePath');
56436        return valuePath ? _emberMetalProperty_get.get(this, 'selection.' + valuePath) : _emberMetalProperty_get.get(this, 'selection');
56437      },
56438      set: function (key, value) {
56439        return value;
56440      }
56441    }),
56442
56443    /**
56444      If given, a top-most dummy option will be rendered to serve as a user
56445      prompt.
56446       @property prompt
56447      @type String
56448      @default null
56449      @public
56450    */
56451    prompt: null,
56452
56453    /**
56454      The path of the option labels. See [content](/api/classes/Ember.Select.html#property_content).
56455       @property optionLabelPath
56456      @type String
56457      @default 'content'
56458      @public
56459    */
56460    optionLabelPath: 'content',
56461
56462    /**
56463      The path of the option values. See [content](/api/classes/Ember.Select.html#property_content).
56464       @property optionValuePath
56465      @type String
56466      @default 'content'
56467      @public
56468    */
56469    optionValuePath: 'content',
56470
56471    /**
56472      The path of the option group.
56473      When this property is used, `content` should be sorted by `optionGroupPath`.
56474       @property optionGroupPath
56475      @type String
56476      @default null
56477      @public
56478    */
56479    optionGroupPath: null,
56480
56481    /**
56482      The view class for optgroup.
56483       @property groupView
56484      @type Ember.View
56485      @default Ember.SelectOptgroup
56486      @public
56487    */
56488    groupView: SelectOptgroup,
56489
56490    groupedContent: _emberMetalComputed.computed('optionGroupPath', 'content.[]', function () {
56491      var groupPath = _emberMetalProperty_get.get(this, 'optionGroupPath');
56492      var groupedContent = _emberRuntimeSystemNative_array.A();
56493      var content = _emberMetalProperty_get.get(this, 'content') || [];
56494
56495      content.forEach(function (item) {
56496        var label = _emberMetalProperty_get.get(item, groupPath);
56497
56498        if (_emberMetalProperty_get.get(groupedContent, 'lastObject.label') !== label) {
56499          groupedContent.pushObject({
56500            label: label,
56501            content: _emberRuntimeSystemNative_array.A()
56502          });
56503        }
56504
56505        _emberMetalProperty_get.get(groupedContent, 'lastObject.content').push(item);
56506      });
56507
56508      return groupedContent;
56509    }),
56510
56511    /**
56512      The view class for option.
56513       @property optionView
56514      @type Ember.View
56515      @default Ember.SelectOption
56516      @private
56517    */
56518    optionView: SelectOption,
56519
56520    _change: function (hasDOM) {
56521      if (_emberMetalProperty_get.get(this, 'multiple')) {
56522        this._changeMultiple(hasDOM);
56523      } else {
56524        this._changeSingle(hasDOM);
56525      }
56526    },
56527
56528    selectionDidChange: _emberMetalMixin.observer('selection.[]', function () {
56529      var selection = _emberMetalProperty_get.get(this, 'selection');
56530      if (_emberMetalProperty_get.get(this, 'multiple')) {
56531        if (!_emberRuntimeUtils.isArray(selection)) {
56532          _emberMetalProperty_set.set(this, 'selection', _emberRuntimeSystemNative_array.A([selection]));
56533          return;
56534        }
56535        this._selectionDidChangeMultiple();
56536      } else {
56537        this._selectionDidChangeSingle();
56538      }
56539    }),
56540
56541    valueDidChange: _emberMetalMixin.observer('value', function () {
56542      var content = _emberMetalProperty_get.get(this, 'content');
56543      var value = _emberMetalProperty_get.get(this, 'value');
56544      var valuePath = _emberMetalProperty_get.get(this, 'optionValuePath').replace(/^content\.?/, '');
56545      var selectedValue = valuePath ? _emberMetalProperty_get.get(this, 'selection.' + valuePath) : _emberMetalProperty_get.get(this, 'selection');
56546      var selection;
56547
56548      if (value !== selectedValue) {
56549        selection = content ? content.find(function (obj) {
56550          return value === (valuePath ? _emberMetalProperty_get.get(obj, valuePath) : obj);
56551        }) : null;
56552
56553        this.set('selection', selection);
56554      }
56555    }),
56556
56557    _setDefaults: function () {
56558      var selection = _emberMetalProperty_get.get(this, 'selection');
56559      var value = _emberMetalProperty_get.get(this, 'value');
56560
56561      if (!_emberMetalIs_none.default(selection)) {
56562        this.selectionDidChange();
56563      }
56564      if (!_emberMetalIs_none.default(value)) {
56565        this.valueDidChange();
56566      }
56567      if (_emberMetalIs_none.default(selection)) {
56568        this._change(false);
56569      }
56570    },
56571
56572    _changeSingle: function (hasDOM) {
56573      var value = this.get('value');
56574      var selectedIndex = hasDOM !== false ? this.$()[0].selectedIndex : this._selectedIndex(value);
56575      var content = _emberMetalProperty_get.get(this, 'content');
56576      var prompt = _emberMetalProperty_get.get(this, 'prompt');
56577
56578      if (!content || !_emberMetalProperty_get.get(content, 'length')) {
56579        return;
56580      }
56581      if (prompt && selectedIndex === 0) {
56582        _emberMetalProperty_set.set(this, 'selection', null);
56583        return;
56584      }
56585
56586      if (prompt) {
56587        selectedIndex -= 1;
56588      }
56589      _emberMetalProperty_set.set(this, 'selection', _emberRuntimeMixinsArray.objectAt(content, selectedIndex));
56590    },
56591
56592    _selectedIndex: function (value) {
56593      var defaultIndex = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
56594
56595      var content = _emberMetalProperty_get.get(this, 'contentValues');
56596
56597      var selectionIndex = content.indexOf(value);
56598
56599      var prompt = _emberMetalProperty_get.get(this, 'prompt');
56600      if (prompt) {
56601        selectionIndex += 1;
56602      }
56603
56604      if (selectionIndex < 0) {
56605        selectionIndex = defaultIndex;
56606      }
56607
56608      return selectionIndex;
56609    },
56610
56611    _changeMultiple: function (hasDOM) {
56612      var options = hasDOM !== false ? this.$('option:selected') : [];
56613      var prompt = _emberMetalProperty_get.get(this, 'prompt');
56614      var offset = prompt ? 1 : 0;
56615      var content = _emberMetalProperty_get.get(this, 'content');
56616      var selection = _emberMetalProperty_get.get(this, 'selection');
56617
56618      if (!content) {
56619        return;
56620      }
56621      if (options) {
56622        var selectedIndexes = options.map(function () {
56623          return this.index - offset;
56624        });
56625        var newSelection = content.objectsAt([].slice.call(selectedIndexes));
56626
56627        if (_emberRuntimeUtils.isArray(selection)) {
56628          _emberMetalReplace.default(selection, 0, _emberMetalProperty_get.get(selection, 'length'), newSelection);
56629        } else {
56630          _emberMetalProperty_set.set(this, 'selection', newSelection);
56631        }
56632      }
56633    },
56634
56635    _selectionDidChangeSingle: function () {
56636      var value = _emberMetalProperty_get.get(this, 'value');
56637      var self = this;
56638      if (value && value.then) {
56639        value.then(function (resolved) {
56640          // Ensure that we don't overwrite new value
56641          if (_emberMetalProperty_get.get(self, 'value') === value) {
56642            self._setSelectedIndex(resolved);
56643          }
56644        });
56645      } else {
56646        this._setSelectedIndex(value);
56647      }
56648    },
56649
56650    _setSelectedIndex: function (selectionValue) {
56651      var el = _emberMetalProperty_get.get(this, 'element');
56652      if (!el) {
56653        return;
56654      }
56655
56656      el.selectedIndex = this._selectedIndex(selectionValue, -1);
56657    },
56658
56659    _valuePath: _emberMetalComputed.computed('optionValuePath', function () {
56660      var optionValuePath = _emberMetalProperty_get.get(this, 'optionValuePath');
56661      return optionValuePath.replace(/^content\.?/, '');
56662    }),
56663
56664    contentValues: _emberMetalComputed.computed('content.[]', '_valuePath', function () {
56665      var valuePath = _emberMetalProperty_get.get(this, '_valuePath');
56666      var content = _emberMetalProperty_get.get(this, 'content') || [];
56667
56668      if (valuePath) {
56669        return content.map(function (el) {
56670          return _emberMetalProperty_get.get(el, valuePath);
56671        });
56672      } else {
56673        return content.slice();
56674      }
56675    }),
56676
56677    _selectionDidChangeMultiple: function () {
56678      var content = _emberMetalProperty_get.get(this, 'content');
56679      var selection = _emberMetalProperty_get.get(this, 'selection');
56680      var selectedIndexes = content ? indexesOf(content, selection) : [-1];
56681      var prompt = _emberMetalProperty_get.get(this, 'prompt');
56682      var offset = prompt ? 1 : 0;
56683      var options = this.$('option');
56684      var adjusted;
56685
56686      if (options) {
56687        options.each(function () {
56688          adjusted = this.index > -1 ? this.index - offset : -1;
56689          this.selected = selectedIndexes.indexOf(adjusted) > -1;
56690        });
56691      }
56692    },
56693
56694    _willRender: function () {
56695      this._setDefaults();
56696    },
56697
56698    init: function () {
56699      this._super.apply(this, arguments);
56700      this.on('change', this, this._change);
56701    }
56702  });
56703
56704  function indexesOf(iterable, elements) {
56705    return elements === undefined ? [] : elements.map(function (item) {
56706      return iterable.indexOf(item);
56707    });
56708  }
56709
56710  exports.default = Select;
56711  exports.Select = Select;
56712  exports.SelectOption = SelectOption;
56713  exports.SelectOptgroup = SelectOptgroup;
56714});
56715enifed('ember-views/views/states/default', ['exports', 'ember-metal/error', 'ember-metal/property_get', 'ember-views/compat/attrs-proxy'], function (exports, _emberMetalError, _emberMetalProperty_get, _emberViewsCompatAttrsProxy) {
56716  'use strict';
56717
56718  /**
56719  @module ember
56720  @submodule ember-views
56721  */
56722  exports.default = {
56723    // appendChild is only legal while rendering the buffer.
56724    appendChild: function () {
56725      throw new _emberMetalError.default('You can\'t use appendChild outside of the rendering process');
56726    },
56727
56728    $: function () {
56729      return undefined;
56730    },
56731
56732    getElement: function () {
56733      return null;
56734    },
56735
56736    legacyPropertyDidChange: function (view, key) {
56737      var attrs = view.attrs;
56738      if (attrs && key in attrs) {
56739        var possibleCell = attrs[key];
56740
56741        if (possibleCell && possibleCell[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) {
56742          var value = _emberMetalProperty_get.get(view, key);
56743          if (value === possibleCell.value) {
56744            return;
56745          }
56746          possibleCell.update(value);
56747        }
56748      }
56749    },
56750
56751    // Handle events from `Ember.EventDispatcher`
56752    handleEvent: function () {
56753      return true; // continue event propagation
56754    },
56755
56756    cleanup: function () {},
56757    destroyElement: function () {},
56758
56759    rerender: function (view) {
56760      view.renderer.ensureViewNotRendering(view);
56761    },
56762    invokeObserver: function () {}
56763  };
56764});
56765enifed('ember-views/views/states/destroying', ['exports', 'ember-metal/assign', 'ember-views/views/states/default', 'ember-metal/error'], function (exports, _emberMetalAssign, _emberViewsViewsStatesDefault, _emberMetalError) {
56766  'use strict';
56767
56768  /**
56769  @module ember
56770  @submodule ember-views
56771  */
56772
56773  var destroying = Object.create(_emberViewsViewsStatesDefault.default);
56774
56775  _emberMetalAssign.default(destroying, {
56776    appendChild: function () {
56777      throw new _emberMetalError.default('You can\'t call appendChild on a view being destroyed');
56778    },
56779    rerender: function () {
56780      throw new _emberMetalError.default('You can\'t call rerender on a view being destroyed');
56781    },
56782    destroyElement: function () {
56783      throw new _emberMetalError.default('You can\'t call destroyElement on a view being destroyed');
56784    }
56785  });
56786
56787  exports.default = destroying;
56788});
56789enifed('ember-views/views/states/has_element', ['exports', 'ember-views/views/states/default', 'ember-metal/assign', 'ember-views/system/jquery', 'ember-metal/run_loop', 'ember-metal/property_get'], function (exports, _emberViewsViewsStatesDefault, _emberMetalAssign, _emberViewsSystemJquery, _emberMetalRun_loop, _emberMetalProperty_get) {
56790  'use strict';
56791
56792  var hasElement = Object.create(_emberViewsViewsStatesDefault.default);
56793
56794  _emberMetalAssign.default(hasElement, {
56795    $: function (view, sel) {
56796      var elem = view.element;
56797      return sel ? _emberViewsSystemJquery.default(sel, elem) : _emberViewsSystemJquery.default(elem);
56798    },
56799
56800    getElement: function (view) {
56801      var parent = _emberMetalProperty_get.get(view, 'parentView');
56802      if (parent) {
56803        parent = _emberMetalProperty_get.get(parent, 'element');
56804      }
56805      if (parent) {
56806        return view.findElementInParentElement(parent);
56807      }
56808      return _emberViewsSystemJquery.default('#' + _emberMetalProperty_get.get(view, 'elementId'))[0];
56809    },
56810
56811    // once the view has been inserted into the DOM, rerendering is
56812    // deferred to allow bindings to synchronize.
56813    rerender: function (view) {
56814      view.renderer.ensureViewNotRendering(view);
56815      view.renderer.rerender(view);
56816    },
56817
56818    cleanup: function (view) {
56819      view._currentState.destroyElement(view);
56820    },
56821
56822    // once the view is already in the DOM, destroying it removes it
56823    // from the DOM, nukes its element, and puts it back into the
56824    // preRender state if inDOM.
56825
56826    destroyElement: function (view) {
56827      view.renderer.remove(view, false);
56828      return view;
56829    },
56830
56831    // Handle events from `Ember.EventDispatcher`
56832    handleEvent: function (view, eventName, evt) {
56833      if (view.has(eventName)) {
56834        // Handler should be able to re-dispatch events, so we don't
56835        // preventDefault or stopPropagation.
56836        return _emberMetalRun_loop.default.join(view, view.trigger, eventName, evt);
56837      } else {
56838        return true; // continue event propagation
56839      }
56840    },
56841
56842    invokeObserver: function (target, observer) {
56843      observer.call(target);
56844    }
56845  });
56846
56847  exports.default = hasElement;
56848});
56849
56850/**
56851@module ember
56852@submodule ember-views
56853*/
56854enifed('ember-views/views/states/in_dom', ['exports', 'ember-metal/debug', 'ember-metal/assign', 'ember-metal/error', 'ember-metal/observer', 'ember-views/views/states/has_element'], function (exports, _emberMetalDebug, _emberMetalAssign, _emberMetalError, _emberMetalObserver, _emberViewsViewsStatesHas_element) {
56855  'use strict';
56856
56857  /**
56858  @module ember
56859  @submodule ember-views
56860  */
56861
56862  var inDOM = Object.create(_emberViewsViewsStatesHas_element.default);
56863
56864  _emberMetalAssign.default(inDOM, {
56865    enter: function (view) {
56866      // Register the view for event handling. This hash is used by
56867      // Ember.EventDispatcher to dispatch incoming events.
56868      if (view.tagName !== '') {
56869        view._register();
56870      }
56871
56872      _emberMetalDebug.runInDebug(function () {
56873        _emberMetalObserver._addBeforeObserver(view, 'elementId', function () {
56874          throw new _emberMetalError.default('Changing a view\'s elementId after creation is not allowed');
56875        });
56876      });
56877    },
56878
56879    exit: function (view) {
56880      view._unregister();
56881    }
56882  });
56883
56884  exports.default = inDOM;
56885});
56886enifed('ember-views/views/states/pre_render', ['exports', 'ember-views/views/states/default', 'ember-metal/assign'], function (exports, _emberViewsViewsStatesDefault, _emberMetalAssign) {
56887  'use strict';
56888
56889  /**
56890  @module ember
56891  @submodule ember-views
56892  */
56893
56894  var preRender = Object.create(_emberViewsViewsStatesDefault.default);
56895
56896  _emberMetalAssign.default(preRender, {
56897    legacyPropertyDidChange: function (view, key) {}
56898  });
56899
56900  exports.default = preRender;
56901});
56902enifed('ember-views/views/states', ['exports', 'ember-metal/assign', 'ember-views/views/states/default', 'ember-views/views/states/pre_render', 'ember-views/views/states/has_element', 'ember-views/views/states/in_dom', 'ember-views/views/states/destroying'], function (exports, _emberMetalAssign, _emberViewsViewsStatesDefault, _emberViewsViewsStatesPre_render, _emberViewsViewsStatesHas_element, _emberViewsViewsStatesIn_dom, _emberViewsViewsStatesDestroying) {
56903  'use strict';
56904
56905  exports.cloneStates = cloneStates;
56906
56907  function cloneStates(from) {
56908    var into = {};
56909
56910    into._default = {};
56911    into.preRender = Object.create(into._default);
56912    into.destroying = Object.create(into._default);
56913    into.hasElement = Object.create(into._default);
56914    into.inDOM = Object.create(into.hasElement);
56915
56916    for (var stateName in from) {
56917      if (!from.hasOwnProperty(stateName)) {
56918        continue;
56919      }
56920      _emberMetalAssign.default(into[stateName], from[stateName]);
56921    }
56922
56923    return into;
56924  }
56925
56926  var states = {
56927    _default: _emberViewsViewsStatesDefault.default,
56928    preRender: _emberViewsViewsStatesPre_render.default,
56929    inDOM: _emberViewsViewsStatesIn_dom.default,
56930    hasElement: _emberViewsViewsStatesHas_element.default,
56931    destroying: _emberViewsViewsStatesDestroying.default
56932  };
56933  exports.states = states;
56934});
56935enifed('ember-views/views/text_area', ['exports', 'ember-views/components/component', 'ember-views/mixins/text_support'], function (exports, _emberViewsComponentsComponent, _emberViewsMixinsText_support) {
56936  /**
56937  @module ember
56938  @submodule ember-views
56939  */
56940  'use strict';
56941
56942  /**
56943    The internal class used to create textarea element when the `{{textarea}}`
56944    helper is used.
56945  
56946    See [Ember.Templates.helpers.textarea](/api/classes/Ember.Templates.helpers.html#method_textarea)  for usage details.
56947  
56948    ## Layout and LayoutName properties
56949  
56950    Because HTML `textarea` elements do not contain inner HTML the `layout` and
56951    `layoutName` properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s
56952    layout section for more information.
56953  
56954    @class TextArea
56955    @namespace Ember
56956    @extends Ember.Component
56957    @uses Ember.TextSupport
56958    @public
56959  */
56960  exports.default = _emberViewsComponentsComponent.default.extend(_emberViewsMixinsText_support.default, {
56961    instrumentDisplay: '{{textarea}}',
56962
56963    classNames: ['ember-text-area'],
56964
56965    tagName: 'textarea',
56966    attributeBindings: ['rows', 'cols', 'name', 'selectionEnd', 'selectionStart', 'wrap', 'lang', 'dir', 'value'],
56967    rows: null,
56968    cols: null
56969  });
56970});
56971enifed('ember-views/views/text_field', ['exports', 'ember-metal/computed', 'ember-metal/environment', 'ember-views/components/component', 'ember-views/mixins/text_support', 'ember-metal/empty_object'], function (exports, _emberMetalComputed, _emberMetalEnvironment, _emberViewsComponentsComponent, _emberViewsMixinsText_support, _emberMetalEmpty_object) {
56972  /**
56973  @module ember
56974  @submodule ember-views
56975  */
56976  'use strict';
56977
56978  var inputTypeTestElement;
56979  var inputTypes = new _emberMetalEmpty_object.default();
56980  function canSetTypeOfInput(type) {
56981    if (type in inputTypes) {
56982      return inputTypes[type];
56983    }
56984
56985    // if running in outside of a browser always return the
56986    // original type
56987    if (!_emberMetalEnvironment.default.hasDOM) {
56988      inputTypes[type] = type;
56989
56990      return type;
56991    }
56992
56993    if (!inputTypeTestElement) {
56994      inputTypeTestElement = document.createElement('input');
56995    }
56996
56997    try {
56998      inputTypeTestElement.type = type;
56999    } catch (e) {}
57000
57001    return inputTypes[type] = inputTypeTestElement.type === type;
57002  }
57003
57004  /**
57005  
57006    The internal class used to create text inputs when the `{{input}}`
57007    helper is used with `type` of `text`.
57008  
57009    See [Ember.Templates.helpers.input](/api/classes/Ember.Templates.helpers.html#method_input)  for usage details.
57010  
57011    ## Layout and LayoutName properties
57012  
57013    Because HTML `input` elements are self closing `layout` and `layoutName`
57014    properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s
57015    layout section for more information.
57016  
57017    @class TextField
57018    @namespace Ember
57019    @extends Ember.Component
57020    @uses Ember.TextSupport
57021    @public
57022  */
57023  exports.default = _emberViewsComponentsComponent.default.extend(_emberViewsMixinsText_support.default, {
57024    instrumentDisplay: '{{input type="text"}}',
57025
57026    classNames: ['ember-text-field'],
57027    tagName: 'input',
57028    attributeBindings: ['accept', 'autocomplete', 'autosave', 'dir', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget', 'height', 'inputmode', 'lang', 'list', 'max', 'min', 'multiple', 'name', 'pattern', 'size', 'step', 'type', 'value', 'width'],
57029
57030    defaultLayout: null,
57031
57032    /**
57033      The `value` attribute of the input element. As the user inputs text, this
57034      property is updated live.
57035       @property value
57036      @type String
57037      @default ""
57038      @public
57039    */
57040    value: '',
57041
57042    /**
57043      The `type` attribute of the input element.
57044       @property type
57045      @type String
57046      @default "text"
57047      @public
57048    */
57049    type: _emberMetalComputed.computed({
57050      get: function () {
57051        return 'text';
57052      },
57053
57054      set: function (key, value) {
57055        var type = 'text';
57056
57057        if (canSetTypeOfInput(value)) {
57058          type = value;
57059        }
57060
57061        return type;
57062      }
57063    }),
57064
57065    /**
57066      The `size` of the text field in characters.
57067       @property size
57068      @type String
57069      @default null
57070      @public
57071    */
57072    size: null,
57073
57074    /**
57075      The `pattern` attribute of input element.
57076       @property pattern
57077      @type String
57078      @default null
57079      @public
57080    */
57081    pattern: null,
57082
57083    /**
57084      The `min` attribute of input element used with `type="number"` or `type="range"`.
57085       @property min
57086      @type String
57087      @default null
57088      @since 1.4.0
57089      @public
57090    */
57091    min: null,
57092
57093    /**
57094      The `max` attribute of input element used with `type="number"` or `type="range"`.
57095       @property max
57096      @type String
57097      @default null
57098      @since 1.4.0
57099      @public
57100    */
57101    max: null
57102  });
57103});
57104enifed('ember-views/views/view', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-views/system/ext', 'ember-views/views/core_view', 'ember-views/mixins/view_context_support', 'ember-views/mixins/view_child_views_support', 'ember-views/mixins/legacy_child_views_support', 'ember-views/mixins/view_state_support', 'ember-views/mixins/template_rendering_support', 'ember-views/mixins/class_names_support', 'ember-views/mixins/legacy_view_support', 'ember-views/mixins/instrumentation_support', 'ember-views/mixins/aria_role_support', 'ember-views/mixins/visibility_support', 'ember-views/compat/attrs-proxy', 'ember-views/mixins/view_support', 'ember-metal/deprecate_property'], function (exports, _emberMetalCore, _emberMetalDebug, _emberViewsSystemExt, _emberViewsViewsCore_view, _emberViewsMixinsView_context_support, _emberViewsMixinsView_child_views_support, _emberViewsMixinsLegacy_child_views_support, _emberViewsMixinsView_state_support, _emberViewsMixinsTemplate_rendering_support, _emberViewsMixinsClass_names_support, _emberViewsMixinsLegacy_view_support, _emberViewsMixinsInstrumentation_support, _emberViewsMixinsAria_role_support, _emberViewsMixinsVisibility_support, _emberViewsCompatAttrsProxy, _emberViewsMixinsView_support, _emberMetalDeprecate_property) {
57105  // jQuery, Ember.lookup,
57106  // Ember.ContainerView circular dependency
57107  // Ember.ENV
57108  'use strict';
57109
57110  /**
57111  @module ember
57112  @submodule ember-views
57113  */
57114
57115  /**
57116    `Ember.View` is the class in Ember responsible for encapsulating templates of
57117    HTML content, combining templates with data to render as sections of a page's
57118    DOM, and registering and responding to user-initiated events.
57119  
57120    ## HTML Tag
57121  
57122    The default HTML tag name used for a view's DOM representation is `div`. This
57123    can be customized by setting the `tagName` property. The following view
57124    class:
57125  
57126    ```javascript
57127    ParagraphView = Ember.View.extend({
57128      tagName: 'em'
57129    });
57130    ```
57131  
57132    Would result in instances with the following HTML:
57133  
57134    ```html
57135    <em id="ember1" class="ember-view"></em>
57136    ```
57137  
57138    ## HTML `class` Attribute
57139  
57140    The HTML `class` attribute of a view's tag can be set by providing a
57141    `classNames` property that is set to an array of strings:
57142  
57143    ```javascript
57144    MyView = Ember.View.extend({
57145      classNames: ['my-class', 'my-other-class']
57146    });
57147    ```
57148  
57149    Will result in view instances with an HTML representation of:
57150  
57151    ```html
57152    <div id="ember1" class="ember-view my-class my-other-class"></div>
57153    ```
57154  
57155    `class` attribute values can also be set by providing a `classNameBindings`
57156    property set to an array of properties names for the view. The return value
57157    of these properties will be added as part of the value for the view's `class`
57158    attribute. These properties can be computed properties:
57159  
57160    ```javascript
57161    MyView = Ember.View.extend({
57162      classNameBindings: ['propertyA', 'propertyB'],
57163      propertyA: 'from-a',
57164      propertyB: Ember.computed(function() {
57165        if (someLogic) { return 'from-b'; }
57166      })
57167    });
57168    ```
57169  
57170    Will result in view instances with an HTML representation of:
57171  
57172    ```html
57173    <div id="ember1" class="ember-view from-a from-b"></div>
57174    ```
57175  
57176    If the value of a class name binding returns a boolean the property name
57177    itself will be used as the class name if the property is true. The class name
57178    will not be added if the value is `false` or `undefined`.
57179  
57180    ```javascript
57181    MyView = Ember.View.extend({
57182      classNameBindings: ['hovered'],
57183      hovered: true
57184    });
57185    ```
57186  
57187    Will result in view instances with an HTML representation of:
57188  
57189    ```html
57190    <div id="ember1" class="ember-view hovered"></div>
57191    ```
57192  
57193    When using boolean class name bindings you can supply a string value other
57194    than the property name for use as the `class` HTML attribute by appending the
57195    preferred value after a ":" character when defining the binding:
57196  
57197    ```javascript
57198    MyView = Ember.View.extend({
57199      classNameBindings: ['awesome:so-very-cool'],
57200      awesome: true
57201    });
57202    ```
57203  
57204    Will result in view instances with an HTML representation of:
57205  
57206    ```html
57207    <div id="ember1" class="ember-view so-very-cool"></div>
57208    ```
57209  
57210    Boolean value class name bindings whose property names are in a
57211    camelCase-style format will be converted to a dasherized format:
57212  
57213    ```javascript
57214    MyView = Ember.View.extend({
57215      classNameBindings: ['isUrgent'],
57216      isUrgent: true
57217    });
57218    ```
57219  
57220    Will result in view instances with an HTML representation of:
57221  
57222    ```html
57223    <div id="ember1" class="ember-view is-urgent"></div>
57224    ```
57225  
57226    Class name bindings can also refer to object values that are found by
57227    traversing a path relative to the view itself:
57228  
57229    ```javascript
57230    MyView = Ember.View.extend({
57231      classNameBindings: ['messages.empty']
57232      messages: Ember.Object.create({
57233        empty: true
57234      })
57235    });
57236    ```
57237  
57238    Will result in view instances with an HTML representation of:
57239  
57240    ```html
57241    <div id="ember1" class="ember-view empty"></div>
57242    ```
57243  
57244    If you want to add a class name for a property which evaluates to true and
57245    and a different class name if it evaluates to false, you can pass a binding
57246    like this:
57247  
57248    ```javascript
57249    // Applies 'enabled' class when isEnabled is true and 'disabled' when isEnabled is false
57250    Ember.View.extend({
57251      classNameBindings: ['isEnabled:enabled:disabled']
57252      isEnabled: true
57253    });
57254    ```
57255  
57256    Will result in view instances with an HTML representation of:
57257  
57258    ```html
57259    <div id="ember1" class="ember-view enabled"></div>
57260    ```
57261  
57262    When isEnabled is `false`, the resulting HTML representation looks like
57263    this:
57264  
57265    ```html
57266    <div id="ember1" class="ember-view disabled"></div>
57267    ```
57268  
57269    This syntax offers the convenience to add a class if a property is `false`:
57270  
57271    ```javascript
57272    // Applies no class when isEnabled is true and class 'disabled' when isEnabled is false
57273    Ember.View.extend({
57274      classNameBindings: ['isEnabled::disabled']
57275      isEnabled: true
57276    });
57277    ```
57278  
57279    Will result in view instances with an HTML representation of:
57280  
57281    ```html
57282    <div id="ember1" class="ember-view"></div>
57283    ```
57284  
57285    When the `isEnabled` property on the view is set to `false`, it will result
57286    in view instances with an HTML representation of:
57287  
57288    ```html
57289    <div id="ember1" class="ember-view disabled"></div>
57290    ```
57291  
57292    Updates to the value of a class name binding will result in automatic
57293    update of the  HTML `class` attribute in the view's rendered HTML
57294    representation. If the value becomes `false` or `undefined` the class name
57295    will be removed.
57296  
57297    Both `classNames` and `classNameBindings` are concatenated properties. See
57298    [Ember.Object](/api/classes/Ember.Object.html) documentation for more
57299    information about concatenated properties.
57300  
57301    ## HTML Attributes
57302  
57303    The HTML attribute section of a view's tag can be set by providing an
57304    `attributeBindings` property set to an array of property names on the view.
57305    The return value of these properties will be used as the value of the view's
57306    HTML associated attribute:
57307  
57308    ```javascript
57309    AnchorView = Ember.View.extend({
57310      tagName: 'a',
57311      attributeBindings: ['href'],
57312      href: 'http://google.com'
57313    });
57314    ```
57315  
57316    Will result in view instances with an HTML representation of:
57317  
57318    ```html
57319    <a id="ember1" class="ember-view" href="http://google.com"></a>
57320    ```
57321  
57322    One property can be mapped on to another by placing a ":" between
57323    the source property and the destination property:
57324  
57325    ```javascript
57326    AnchorView = Ember.View.extend({
57327      tagName: 'a',
57328      attributeBindings: ['url:href'],
57329      url: 'http://google.com'
57330    });
57331    ```
57332  
57333    Will result in view instances with an HTML representation of:
57334  
57335    ```html
57336    <a id="ember1" class="ember-view" href="http://google.com"></a>
57337    ```
57338  
57339    Namespaced attributes (e.g. `xlink:href`) are supported, but have to be
57340    mapped, since `:` is not a valid character for properties in Javascript:
57341  
57342    ```javascript
57343    UseView = Ember.View.extend({
57344      tagName: 'use',
57345      attributeBindings: ['xlinkHref:xlink:href'],
57346      xlinkHref: '#triangle'
57347    });
57348    ```
57349    Will result in view instances with an HTML representation of:
57350  
57351    ```html
57352    <use xlink:href="#triangle"></use>
57353    ```
57354  
57355    If the return value of an `attributeBindings` monitored property is a boolean
57356    the property's value will be set as a coerced string:
57357  
57358    ```javascript
57359    MyTextInput = Ember.View.extend({
57360      tagName: 'input',
57361      attributeBindings: ['disabled'],
57362      disabled: false
57363    });
57364    ```
57365  
57366    Will result in a view instance with an HTML representation of:
57367  
57368    ```html
57369    <input id="ember1" class="ember-view" disabled="false" />
57370    ```
57371  
57372    `attributeBindings` can refer to computed properties:
57373  
57374    ```javascript
57375    MyTextInput = Ember.View.extend({
57376      tagName: 'input',
57377      attributeBindings: ['disabled'],
57378      disabled: Ember.computed(function() {
57379        if (someLogic) {
57380          return true;
57381        } else {
57382          return false;
57383        }
57384      })
57385    });
57386    ```
57387  
57388    To prevent setting an attribute altogether, use `null` or `undefined` as the
57389    return value of the `attributeBindings` monitored property:
57390  
57391    ```javascript
57392    MyTextInput = Ember.View.extend({
57393      tagName: 'form',
57394      attributeBindings: ['novalidate'],
57395      novalidate: null
57396    });
57397    ```
57398  
57399    Updates to the property of an attribute binding will result in automatic
57400    update of the  HTML attribute in the view's rendered HTML representation.
57401  
57402    `attributeBindings` is a concatenated property. See [Ember.Object](/api/classes/Ember.Object.html)
57403    documentation for more information about concatenated properties.
57404  
57405    ## Templates
57406  
57407    The HTML contents of a view's rendered representation are determined by its
57408    template. Templates can be any function that accepts an optional context
57409    parameter and returns a string of HTML that will be inserted within the
57410    view's tag. Most typically in Ember this function will be a compiled
57411    template.
57412  
57413    ```javascript
57414    AView = Ember.View.extend({
57415      template: Ember.HTMLBars.compile('I am the template')
57416    });
57417    ```
57418  
57419    Will result in view instances with an HTML representation of:
57420  
57421    ```html
57422    <div id="ember1" class="ember-view">I am the template</div>
57423    ```
57424  
57425    Within an Ember application is more common to define a Handlebars templates as
57426    part of a page:
57427  
57428    ```html
57429    <script type='text/x-handlebars' data-template-name='some-template'>
57430      Hello
57431    </script>
57432    ```
57433  
57434    And associate it by name using a view's `templateName` property:
57435  
57436    ```javascript
57437    AView = Ember.View.extend({
57438      templateName: 'some-template'
57439    });
57440    ```
57441  
57442    If you have nested routes, your Handlebars template will look like this:
57443  
57444    ```html
57445    <script type='text/x-handlebars' data-template-name='posts/new'>
57446      <h1>New Post</h1>
57447    </script>
57448    ```
57449  
57450    And `templateName` property:
57451  
57452    ```javascript
57453    AView = Ember.View.extend({
57454      templateName: 'posts/new'
57455    });
57456    ```
57457  
57458    Using a value for `templateName` that does not have a template
57459    with a matching `data-template-name` attribute will throw an error.
57460  
57461    For views classes that may have a template later defined (e.g. as the block
57462    portion of a `{{view}}` helper call in another template or in
57463    a subclass), you can provide a `defaultTemplate` property set to compiled
57464    template function. If a template is not later provided for the view instance
57465    the `defaultTemplate` value will be used:
57466  
57467    ```javascript
57468    AView = Ember.View.extend({
57469      defaultTemplate: Ember.HTMLBars.compile('I was the default'),
57470      template: null,
57471      templateName: null
57472    });
57473    ```
57474  
57475    Will result in instances with an HTML representation of:
57476  
57477    ```html
57478    <div id="ember1" class="ember-view">I was the default</div>
57479    ```
57480  
57481    If a `template` or `templateName` is provided it will take precedence over
57482    `defaultTemplate`:
57483  
57484    ```javascript
57485    AView = Ember.View.extend({
57486      defaultTemplate: Ember.HTMLBars.compile('I was the default')
57487    });
57488  
57489    aView = AView.create({
57490      template: Ember.HTMLBars.compile('I was the template, not default')
57491    });
57492    ```
57493  
57494    Will result in the following HTML representation when rendered:
57495  
57496    ```html
57497    <div id="ember1" class="ember-view">I was the template, not default</div>
57498    ```
57499  
57500    ## View Context
57501  
57502    The default context of the compiled template is the view's controller:
57503  
57504    ```javascript
57505    AView = Ember.View.extend({
57506      template: Ember.HTMLBars.compile('Hello {{excitedGreeting}}')
57507    });
57508  
57509    aController = Ember.Object.create({
57510      firstName: 'Barry',
57511      excitedGreeting: Ember.computed('content.firstName', function() {
57512        return this.get('content.firstName') + '!!!';
57513      })
57514    });
57515  
57516    aView = AView.create({
57517      controller: aController
57518    });
57519    ```
57520  
57521    Will result in an HTML representation of:
57522  
57523    ```html
57524    <div id="ember1" class="ember-view">Hello Barry!!!</div>
57525    ```
57526  
57527    A context can also be explicitly supplied through the view's `context`
57528    property. If the view has neither `context` nor `controller` properties, the
57529    `parentView`'s context will be used.
57530  
57531    ## Layouts
57532  
57533    Views can have a secondary template that wraps their main template. Like
57534    primary templates, layouts can be any function that  accepts an optional
57535    context parameter and returns a string of HTML that will be inserted inside
57536    view's tag. Views whose HTML element is self closing (e.g. `<input />`)
57537    cannot have a layout and this property will be ignored.
57538  
57539    Most typically in Ember a layout will be a compiled template.
57540  
57541    A view's layout can be set directly with the `layout` property or reference
57542    an existing template by name with the `layoutName` property.
57543  
57544    A template used as a layout must contain a single use of the
57545    `{{yield}}` helper. The HTML contents of a view's rendered `template` will be
57546    inserted at this location:
57547  
57548    ```javascript
57549    AViewWithLayout = Ember.View.extend({
57550      layout: Ember.HTMLBars.compile("<div class='my-decorative-class'>{{yield}}</div>"),
57551      template: Ember.HTMLBars.compile("I got wrapped")
57552    });
57553    ```
57554  
57555    Will result in view instances with an HTML representation of:
57556  
57557    ```html
57558    <div id="ember1" class="ember-view">
57559      <div class="my-decorative-class">
57560        I got wrapped
57561      </div>
57562    </div>
57563    ```
57564  
57565    See [Ember.Templates.helpers.yield](/api/classes/Ember.Templates.helpers.html#method_yield)
57566    for more information.
57567  
57568    ## Responding to Browser Events
57569  
57570    Views can respond to user-initiated events in one of three ways: method
57571    implementation, through an event manager, and through `{{action}}` helper use
57572    in their template or layout.
57573  
57574    ### Method Implementation
57575  
57576    Views can respond to user-initiated events by implementing a method that
57577    matches the event name. A `jQuery.Event` object will be passed as the
57578    argument to this method.
57579  
57580    ```javascript
57581    AView = Ember.View.extend({
57582      click: function(event) {
57583        // will be called when an instance's
57584        // rendered element is clicked
57585      }
57586    });
57587    ```
57588  
57589    ### Event Managers
57590  
57591    Views can define an object as their `eventManager` property. This object can
57592    then implement methods that match the desired event names. Matching events
57593    that occur on the view's rendered HTML or the rendered HTML of any of its DOM
57594    descendants will trigger this method. A `jQuery.Event` object will be passed
57595    as the first argument to the method and an  `Ember.View` object as the
57596    second. The `Ember.View` will be the view whose rendered HTML was interacted
57597    with. This may be the view with the `eventManager` property or one of its
57598    descendant views.
57599  
57600    ```javascript
57601    AView = Ember.View.extend({
57602      eventManager: Ember.Object.create({
57603        doubleClick: function(event, view) {
57604          // will be called when an instance's
57605          // rendered element or any rendering
57606          // of this view's descendant
57607          // elements is clicked
57608        }
57609      })
57610    });
57611    ```
57612  
57613    An event defined for an event manager takes precedence over events of the
57614    same name handled through methods on the view.
57615  
57616    ```javascript
57617    AView = Ember.View.extend({
57618      mouseEnter: function(event) {
57619        // will never trigger.
57620      },
57621      eventManager: Ember.Object.create({
57622        mouseEnter: function(event, view) {
57623          // takes precedence over AView#mouseEnter
57624        }
57625      })
57626    });
57627    ```
57628  
57629    Similarly a view's event manager will take precedence for events of any views
57630    rendered as a descendant. A method name that matches an event name will not
57631    be called if the view instance was rendered inside the HTML representation of
57632    a view that has an `eventManager` property defined that handles events of the
57633    name. Events not handled by the event manager will still trigger method calls
57634    on the descendant.
57635  
57636    ```javascript
57637    var App = Ember.Application.create();
57638    App.OuterView = Ember.View.extend({
57639      template: Ember.HTMLBars.compile("outer {{#view 'inner'}}inner{{/view}} outer"),
57640      eventManager: Ember.Object.create({
57641        mouseEnter: function(event, view) {
57642          // view might be instance of either
57643          // OuterView or InnerView depending on
57644          // where on the page the user interaction occurred
57645        }
57646      })
57647    });
57648  
57649    App.InnerView = Ember.View.extend({
57650      click: function(event) {
57651        // will be called if rendered inside
57652        // an OuterView because OuterView's
57653        // eventManager doesn't handle click events
57654      },
57655      mouseEnter: function(event) {
57656        // will never be called if rendered inside
57657        // an OuterView.
57658      }
57659    });
57660    ```
57661  
57662    ### `{{action}}` Helper
57663  
57664    See [Ember.Templates.helpers.action](/api/classes/Ember.Templates.helpers.html#method_action).
57665  
57666    ### Event Names
57667  
57668    All of the event handling approaches described above respond to the same set
57669    of events. The names of the built-in events are listed below. (The hash of
57670    built-in events exists in `Ember.EventDispatcher`.) Additional, custom events
57671    can be registered by using `Ember.Application.customEvents`.
57672  
57673    Touch events:
57674  
57675    * `touchStart`
57676    * `touchMove`
57677    * `touchEnd`
57678    * `touchCancel`
57679  
57680    Keyboard events
57681  
57682    * `keyDown`
57683    * `keyUp`
57684    * `keyPress`
57685  
57686    Mouse events
57687  
57688    * `mouseDown`
57689    * `mouseUp`
57690    * `contextMenu`
57691    * `click`
57692    * `doubleClick`
57693    * `mouseMove`
57694    * `focusIn`
57695    * `focusOut`
57696    * `mouseEnter`
57697    * `mouseLeave`
57698  
57699    Form events:
57700  
57701    * `submit`
57702    * `change`
57703    * `focusIn`
57704    * `focusOut`
57705    * `input`
57706  
57707    HTML5 drag and drop events:
57708  
57709    * `dragStart`
57710    * `drag`
57711    * `dragEnter`
57712    * `dragLeave`
57713    * `dragOver`
57714    * `dragEnd`
57715    * `drop`
57716  
57717    ## `{{view}}` Helper
57718  
57719    Other `Ember.View` instances can be included as part of a view's template by
57720    using the `{{view}}` helper. See [Ember.Templates.helpers.view](/api/classes/Ember.Templates.helpers.html#method_view)
57721    for additional information.
57722  
57723    @class View
57724    @namespace Ember
57725    @extends Ember.CoreView
57726    @deprecated See http://emberjs.com/deprecations/v1.x/#toc_ember-view
57727    @uses Ember.ViewSupport
57728    @uses Ember.ViewContextSupport
57729    @uses Ember.ViewChildViewsSupport
57730    @uses Ember.TemplateRenderingSupport
57731    @uses Ember.ClassNamesSupport
57732    @uses Ember.AttributeBindingsSupport
57733    @uses Ember.LegacyViewSupport
57734    @uses Ember.InstrumentationSupport
57735    @uses Ember.VisibilitySupport
57736    @uses Ember.AriaRoleSupport
57737    @public
57738  */
57739  // jscs:disable validateIndentation
57740  var View = _emberViewsViewsCore_view.default.extend(_emberViewsMixinsView_context_support.default, _emberViewsMixinsView_child_views_support.default, _emberViewsMixinsLegacy_child_views_support.default, _emberViewsMixinsView_state_support.default, _emberViewsMixinsTemplate_rendering_support.default, _emberViewsMixinsClass_names_support.default, _emberViewsMixinsLegacy_view_support.default, _emberViewsMixinsInstrumentation_support.default, _emberViewsMixinsVisibility_support.default, _emberViewsCompatAttrsProxy.default, _emberViewsMixinsAria_role_support.default, _emberViewsMixinsView_support.default, {
57741    init: function () {
57742      this._super.apply(this, arguments);
57743
57744      if (!this._viewRegistry) {
57745        this._viewRegistry = View.views;
57746      }
57747    },
57748
57749    /**
57750      Given a property name, returns a dasherized version of that
57751      property name if the property evaluates to a non-falsy value.
57752       For example, if the view has property `isUrgent` that evaluates to true,
57753      passing `isUrgent` to this method will return `"is-urgent"`.
57754       @method _classStringForProperty
57755      @param property
57756      @private
57757    */
57758    _classStringForProperty: function (parsedPath) {
57759      return View._classStringForValue(parsedPath.path, parsedPath.stream.value(), parsedPath.className, parsedPath.falsyClassName);
57760    }
57761  });
57762
57763  _emberMetalDeprecate_property.deprecateProperty(View.prototype, 'currentState', '_currentState', {
57764    id: 'ember-view.current-state',
57765    until: '2.3.0',
57766    url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-component-currentstate'
57767  });
57768
57769  // jscs:enable validateIndentation
57770
57771  /*
57772    Describe how the specified actions should behave in the various
57773    states that a view can exist in. Possible states:
57774  
57775    * preRender: when a view is first instantiated, and after its
57776      element was destroyed, it is in the preRender state
57777    * inBuffer: once a view has been rendered, but before it has
57778      been inserted into the DOM, it is in the inBuffer state
57779    * hasElement: the DOM representation of the view is created,
57780      and is ready to be inserted
57781    * inDOM: once a view has been inserted into the DOM it is in
57782      the inDOM state. A view spends the vast majority of its
57783      existence in this state.
57784    * destroyed: once a view has been destroyed (using the destroy
57785      method), it is in this state. No further actions can be invoked
57786      on a destroyed view.
57787  */
57788
57789  // in the destroyed state, everything is illegal
57790
57791  // before rendering has begun, all legal manipulations are noops.
57792
57793  // inside the buffer, legal manipulations are done on the buffer
57794
57795  // once the view has been inserted into the DOM, legal manipulations
57796  // are done on the DOM element.
57797
57798  View.reopenClass({
57799    /**
57800      Global views hash
57801       @property views
57802      @static
57803      @type Object
57804      @private
57805    */
57806    views: {},
57807
57808    // If someone overrides the child views computed property when
57809    // defining their class, we want to be able to process the user's
57810    // supplied childViews and then restore the original computed property
57811    // at view initialization time. This happens in Ember.ContainerView's init
57812    // method.
57813    childViewsProperty: _emberViewsMixinsView_child_views_support.childViewsProperty
57814  });
57815
57816  function viewDeprecationMessage() {
57817    _emberMetalDebug.deprecate('Ember.View is deprecated. Consult the Deprecations Guide for a migration strategy.', !!_emberMetalCore.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT, {
57818      url: 'http://emberjs.com/deprecations/v1.x/#toc_ember-view',
57819      id: 'ember-views.view-deprecated',
57820      until: '2.4.0'
57821    });
57822  }
57823
57824  var DeprecatedView = View.extend({
57825    init: function () {
57826      viewDeprecationMessage();
57827      this._super.apply(this, arguments);
57828    }
57829  });
57830
57831  DeprecatedView.reopen = function () {
57832    viewDeprecationMessage();
57833    View.reopen.apply(View, arguments);
57834    return this;
57835  };
57836
57837  exports.default = View;
57838  exports.ViewContextSupport = _emberViewsMixinsView_context_support.default;
57839  exports.ViewChildViewsSupport = _emberViewsMixinsView_child_views_support.default;
57840  exports.ViewStateSupport = _emberViewsMixinsView_state_support.default;
57841  exports.TemplateRenderingSupport = _emberViewsMixinsTemplate_rendering_support.default;
57842  exports.ClassNamesSupport = _emberViewsMixinsClass_names_support.default;
57843  exports.DeprecatedView = DeprecatedView;
57844});
57845// for the side effect of extending Ember.run.queues
57846enifed('htmlbars-runtime/expression-visitor', ['exports'], function (exports) {
57847  /**
57848    # Expression Nodes:
57849  
57850    These nodes are not directly responsible for any part of the DOM, but are
57851    eventually passed to a Statement Node.
57852  
57853    * get
57854    * subexpr
57855    * concat
57856  */
57857
57858  'use strict';
57859
57860  exports.acceptParams = acceptParams;
57861  exports.acceptHash = acceptHash;
57862
57863  function acceptParams(nodes, env, scope) {
57864    var array = [];
57865
57866    for (var i = 0, l = nodes.length; i < l; i++) {
57867      array.push(acceptExpression(nodes[i], env, scope).value);
57868    }
57869
57870    return array;
57871  }
57872
57873  function acceptHash(pairs, env, scope) {
57874    var object = {};
57875
57876    for (var i = 0, l = pairs.length; i < l; i += 2) {
57877      var key = pairs[i];
57878      var value = pairs[i + 1];
57879      object[key] = acceptExpression(value, env, scope).value;
57880    }
57881
57882    return object;
57883  }
57884
57885  function acceptExpression(node, env, scope) {
57886    var ret = { value: null };
57887
57888    // Primitive literals are unambiguously non-array representations of
57889    // themselves.
57890    if (typeof node !== 'object' || node === null) {
57891      ret.value = node;
57892    } else {
57893      ret.value = evaluateNode(node, env, scope);
57894    }
57895
57896    return ret;
57897  }
57898
57899  function evaluateNode(node, env, scope) {
57900    switch (node[0]) {
57901      // can be used by manualElement
57902      case 'value':
57903        return node[1];
57904      case 'get':
57905        return evaluateGet(node, env, scope);
57906      case 'subexpr':
57907        return evaluateSubexpr(node, env, scope);
57908      case 'concat':
57909        return evaluateConcat(node, env, scope);
57910    }
57911  }
57912
57913  function evaluateGet(node, env, scope) {
57914    var path = node[1];
57915
57916    return env.hooks.get(env, scope, path);
57917  }
57918
57919  function evaluateSubexpr(node, env, scope) {
57920    var path = node[1];
57921    var rawParams = node[2];
57922    var rawHash = node[3];
57923
57924    var params = acceptParams(rawParams, env, scope);
57925    var hash = acceptHash(rawHash, env, scope);
57926
57927    return env.hooks.subexpr(env, scope, path, params, hash);
57928  }
57929
57930  function evaluateConcat(node, env, scope) {
57931    var rawParts = node[1];
57932
57933    var parts = acceptParams(rawParts, env, scope);
57934
57935    return env.hooks.concat(env, parts);
57936  }
57937});
57938enifed("htmlbars-runtime/hooks", ["exports", "htmlbars-runtime/render", "morph-range/morph-list", "htmlbars-util/object-utils", "htmlbars-util/morph-utils", "htmlbars-util/template-utils"], function (exports, _htmlbarsRuntimeRender, _morphRangeMorphList, _htmlbarsUtilObjectUtils, _htmlbarsUtilMorphUtils, _htmlbarsUtilTemplateUtils) {
57939  "use strict";
57940
57941  exports.wrap = wrap;
57942  exports.wrapForHelper = wrapForHelper;
57943  exports.createScope = createScope;
57944  exports.createFreshScope = createFreshScope;
57945  exports.bindShadowScope = bindShadowScope;
57946  exports.createChildScope = createChildScope;
57947  exports.bindSelf = bindSelf;
57948  exports.updateSelf = updateSelf;
57949  exports.bindLocal = bindLocal;
57950  exports.updateLocal = updateLocal;
57951  exports.bindBlock = bindBlock;
57952  exports.block = block;
57953  exports.continueBlock = continueBlock;
57954  exports.hostBlock = hostBlock;
57955  exports.handleRedirect = handleRedirect;
57956  exports.handleKeyword = handleKeyword;
57957  exports.linkRenderNode = linkRenderNode;
57958  exports.inline = inline;
57959  exports.keyword = keyword;
57960  exports.invokeHelper = invokeHelper;
57961  exports.classify = classify;
57962  exports.partial = partial;
57963  exports.range = range;
57964  exports.element = element;
57965  exports.attribute = attribute;
57966  exports.subexpr = subexpr;
57967  exports.get = get;
57968  exports.getRoot = getRoot;
57969  exports.getBlock = getBlock;
57970  exports.getChild = getChild;
57971  exports.getValue = getValue;
57972  exports.getCellOrValue = getCellOrValue;
57973  exports.component = component;
57974  exports.concat = concat;
57975  exports.hasHelper = hasHelper;
57976  exports.lookupHelper = lookupHelper;
57977  exports.bindScope = bindScope;
57978  exports.updateScope = updateScope;
57979
57980  /**
57981    HTMLBars delegates the runtime behavior of a template to
57982    hooks provided by the host environment. These hooks explain
57983    the lexical environment of a Handlebars template, the internal
57984    representation of references, and the interaction between an
57985    HTMLBars template and the DOM it is managing.
57986  
57987    While HTMLBars host hooks have access to all of this internal
57988    machinery, templates and helpers have access to the abstraction
57989    provided by the host hooks.
57990  
57991    ## The Lexical Environment
57992  
57993    The default lexical environment of an HTMLBars template includes:
57994  
57995    * Any local variables, provided by *block arguments*
57996    * The current value of `self`
57997  
57998    ## Simple Nesting
57999  
58000    Let's look at a simple template with a nested block:
58001  
58002    ```hbs
58003    <h1>{{title}}</h1>
58004  
58005    {{#if author}}
58006      <p class="byline">{{author}}</p>
58007    {{/if}}
58008    ```
58009  
58010    In this case, the lexical environment at the top-level of the
58011    template does not change inside of the `if` block. This is
58012    achieved via an implementation of `if` that looks like this:
58013  
58014    ```js
58015    registerHelper('if', function(params) {
58016      if (!!params[0]) {
58017        return this.yield();
58018      }
58019    });
58020    ```
58021  
58022    A call to `this.yield` invokes the child template using the
58023    current lexical environment.
58024  
58025    ## Block Arguments
58026  
58027    It is possible for nested blocks to introduce new local
58028    variables:
58029  
58030    ```hbs
58031    {{#count-calls as |i|}}
58032    <h1>{{title}}</h1>
58033    <p>Called {{i}} times</p>
58034    {{/count}}
58035    ```
58036  
58037    In this example, the child block inherits its surrounding
58038    lexical environment, but augments it with a single new
58039    variable binding.
58040  
58041    The implementation of `count-calls` supplies the value of
58042    `i`, but does not otherwise alter the environment:
58043  
58044    ```js
58045    var count = 0;
58046    registerHelper('count-calls', function() {
58047      return this.yield([ ++count ]);
58048    });
58049    ```
58050  */
58051
58052  function wrap(template) {
58053    if (template === null) {
58054      return null;
58055    }
58056
58057    return {
58058      meta: template.meta,
58059      arity: template.arity,
58060      raw: template,
58061      render: function (self, env, options, blockArguments) {
58062        var scope = env.hooks.createFreshScope();
58063
58064        var contextualElement = options && options.contextualElement;
58065        var renderOptions = new _htmlbarsRuntimeRender.RenderOptions(null, self, blockArguments, contextualElement);
58066
58067        return _htmlbarsRuntimeRender.default(template, env, scope, renderOptions);
58068      }
58069    };
58070  }
58071
58072  function wrapForHelper(template, env, scope, morph, renderState, visitor) {
58073    if (!template) {
58074      return {};
58075    }
58076
58077    var yieldArgs = yieldTemplate(template, env, scope, morph, renderState, visitor);
58078
58079    return {
58080      meta: template.meta,
58081      arity: template.arity,
58082      'yield': yieldArgs, // quoted since it's a reserved word, see issue #420
58083      yieldItem: yieldItem(template, env, scope, morph, renderState, visitor),
58084      raw: template,
58085
58086      render: function (self, blockArguments) {
58087        yieldArgs(blockArguments, self);
58088      }
58089    };
58090  }
58091
58092  // Called by a user-land helper to render a template.
58093  function yieldTemplate(template, env, parentScope, morph, renderState, visitor) {
58094    return function (blockArguments, self) {
58095      // Render state is used to track the progress of the helper (since it
58096      // may call into us multiple times). As the user-land helper calls
58097      // into library code, we track what needs to be cleaned up after the
58098      // helper has returned.
58099      //
58100      // Here, we remember that a template has been yielded and so we do not
58101      // need to remove the previous template. (If no template is yielded
58102      // this render by the helper, we assume nothing should be shown and
58103      // remove any previous rendered templates.)
58104      renderState.morphToClear = null;
58105
58106      // In this conditional is true, it means that on the previous rendering pass
58107      // the helper yielded multiple items via `yieldItem()`, but this time they
58108      // are yielding a single template. In that case, we mark the morph list for
58109      // cleanup so it is removed from the DOM.
58110      if (morph.morphList) {
58111        _htmlbarsUtilTemplateUtils.clearMorphList(morph.morphList, morph, env);
58112        renderState.morphListToClear = null;
58113      }
58114
58115      var scope = parentScope;
58116
58117      if (morph.lastYielded && isStableTemplate(template, morph.lastYielded)) {
58118        return morph.lastResult.revalidateWith(env, undefined, self, blockArguments, visitor);
58119      }
58120
58121      // Check to make sure that we actually **need** a new scope, and can't
58122      // share the parent scope. Note that we need to move this check into
58123      // a host hook, because the host's notion of scope may require a new
58124      // scope in more cases than the ones we can determine statically.
58125      if (self !== undefined || parentScope === null || template.arity) {
58126        scope = env.hooks.createChildScope(parentScope);
58127      }
58128
58129      morph.lastYielded = { self: self, template: template, shadowTemplate: null };
58130
58131      // Render the template that was selected by the helper
58132      var renderOptions = new _htmlbarsRuntimeRender.RenderOptions(morph, self, blockArguments);
58133      _htmlbarsRuntimeRender.default(template, env, scope, renderOptions);
58134    };
58135  }
58136
58137  function yieldItem(template, env, parentScope, morph, renderState, visitor) {
58138    // Initialize state that tracks multiple items being
58139    // yielded in.
58140    var currentMorph = null;
58141
58142    // Candidate morphs for deletion.
58143    var candidates = {};
58144
58145    // Reuse existing MorphList if this is not a first-time
58146    // render.
58147    var morphList = morph.morphList;
58148    if (morphList) {
58149      currentMorph = morphList.firstChildMorph;
58150    }
58151
58152    // Advances the currentMorph pointer to the morph in the previously-rendered
58153    // list that matches the yielded key. While doing so, it marks any morphs
58154    // that it advances past as candidates for deletion. Assuming those morphs
58155    // are not yielded in later, they will be removed in the prune step during
58156    // cleanup.
58157    // Note that this helper function assumes that the morph being seeked to is
58158    // guaranteed to exist in the previous MorphList; if this is called and the
58159    // morph does not exist, it will result in an infinite loop
58160    function advanceToKey(key) {
58161      var seek = currentMorph;
58162
58163      while (seek.key !== key) {
58164        candidates[seek.key] = seek;
58165        seek = seek.nextMorph;
58166      }
58167
58168      currentMorph = seek.nextMorph;
58169      return seek;
58170    }
58171
58172    return function (_key, blockArguments, self) {
58173      if (typeof _key !== 'string') {
58174        throw new Error("You must provide a string key when calling `yieldItem`; you provided " + _key);
58175      }
58176
58177      // At least one item has been yielded, so we do not wholesale
58178      // clear the last MorphList but instead apply a prune operation.
58179      renderState.morphListToClear = null;
58180      morph.lastYielded = null;
58181
58182      var morphList, morphMap;
58183
58184      if (!morph.morphList) {
58185        morph.morphList = new _morphRangeMorphList.default();
58186        morph.morphMap = {};
58187        morph.setMorphList(morph.morphList);
58188      }
58189
58190      morphList = morph.morphList;
58191      morphMap = morph.morphMap;
58192
58193      // A map of morphs that have been yielded in on this
58194      // rendering pass. Any morphs that do not make it into
58195      // this list will be pruned from the MorphList during the cleanup
58196      // process.
58197      var handledMorphs = renderState.handledMorphs;
58198      var key = undefined;
58199
58200      if (_key in handledMorphs) {
58201        // In this branch we are dealing with a duplicate key. The strategy
58202        // is to take the original key and append a counter to it that is
58203        // incremented every time the key is reused. In order to greatly
58204        // reduce the chance of colliding with another valid key we also add
58205        // an extra string "--z8mS2hvDW0A--" to the new key.
58206        var collisions = renderState.collisions;
58207        if (collisions === undefined) {
58208          collisions = renderState.collisions = {};
58209        }
58210        var count = collisions[_key] | 0;
58211        collisions[_key] = ++count;
58212
58213        key = _key + '--z8mS2hvDW0A--' + count;
58214      } else {
58215        key = _key;
58216      }
58217
58218      if (currentMorph && currentMorph.key === key) {
58219        yieldTemplate(template, env, parentScope, currentMorph, renderState, visitor)(blockArguments, self);
58220        currentMorph = currentMorph.nextMorph;
58221        handledMorphs[key] = currentMorph;
58222      } else if (morphMap[key] !== undefined) {
58223        var foundMorph = morphMap[key];
58224
58225        if (key in candidates) {
58226          // If we already saw this morph, move it forward to this position
58227          morphList.insertBeforeMorph(foundMorph, currentMorph);
58228        } else {
58229          // Otherwise, move the pointer forward to the existing morph for this key
58230          advanceToKey(key);
58231        }
58232
58233        handledMorphs[foundMorph.key] = foundMorph;
58234        yieldTemplate(template, env, parentScope, foundMorph, renderState, visitor)(blockArguments, self);
58235      } else {
58236        var childMorph = _htmlbarsRuntimeRender.createChildMorph(env.dom, morph);
58237        childMorph.key = key;
58238        morphMap[key] = handledMorphs[key] = childMorph;
58239        morphList.insertBeforeMorph(childMorph, currentMorph);
58240        yieldTemplate(template, env, parentScope, childMorph, renderState, visitor)(blockArguments, self);
58241      }
58242
58243      renderState.morphListToPrune = morphList;
58244      morph.childNodes = null;
58245    };
58246  }
58247
58248  function isStableTemplate(template, lastYielded) {
58249    return !lastYielded.shadowTemplate && template === lastYielded.template;
58250  }
58251  function optionsFor(template, inverse, env, scope, morph, visitor) {
58252    // If there was a template yielded last time, set morphToClear so it will be cleared
58253    // if no template is yielded on this render.
58254    var morphToClear = morph.lastResult ? morph : null;
58255    var renderState = new _htmlbarsUtilTemplateUtils.RenderState(morphToClear, morph.morphList || null);
58256
58257    return {
58258      templates: {
58259        template: wrapForHelper(template, env, scope, morph, renderState, visitor),
58260        inverse: wrapForHelper(inverse, env, scope, morph, renderState, visitor)
58261      },
58262      renderState: renderState
58263    };
58264  }
58265
58266  function thisFor(options) {
58267    return {
58268      arity: options.template.arity,
58269      'yield': options.template.yield, // quoted since it's a reserved word, see issue #420
58270      yieldItem: options.template.yieldItem,
58271      yieldIn: options.template.yieldIn
58272    };
58273  }
58274
58275  /**
58276    Host Hook: createScope
58277  
58278    @param {Scope?} parentScope
58279    @return Scope
58280  
58281    Corresponds to entering a new HTMLBars block.
58282  
58283    This hook is invoked when a block is entered with
58284    a new `self` or additional local variables.
58285  
58286    When invoked for a top-level template, the
58287    `parentScope` is `null`, and this hook should return
58288    a fresh Scope.
58289  
58290    When invoked for a child template, the `parentScope`
58291    is the scope for the parent environment.
58292  
58293    Note that the `Scope` is an opaque value that is
58294    passed to other host hooks. For example, the `get`
58295    hook uses the scope to retrieve a value for a given
58296    scope and variable name.
58297  */
58298
58299  function createScope(env, parentScope) {
58300    if (parentScope) {
58301      return env.hooks.createChildScope(parentScope);
58302    } else {
58303      return env.hooks.createFreshScope();
58304    }
58305  }
58306
58307  function createFreshScope() {
58308    // because `in` checks have unpredictable performance, keep a
58309    // separate dictionary to track whether a local was bound.
58310    // See `bindLocal` for more information.
58311    return { self: null, blocks: {}, locals: {}, localPresent: {} };
58312  }
58313
58314  /**
58315    Host Hook: bindShadowScope
58316  
58317    @param {Scope?} parentScope
58318    @return Scope
58319  
58320    Corresponds to rendering a new template into an existing
58321    render tree, but with a new top-level lexical scope. This
58322    template is called the "shadow root".
58323  
58324    If a shadow template invokes `{{yield}}`, it will render
58325    the block provided to the shadow root in the original
58326    lexical scope.
58327  
58328    ```hbs
58329    {{!-- post template --}}
58330    <p>{{props.title}}</p>
58331    {{yield}}
58332  
58333    {{!-- blog template --}}
58334    {{#post title="Hello world"}}
58335      <p>by {{byline}}</p>
58336      <article>This is my first post</article>
58337    {{/post}}
58338  
58339    {{#post title="Goodbye world"}}
58340      <p>by {{byline}}</p>
58341      <article>This is my last post</article>
58342    {{/post}}
58343    ```
58344  
58345    ```js
58346    helpers.post = function(params, hash, options) {
58347      options.template.yieldIn(postTemplate, { props: hash });
58348    };
58349  
58350    blog.render({ byline: "Yehuda Katz" });
58351    ```
58352  
58353    Produces:
58354  
58355    ```html
58356    <p>Hello world</p>
58357    <p>by Yehuda Katz</p>
58358    <article>This is my first post</article>
58359  
58360    <p>Goodbye world</p>
58361    <p>by Yehuda Katz</p>
58362    <article>This is my last post</article>
58363    ```
58364  
58365    In short, `yieldIn` creates a new top-level scope for the
58366    provided template and renders it, making the original block
58367    available to `{{yield}}` in that template.
58368  */
58369
58370  function bindShadowScope(env /*, parentScope, shadowScope */) {
58371    return env.hooks.createFreshScope();
58372  }
58373
58374  function createChildScope(parent) {
58375    var scope = Object.create(parent);
58376    scope.locals = Object.create(parent.locals);
58377    scope.localPresent = Object.create(parent.localPresent);
58378    scope.blocks = Object.create(parent.blocks);
58379    return scope;
58380  }
58381
58382  /**
58383    Host Hook: bindSelf
58384  
58385    @param {Scope} scope
58386    @param {any} self
58387  
58388    Corresponds to entering a template.
58389  
58390    This hook is invoked when the `self` value for a scope is ready to be bound.
58391  
58392    The host must ensure that child scopes reflect the change to the `self` in
58393    future calls to the `get` hook.
58394  */
58395
58396  function bindSelf(env, scope, self) {
58397    scope.self = self;
58398  }
58399
58400  function updateSelf(env, scope, self) {
58401    env.hooks.bindSelf(env, scope, self);
58402  }
58403
58404  /**
58405    Host Hook: bindLocal
58406  
58407    @param {Environment} env
58408    @param {Scope} scope
58409    @param {String} name
58410    @param {any} value
58411  
58412    Corresponds to entering a template with block arguments.
58413  
58414    This hook is invoked when a local variable for a scope has been provided.
58415  
58416    The host must ensure that child scopes reflect the change in future calls
58417    to the `get` hook.
58418  */
58419
58420  function bindLocal(env, scope, name, value) {
58421    scope.localPresent[name] = true;
58422    scope.locals[name] = value;
58423  }
58424
58425  function updateLocal(env, scope, name, value) {
58426    env.hooks.bindLocal(env, scope, name, value);
58427  }
58428
58429  /**
58430    Host Hook: bindBlock
58431  
58432    @param {Environment} env
58433    @param {Scope} scope
58434    @param {Function} block
58435  
58436    Corresponds to entering a shadow template that was invoked by a block helper with
58437    `yieldIn`.
58438  
58439    This hook is invoked with an opaque block that will be passed along
58440    to the shadow template, and inserted into the shadow template when
58441    `{{yield}}` is used. Optionally provide a non-default block name
58442    that can be targeted by `{{yield to=blockName}}`.
58443  */
58444
58445  function bindBlock(env, scope, block) {
58446    var name = arguments.length <= 3 || arguments[3] === undefined ? 'default' : arguments[3];
58447
58448    scope.blocks[name] = block;
58449  }
58450
58451  /**
58452    Host Hook: block
58453  
58454    @param {RenderNode} renderNode
58455    @param {Environment} env
58456    @param {Scope} scope
58457    @param {String} path
58458    @param {Array} params
58459    @param {Object} hash
58460    @param {Block} block
58461    @param {Block} elseBlock
58462  
58463    Corresponds to:
58464  
58465    ```hbs
58466    {{#helper param1 param2 key1=val1 key2=val2}}
58467      {{!-- child template --}}
58468    {{/helper}}
58469    ```
58470  
58471    This host hook is a workhorse of the system. It is invoked
58472    whenever a block is encountered, and is responsible for
58473    resolving the helper to call, and then invoke it.
58474  
58475    The helper should be invoked with:
58476  
58477    - `{Array} params`: the parameters passed to the helper
58478      in the template.
58479    - `{Object} hash`: an object containing the keys and values passed
58480      in the hash position in the template.
58481  
58482    The values in `params` and `hash` will already be resolved
58483    through a previous call to the `get` host hook.
58484  
58485    The helper should be invoked with a `this` value that is
58486    an object with one field:
58487  
58488    `{Function} yield`: when invoked, this function executes the
58489    block with the current scope. It takes an optional array of
58490    block parameters. If block parameters are supplied, HTMLBars
58491    will invoke the `bindLocal` host hook to bind the supplied
58492    values to the block arguments provided by the template.
58493  
58494    In general, the default implementation of `block` should work
58495    for most host environments. It delegates to other host hooks
58496    where appropriate, and properly invokes the helper with the
58497    appropriate arguments.
58498  */
58499
58500  function block(morph, env, scope, path, params, hash, template, inverse, visitor) {
58501    if (handleRedirect(morph, env, scope, path, params, hash, template, inverse, visitor)) {
58502      return;
58503    }
58504
58505    continueBlock(morph, env, scope, path, params, hash, template, inverse, visitor);
58506  }
58507
58508  function continueBlock(morph, env, scope, path, params, hash, template, inverse, visitor) {
58509    hostBlock(morph, env, scope, template, inverse, null, visitor, function (options) {
58510      var helper = env.hooks.lookupHelper(env, scope, path);
58511      return env.hooks.invokeHelper(morph, env, scope, visitor, params, hash, helper, options.templates, thisFor(options.templates));
58512    });
58513  }
58514
58515  function hostBlock(morph, env, scope, template, inverse, shadowOptions, visitor, callback) {
58516    var options = optionsFor(template, inverse, env, scope, morph, visitor);
58517    _htmlbarsUtilTemplateUtils.renderAndCleanup(morph, env, options, shadowOptions, callback);
58518  }
58519
58520  function handleRedirect(morph, env, scope, path, params, hash, template, inverse, visitor) {
58521    if (!path) {
58522      return false;
58523    }
58524
58525    var redirect = env.hooks.classify(env, scope, path);
58526    if (redirect) {
58527      switch (redirect) {
58528        case 'component':
58529          env.hooks.component(morph, env, scope, path, params, hash, { default: template, inverse: inverse }, visitor);break;
58530        case 'inline':
58531          env.hooks.inline(morph, env, scope, path, params, hash, visitor);break;
58532        case 'block':
58533          env.hooks.block(morph, env, scope, path, params, hash, template, inverse, visitor);break;
58534        default:
58535          throw new Error("Internal HTMLBars redirection to " + redirect + " not supported");
58536      }
58537      return true;
58538    }
58539
58540    if (handleKeyword(path, morph, env, scope, params, hash, template, inverse, visitor)) {
58541      return true;
58542    }
58543
58544    return false;
58545  }
58546
58547  function handleKeyword(path, morph, env, scope, params, hash, template, inverse, visitor) {
58548    var keyword = env.hooks.keywords[path];
58549    if (!keyword) {
58550      return false;
58551    }
58552
58553    if (typeof keyword === 'function') {
58554      return keyword(morph, env, scope, params, hash, template, inverse, visitor);
58555    }
58556
58557    if (keyword.willRender) {
58558      keyword.willRender(morph, env);
58559    }
58560
58561    var lastState, newState;
58562    if (keyword.setupState) {
58563      lastState = _htmlbarsUtilObjectUtils.shallowCopy(morph.getState());
58564      newState = morph.setState(keyword.setupState(lastState, env, scope, params, hash));
58565    }
58566
58567    if (keyword.childEnv) {
58568      // Build the child environment...
58569      env = keyword.childEnv(morph.getState(), env);
58570
58571      // ..then save off the child env builder on the render node. If the render
58572      // node tree is re-rendered and this node is not dirty, the child env
58573      // builder will still be invoked so that child dirty render nodes still get
58574      // the correct child env.
58575      morph.buildChildEnv = keyword.childEnv;
58576    }
58577
58578    var firstTime = !morph.rendered;
58579
58580    if (keyword.isEmpty) {
58581      var isEmpty = keyword.isEmpty(morph.getState(), env, scope, params, hash);
58582
58583      if (isEmpty) {
58584        if (!firstTime) {
58585          _htmlbarsUtilTemplateUtils.clearMorph(morph, env, false);
58586        }
58587        return true;
58588      }
58589    }
58590
58591    if (firstTime) {
58592      if (keyword.render) {
58593        keyword.render(morph, env, scope, params, hash, template, inverse, visitor);
58594      }
58595      morph.rendered = true;
58596      return true;
58597    }
58598
58599    var isStable;
58600    if (keyword.isStable) {
58601      isStable = keyword.isStable(lastState, newState);
58602    } else {
58603      isStable = stableState(lastState, newState);
58604    }
58605
58606    if (isStable) {
58607      if (keyword.rerender) {
58608        var newEnv = keyword.rerender(morph, env, scope, params, hash, template, inverse, visitor);
58609        env = newEnv || env;
58610      }
58611      _htmlbarsUtilMorphUtils.validateChildMorphs(env, morph, visitor);
58612      return true;
58613    } else {
58614      _htmlbarsUtilTemplateUtils.clearMorph(morph, env, false);
58615    }
58616
58617    // If the node is unstable, re-render from scratch
58618    if (keyword.render) {
58619      keyword.render(morph, env, scope, params, hash, template, inverse, visitor);
58620      morph.rendered = true;
58621      return true;
58622    }
58623  }
58624
58625  function stableState(oldState, newState) {
58626    if (_htmlbarsUtilObjectUtils.keyLength(oldState) !== _htmlbarsUtilObjectUtils.keyLength(newState)) {
58627      return false;
58628    }
58629
58630    for (var prop in oldState) {
58631      if (oldState[prop] !== newState[prop]) {
58632        return false;
58633      }
58634    }
58635
58636    return true;
58637  }
58638
58639  function linkRenderNode() /* morph, env, scope, params, hash */{
58640    return;
58641  }
58642
58643  /**
58644    Host Hook: inline
58645  
58646    @param {RenderNode} renderNode
58647    @param {Environment} env
58648    @param {Scope} scope
58649    @param {String} path
58650    @param {Array} params
58651    @param {Hash} hash
58652  
58653    Corresponds to:
58654  
58655    ```hbs
58656    {{helper param1 param2 key1=val1 key2=val2}}
58657    ```
58658  
58659    This host hook is similar to the `block` host hook, but it
58660    invokes helpers that do not supply an attached block.
58661  
58662    Like the `block` hook, the helper should be invoked with:
58663  
58664    - `{Array} params`: the parameters passed to the helper
58665      in the template.
58666    - `{Object} hash`: an object containing the keys and values passed
58667      in the hash position in the template.
58668  
58669    The values in `params` and `hash` will already be resolved
58670    through a previous call to the `get` host hook.
58671  
58672    In general, the default implementation of `inline` should work
58673    for most host environments. It delegates to other host hooks
58674    where appropriate, and properly invokes the helper with the
58675    appropriate arguments.
58676  
58677    The default implementation of `inline` also makes `partial`
58678    a keyword. Instead of invoking a helper named `partial`,
58679    it invokes the `partial` host hook.
58680  */
58681
58682  function inline(morph, env, scope, path, params, hash, visitor) {
58683    if (handleRedirect(morph, env, scope, path, params, hash, null, null, visitor)) {
58684      return;
58685    }
58686
58687    var value = undefined,
58688        hasValue = undefined;
58689    if (morph.linkedResult) {
58690      value = env.hooks.getValue(morph.linkedResult);
58691      hasValue = true;
58692    } else {
58693      var options = optionsFor(null, null, env, scope, morph);
58694
58695      var helper = env.hooks.lookupHelper(env, scope, path);
58696      var result = env.hooks.invokeHelper(morph, env, scope, visitor, params, hash, helper, options.templates, thisFor(options.templates));
58697
58698      if (result && result.link) {
58699        morph.linkedResult = result.value;
58700        _htmlbarsUtilMorphUtils.linkParams(env, scope, morph, '@content-helper', [morph.linkedResult], null);
58701      }
58702
58703      if (result && 'value' in result) {
58704        value = env.hooks.getValue(result.value);
58705        hasValue = true;
58706      }
58707    }
58708
58709    if (hasValue) {
58710      if (morph.lastValue !== value) {
58711        morph.setContent(value);
58712      }
58713      morph.lastValue = value;
58714    }
58715  }
58716
58717  function keyword(path, morph, env, scope, params, hash, template, inverse, visitor) {
58718    handleKeyword(path, morph, env, scope, params, hash, template, inverse, visitor);
58719  }
58720
58721  function invokeHelper(morph, env, scope, visitor, _params, _hash, helper, templates, context) {
58722    var params = normalizeArray(env, _params);
58723    var hash = normalizeObject(env, _hash);
58724    return { value: helper.call(context, params, hash, templates) };
58725  }
58726
58727  function normalizeArray(env, array) {
58728    var out = new Array(array.length);
58729
58730    for (var i = 0, l = array.length; i < l; i++) {
58731      out[i] = env.hooks.getCellOrValue(array[i]);
58732    }
58733
58734    return out;
58735  }
58736
58737  function normalizeObject(env, object) {
58738    var out = {};
58739
58740    for (var prop in object) {
58741      out[prop] = env.hooks.getCellOrValue(object[prop]);
58742    }
58743
58744    return out;
58745  }
58746
58747  function classify() /* env, scope, path */{
58748    return null;
58749  }
58750
58751  var keywords = {
58752    partial: function (morph, env, scope, params) {
58753      var value = env.hooks.partial(morph, env, scope, params[0]);
58754      morph.setContent(value);
58755      return true;
58756    },
58757
58758    // quoted since it's a reserved word, see issue #420
58759    'yield': function (morph, env, scope, params, hash, template, inverse, visitor) {
58760      // the current scope is provided purely for the creation of shadow
58761      // scopes; it should not be provided to user code.
58762
58763      var to = env.hooks.getValue(hash.to) || 'default';
58764      var block = env.hooks.getBlock(scope, to);
58765
58766      if (block) {
58767        block.invoke(env, params, hash.self, morph, scope, visitor);
58768      }
58769      return true;
58770    },
58771
58772    hasBlock: function (morph, env, scope, params) {
58773      var name = env.hooks.getValue(params[0]) || 'default';
58774      return !!env.hooks.getBlock(scope, name);
58775    },
58776
58777    hasBlockParams: function (morph, env, scope, params) {
58778      var name = env.hooks.getValue(params[0]) || 'default';
58779      var block = env.hooks.getBlock(scope, name);
58780      return !!(block && block.arity);
58781    }
58782
58783  };
58784
58785  exports.keywords = keywords;
58786  /**
58787    Host Hook: partial
58788  
58789    @param {RenderNode} renderNode
58790    @param {Environment} env
58791    @param {Scope} scope
58792    @param {String} path
58793  
58794    Corresponds to:
58795  
58796    ```hbs
58797    {{partial "location"}}
58798    ```
58799  
58800    This host hook is invoked by the default implementation of
58801    the `inline` hook. This makes `partial` a keyword in an
58802    HTMLBars environment using the default `inline` host hook.
58803  
58804    It is implemented as a host hook so that it can retrieve
58805    the named partial out of the `Environment`. Helpers, in
58806    contrast, only have access to the values passed in to them,
58807    and not to the ambient lexical environment.
58808  
58809    The host hook should invoke the referenced partial with
58810    the ambient `self`.
58811  */
58812
58813  function partial(renderNode, env, scope, path) {
58814    var template = env.partials[path];
58815    return template.render(scope.self, env, {}).fragment;
58816  }
58817
58818  /**
58819    Host hook: range
58820  
58821    @param {RenderNode} renderNode
58822    @param {Environment} env
58823    @param {Scope} scope
58824    @param {any} value
58825  
58826    Corresponds to:
58827  
58828    ```hbs
58829    {{content}}
58830    {{{unescaped}}}
58831    ```
58832  
58833    This hook is responsible for updating a render node
58834    that represents a range of content with a value.
58835  */
58836
58837  function range(morph, env, scope, path, value, visitor) {
58838    if (handleRedirect(morph, env, scope, path, [], {}, null, null, visitor)) {
58839      return;
58840    }
58841
58842    value = env.hooks.getValue(value);
58843
58844    if (morph.lastValue !== value) {
58845      morph.setContent(value);
58846    }
58847
58848    morph.lastValue = value;
58849  }
58850
58851  /**
58852    Host hook: element
58853  
58854    @param {RenderNode} renderNode
58855    @param {Environment} env
58856    @param {Scope} scope
58857    @param {String} path
58858    @param {Array} params
58859    @param {Hash} hash
58860  
58861    Corresponds to:
58862  
58863    ```hbs
58864    <div {{bind-attr foo=bar}}></div>
58865    ```
58866  
58867    This hook is responsible for invoking a helper that
58868    modifies an element.
58869  
58870    Its purpose is largely legacy support for awkward
58871    idioms that became common when using the string-based
58872    Handlebars engine.
58873  
58874    Most of the uses of the `element` hook are expected
58875    to be superseded by component syntax and the
58876    `attribute` hook.
58877  */
58878
58879  function element(morph, env, scope, path, params, hash, visitor) {
58880    if (handleRedirect(morph, env, scope, path, params, hash, null, null, visitor)) {
58881      return;
58882    }
58883
58884    var helper = env.hooks.lookupHelper(env, scope, path);
58885    if (helper) {
58886      env.hooks.invokeHelper(null, env, scope, null, params, hash, helper, { element: morph.element });
58887    }
58888  }
58889
58890  /**
58891    Host hook: attribute
58892  
58893    @param {RenderNode} renderNode
58894    @param {Environment} env
58895    @param {String} name
58896    @param {any} value
58897  
58898    Corresponds to:
58899  
58900    ```hbs
58901    <div foo={{bar}}></div>
58902    ```
58903  
58904    This hook is responsible for updating a render node
58905    that represents an element's attribute with a value.
58906  
58907    It receives the name of the attribute as well as an
58908    already-resolved value, and should update the render
58909    node with the value if appropriate.
58910  */
58911
58912  function attribute(morph, env, scope, name, value) {
58913    value = env.hooks.getValue(value);
58914
58915    if (morph.lastValue !== value) {
58916      morph.setContent(value);
58917    }
58918
58919    morph.lastValue = value;
58920  }
58921
58922  function subexpr(env, scope, helperName, params, hash) {
58923    var helper = env.hooks.lookupHelper(env, scope, helperName);
58924    var result = env.hooks.invokeHelper(null, env, scope, null, params, hash, helper, {});
58925    if (result && 'value' in result) {
58926      return env.hooks.getValue(result.value);
58927    }
58928  }
58929
58930  /**
58931    Host Hook: get
58932  
58933    @param {Environment} env
58934    @param {Scope} scope
58935    @param {String} path
58936  
58937    Corresponds to:
58938  
58939    ```hbs
58940    {{foo.bar}}
58941      ^
58942  
58943    {{helper foo.bar key=value}}
58944             ^           ^
58945    ```
58946  
58947    This hook is the "leaf" hook of the system. It is used to
58948    resolve a path relative to the current scope.
58949  */
58950
58951  function get(env, scope, path) {
58952    if (path === '') {
58953      return scope.self;
58954    }
58955
58956    var keys = path.split('.');
58957    var value = env.hooks.getRoot(scope, keys[0])[0];
58958
58959    for (var i = 1; i < keys.length; i++) {
58960      if (value) {
58961        value = env.hooks.getChild(value, keys[i]);
58962      } else {
58963        break;
58964      }
58965    }
58966
58967    return value;
58968  }
58969
58970  function getRoot(scope, key) {
58971    if (scope.localPresent[key]) {
58972      return [scope.locals[key]];
58973    } else if (scope.self) {
58974      return [scope.self[key]];
58975    } else {
58976      return [undefined];
58977    }
58978  }
58979
58980  function getBlock(scope, key) {
58981    return scope.blocks[key];
58982  }
58983
58984  function getChild(value, key) {
58985    return value[key];
58986  }
58987
58988  function getValue(reference) {
58989    return reference;
58990  }
58991
58992  function getCellOrValue(reference) {
58993    return reference;
58994  }
58995
58996  function component(morph, env, scope, tagName, params, attrs, templates, visitor) {
58997    if (env.hooks.hasHelper(env, scope, tagName)) {
58998      return env.hooks.block(morph, env, scope, tagName, params, attrs, templates.default, templates.inverse, visitor);
58999    }
59000
59001    componentFallback(morph, env, scope, tagName, attrs, templates.default);
59002  }
59003
59004  function concat(env, params) {
59005    var value = "";
59006    for (var i = 0, l = params.length; i < l; i++) {
59007      value += env.hooks.getValue(params[i]);
59008    }
59009    return value;
59010  }
59011
59012  function componentFallback(morph, env, scope, tagName, attrs, template) {
59013    var element = env.dom.createElement(tagName);
59014    for (var name in attrs) {
59015      element.setAttribute(name, env.hooks.getValue(attrs[name]));
59016    }
59017    var fragment = _htmlbarsRuntimeRender.default(template, env, scope, {}).fragment;
59018    element.appendChild(fragment);
59019    morph.setNode(element);
59020  }
59021
59022  function hasHelper(env, scope, helperName) {
59023    return env.helpers[helperName] !== undefined;
59024  }
59025
59026  function lookupHelper(env, scope, helperName) {
59027    return env.helpers[helperName];
59028  }
59029
59030  function bindScope() /* env, scope */{
59031    // this function is used to handle host-specified extensions to scope
59032    // other than `self`, `locals` and `block`.
59033  }
59034
59035  function updateScope(env, scope) {
59036    env.hooks.bindScope(env, scope);
59037  }
59038
59039  exports.default = {
59040    // fundamental hooks that you will likely want to override
59041    bindLocal: bindLocal,
59042    bindSelf: bindSelf,
59043    bindScope: bindScope,
59044    classify: classify,
59045    component: component,
59046    concat: concat,
59047    createFreshScope: createFreshScope,
59048    getChild: getChild,
59049    getRoot: getRoot,
59050    getBlock: getBlock,
59051    getValue: getValue,
59052    getCellOrValue: getCellOrValue,
59053    keywords: keywords,
59054    linkRenderNode: linkRenderNode,
59055    partial: partial,
59056    subexpr: subexpr,
59057
59058    // fundamental hooks with good default behavior
59059    bindBlock: bindBlock,
59060    bindShadowScope: bindShadowScope,
59061    updateLocal: updateLocal,
59062    updateSelf: updateSelf,
59063    updateScope: updateScope,
59064    createChildScope: createChildScope,
59065    hasHelper: hasHelper,
59066    lookupHelper: lookupHelper,
59067    invokeHelper: invokeHelper,
59068    cleanupRenderNode: null,
59069    destroyRenderNode: null,
59070    willCleanupTree: null,
59071    didCleanupTree: null,
59072    willRenderNode: null,
59073    didRenderNode: null,
59074
59075    // derived hooks
59076    attribute: attribute,
59077    block: block,
59078    createScope: createScope,
59079    element: element,
59080    get: get,
59081    inline: inline,
59082    range: range,
59083    keyword: keyword
59084  };
59085});
59086enifed("htmlbars-runtime/morph", ["exports", "morph-range"], function (exports, _morphRange) {
59087  "use strict";
59088
59089  var guid = 1;
59090
59091  function HTMLBarsMorph(domHelper, contextualElement) {
59092    this.super$constructor(domHelper, contextualElement);
59093
59094    this._state = undefined;
59095    this.ownerNode = null;
59096    this.isDirty = false;
59097    this.isSubtreeDirty = false;
59098    this.lastYielded = null;
59099    this.lastResult = null;
59100    this.lastValue = null;
59101    this.buildChildEnv = null;
59102    this.morphList = null;
59103    this.morphMap = null;
59104    this.key = null;
59105    this.linkedParams = null;
59106    this.linkedResult = null;
59107    this.childNodes = null;
59108    this.rendered = false;
59109    this.guid = "range" + guid++;
59110    this.seen = false;
59111  }
59112
59113  HTMLBarsMorph.empty = function (domHelper, contextualElement) {
59114    var morph = new HTMLBarsMorph(domHelper, contextualElement);
59115    morph.clear();
59116    return morph;
59117  };
59118
59119  HTMLBarsMorph.create = function (domHelper, contextualElement, node) {
59120    var morph = new HTMLBarsMorph(domHelper, contextualElement);
59121    morph.setNode(node);
59122    return morph;
59123  };
59124
59125  HTMLBarsMorph.attach = function (domHelper, contextualElement, firstNode, lastNode) {
59126    var morph = new HTMLBarsMorph(domHelper, contextualElement);
59127    morph.setRange(firstNode, lastNode);
59128    return morph;
59129  };
59130
59131  var prototype = HTMLBarsMorph.prototype = Object.create(_morphRange.default.prototype);
59132  prototype.constructor = HTMLBarsMorph;
59133  prototype.super$constructor = _morphRange.default;
59134
59135  prototype.getState = function () {
59136    if (!this._state) {
59137      this._state = {};
59138    }
59139
59140    return this._state;
59141  };
59142
59143  prototype.setState = function (newState) {
59144    /*jshint -W093 */
59145
59146    return this._state = newState;
59147  };
59148
59149  exports.default = HTMLBarsMorph;
59150});
59151enifed("htmlbars-runtime/node-visitor", ["exports", "htmlbars-util/morph-utils", "htmlbars-runtime/expression-visitor"], function (exports, _htmlbarsUtilMorphUtils, _htmlbarsRuntimeExpressionVisitor) {
59152  "use strict";
59153
59154  /**
59155    Node classification:
59156  
59157    # Primary Statement Nodes:
59158  
59159    These nodes are responsible for a render node that represents a morph-range.
59160  
59161    * block
59162    * inline
59163    * content
59164    * element
59165    * component
59166  
59167    # Leaf Statement Nodes:
59168  
59169    This node is responsible for a render node that represents a morph-attr.
59170  
59171    * attribute
59172  */
59173
59174  function linkParamsAndHash(env, scope, morph, path, params, hash) {
59175    if (morph.linkedParams) {
59176      params = morph.linkedParams.params;
59177      hash = morph.linkedParams.hash;
59178    } else {
59179      params = params && _htmlbarsRuntimeExpressionVisitor.acceptParams(params, env, scope);
59180      hash = hash && _htmlbarsRuntimeExpressionVisitor.acceptHash(hash, env, scope);
59181    }
59182
59183    _htmlbarsUtilMorphUtils.linkParams(env, scope, morph, path, params, hash);
59184    return [params, hash];
59185  }
59186
59187  var AlwaysDirtyVisitor = {
59188
59189    block: function (node, morph, env, scope, template, visitor) {
59190      var path = node[1];
59191      var params = node[2];
59192      var hash = node[3];
59193      var templateId = node[4];
59194      var inverseId = node[5];
59195
59196      var paramsAndHash = linkParamsAndHash(env, scope, morph, path, params, hash);
59197
59198      morph.isDirty = morph.isSubtreeDirty = false;
59199      env.hooks.block(morph, env, scope, path, paramsAndHash[0], paramsAndHash[1], templateId === null ? null : template.templates[templateId], inverseId === null ? null : template.templates[inverseId], visitor);
59200    },
59201
59202    inline: function (node, morph, env, scope, visitor) {
59203      var path = node[1];
59204      var params = node[2];
59205      var hash = node[3];
59206
59207      var paramsAndHash = linkParamsAndHash(env, scope, morph, path, params, hash);
59208
59209      morph.isDirty = morph.isSubtreeDirty = false;
59210      env.hooks.inline(morph, env, scope, path, paramsAndHash[0], paramsAndHash[1], visitor);
59211    },
59212
59213    content: function (node, morph, env, scope, visitor) {
59214      var path = node[1];
59215
59216      morph.isDirty = morph.isSubtreeDirty = false;
59217
59218      if (isHelper(env, scope, path)) {
59219        env.hooks.inline(morph, env, scope, path, [], {}, visitor);
59220        if (morph.linkedResult) {
59221          _htmlbarsUtilMorphUtils.linkParams(env, scope, morph, '@content-helper', [morph.linkedResult], null);
59222        }
59223        return;
59224      }
59225
59226      var params = undefined;
59227      if (morph.linkedParams) {
59228        params = morph.linkedParams.params;
59229      } else {
59230        params = [env.hooks.get(env, scope, path)];
59231      }
59232
59233      _htmlbarsUtilMorphUtils.linkParams(env, scope, morph, '@range', params, null);
59234      env.hooks.range(morph, env, scope, path, params[0], visitor);
59235    },
59236
59237    element: function (node, morph, env, scope, visitor) {
59238      var path = node[1];
59239      var params = node[2];
59240      var hash = node[3];
59241
59242      var paramsAndHash = linkParamsAndHash(env, scope, morph, path, params, hash);
59243
59244      morph.isDirty = morph.isSubtreeDirty = false;
59245      env.hooks.element(morph, env, scope, path, paramsAndHash[0], paramsAndHash[1], visitor);
59246    },
59247
59248    attribute: function (node, morph, env, scope) {
59249      var name = node[1];
59250      var value = node[2];
59251
59252      var paramsAndHash = linkParamsAndHash(env, scope, morph, '@attribute', [value], null);
59253
59254      morph.isDirty = morph.isSubtreeDirty = false;
59255      env.hooks.attribute(morph, env, scope, name, paramsAndHash[0][0]);
59256    },
59257
59258    component: function (node, morph, env, scope, template, visitor) {
59259      var path = node[1];
59260      var attrs = node[2];
59261      var templateId = node[3];
59262      var inverseId = node[4];
59263
59264      var paramsAndHash = linkParamsAndHash(env, scope, morph, path, [], attrs);
59265      var templates = {
59266        default: template.templates[templateId],
59267        inverse: template.templates[inverseId]
59268      };
59269
59270      morph.isDirty = morph.isSubtreeDirty = false;
59271      env.hooks.component(morph, env, scope, path, paramsAndHash[0], paramsAndHash[1], templates, visitor);
59272    },
59273
59274    attributes: function (node, morph, env, scope, parentMorph, visitor) {
59275      var template = node[1];
59276
59277      env.hooks.attributes(morph, env, scope, template, parentMorph, visitor);
59278    }
59279
59280  };
59281
59282  exports.AlwaysDirtyVisitor = AlwaysDirtyVisitor;
59283  exports.default = {
59284    block: function (node, morph, env, scope, template, visitor) {
59285      dirtyCheck(env, morph, visitor, function (visitor) {
59286        AlwaysDirtyVisitor.block(node, morph, env, scope, template, visitor);
59287      });
59288    },
59289
59290    inline: function (node, morph, env, scope, visitor) {
59291      dirtyCheck(env, morph, visitor, function (visitor) {
59292        AlwaysDirtyVisitor.inline(node, morph, env, scope, visitor);
59293      });
59294    },
59295
59296    content: function (node, morph, env, scope, visitor) {
59297      dirtyCheck(env, morph, visitor, function (visitor) {
59298        AlwaysDirtyVisitor.content(node, morph, env, scope, visitor);
59299      });
59300    },
59301
59302    element: function (node, morph, env, scope, template, visitor) {
59303      dirtyCheck(env, morph, visitor, function (visitor) {
59304        AlwaysDirtyVisitor.element(node, morph, env, scope, template, visitor);
59305      });
59306    },
59307
59308    attribute: function (node, morph, env, scope, template) {
59309      dirtyCheck(env, morph, null, function () {
59310        AlwaysDirtyVisitor.attribute(node, morph, env, scope, template);
59311      });
59312    },
59313
59314    component: function (node, morph, env, scope, template, visitor) {
59315      dirtyCheck(env, morph, visitor, function (visitor) {
59316        AlwaysDirtyVisitor.component(node, morph, env, scope, template, visitor);
59317      });
59318    },
59319
59320    attributes: function (node, morph, env, scope, parentMorph, visitor) {
59321      AlwaysDirtyVisitor.attributes(node, morph, env, scope, parentMorph, visitor);
59322    }
59323  };
59324
59325  function dirtyCheck(_env, morph, visitor, callback) {
59326    var isDirty = morph.isDirty;
59327    var isSubtreeDirty = morph.isSubtreeDirty;
59328    var env = _env;
59329
59330    if (isSubtreeDirty) {
59331      visitor = AlwaysDirtyVisitor;
59332    }
59333
59334    if (isDirty || isSubtreeDirty) {
59335      callback(visitor);
59336    } else {
59337      if (morph.buildChildEnv) {
59338        env = morph.buildChildEnv(morph.getState(), env);
59339      }
59340      _htmlbarsUtilMorphUtils.validateChildMorphs(env, morph, visitor);
59341    }
59342  }
59343
59344  function isHelper(env, scope, path) {
59345    return env.hooks.keywords[path] !== undefined || env.hooks.hasHelper(env, scope, path);
59346  }
59347});
59348enifed("htmlbars-runtime/render", ["exports", "htmlbars-util/morph-utils", "htmlbars-runtime/node-visitor", "htmlbars-runtime/morph", "htmlbars-util/template-utils", "htmlbars-util/void-tag-names"], function (exports, _htmlbarsUtilMorphUtils, _htmlbarsRuntimeNodeVisitor, _htmlbarsRuntimeMorph, _htmlbarsUtilTemplateUtils, _htmlbarsUtilVoidTagNames) {
59349  "use strict";
59350
59351  exports.default = render;
59352  exports.RenderOptions = RenderOptions;
59353  exports.manualElement = manualElement;
59354  exports.attachAttributes = attachAttributes;
59355  exports.createChildMorph = createChildMorph;
59356  exports.getCachedFragment = getCachedFragment;
59357
59358  var svgNamespace = "http://www.w3.org/2000/svg";
59359
59360  function render(template, env, scope, options) {
59361    var dom = env.dom;
59362    var contextualElement;
59363
59364    if (options) {
59365      if (options.renderNode) {
59366        contextualElement = options.renderNode.contextualElement;
59367      } else if (options.contextualElement) {
59368        contextualElement = options.contextualElement;
59369      }
59370    }
59371
59372    dom.detectNamespace(contextualElement);
59373
59374    var renderResult = RenderResult.build(env, scope, template, options, contextualElement);
59375    renderResult.render();
59376
59377    return renderResult;
59378  }
59379
59380  function RenderOptions(renderNode, self, blockArguments, contextualElement) {
59381    this.renderNode = renderNode || null;
59382    this.self = self;
59383    this.blockArguments = blockArguments || null;
59384    this.contextualElement = contextualElement || null;
59385  }
59386
59387  function RenderResult(env, scope, options, rootNode, ownerNode, nodes, fragment, template, shouldSetContent) {
59388    this.root = rootNode;
59389    this.fragment = fragment;
59390
59391    this.nodes = nodes;
59392    this.template = template;
59393    this.statements = template.statements.slice();
59394    this.env = env;
59395    this.scope = scope;
59396    this.shouldSetContent = shouldSetContent;
59397
59398    if (options.self !== undefined) {
59399      this.bindSelf(options.self);
59400    }
59401    if (options.blockArguments !== undefined) {
59402      this.bindLocals(options.blockArguments);
59403    }
59404
59405    this.initializeNodes(ownerNode);
59406  }
59407
59408  RenderResult.build = function (env, scope, template, options, contextualElement) {
59409    var dom = env.dom;
59410    var fragment = getCachedFragment(template, env);
59411    var nodes = template.buildRenderNodes(dom, fragment, contextualElement);
59412
59413    var rootNode, ownerNode, shouldSetContent;
59414
59415    if (options && options.renderNode) {
59416      rootNode = options.renderNode;
59417      ownerNode = rootNode.ownerNode;
59418      shouldSetContent = true;
59419    } else {
59420      rootNode = dom.createMorph(null, fragment.firstChild, fragment.lastChild, contextualElement);
59421      ownerNode = rootNode;
59422      rootNode.ownerNode = ownerNode;
59423      shouldSetContent = false;
59424    }
59425
59426    if (rootNode.childNodes) {
59427      _htmlbarsUtilMorphUtils.visitChildren(rootNode.childNodes, function (node) {
59428        _htmlbarsUtilTemplateUtils.clearMorph(node, env, true);
59429      });
59430    }
59431
59432    rootNode.childNodes = nodes;
59433    return new RenderResult(env, scope, options, rootNode, ownerNode, nodes, fragment, template, shouldSetContent);
59434  };
59435
59436  function manualElement(tagName, attributes, _isEmpty) {
59437    var statements = [];
59438
59439    for (var key in attributes) {
59440      if (typeof attributes[key] === 'string') {
59441        continue;
59442      }
59443      statements.push(["attribute", key, attributes[key]]);
59444    }
59445
59446    var isEmpty = _isEmpty || _htmlbarsUtilVoidTagNames.default[tagName];
59447
59448    if (!isEmpty) {
59449      statements.push(['content', 'yield']);
59450    }
59451
59452    var template = {
59453      arity: 0,
59454      cachedFragment: null,
59455      hasRendered: false,
59456      buildFragment: function buildFragment(dom) {
59457        var el0 = dom.createDocumentFragment();
59458        if (tagName === 'svg') {
59459          dom.setNamespace(svgNamespace);
59460        }
59461        var el1 = dom.createElement(tagName);
59462
59463        for (var key in attributes) {
59464          if (typeof attributes[key] !== 'string') {
59465            continue;
59466          }
59467          dom.setAttribute(el1, key, attributes[key]);
59468        }
59469
59470        if (!isEmpty) {
59471          var el2 = dom.createComment("");
59472          dom.appendChild(el1, el2);
59473        }
59474
59475        dom.appendChild(el0, el1);
59476
59477        return el0;
59478      },
59479      buildRenderNodes: function buildRenderNodes(dom, fragment) {
59480        var element = dom.childAt(fragment, [0]);
59481        var morphs = [];
59482
59483        for (var key in attributes) {
59484          if (typeof attributes[key] === 'string') {
59485            continue;
59486          }
59487          morphs.push(dom.createAttrMorph(element, key));
59488        }
59489
59490        if (!isEmpty) {
59491          morphs.push(dom.createMorphAt(element, 0, 0));
59492        }
59493
59494        return morphs;
59495      },
59496      statements: statements,
59497      locals: [],
59498      templates: []
59499    };
59500
59501    return template;
59502  }
59503
59504  function attachAttributes(attributes) {
59505    var statements = [];
59506
59507    for (var key in attributes) {
59508      if (typeof attributes[key] === 'string') {
59509        continue;
59510      }
59511      statements.push(["attribute", key, attributes[key]]);
59512    }
59513
59514    var template = {
59515      arity: 0,
59516      cachedFragment: null,
59517      hasRendered: false,
59518      buildFragment: function buildFragment(dom) {
59519        var el0 = this.element;
59520        if (el0.namespaceURI === "http://www.w3.org/2000/svg") {
59521          dom.setNamespace(svgNamespace);
59522        }
59523        for (var key in attributes) {
59524          if (typeof attributes[key] !== 'string') {
59525            continue;
59526          }
59527          dom.setAttribute(el0, key, attributes[key]);
59528        }
59529
59530        return el0;
59531      },
59532      buildRenderNodes: function buildRenderNodes(dom) {
59533        var element = this.element;
59534        var morphs = [];
59535
59536        for (var key in attributes) {
59537          if (typeof attributes[key] === 'string') {
59538            continue;
59539          }
59540          morphs.push(dom.createAttrMorph(element, key));
59541        }
59542
59543        return morphs;
59544      },
59545      statements: statements,
59546      locals: [],
59547      templates: [],
59548      element: null
59549    };
59550
59551    return template;
59552  }
59553
59554  RenderResult.prototype.initializeNodes = function (ownerNode) {
59555    var childNodes = this.root.childNodes;
59556
59557    for (var i = 0, l = childNodes.length; i < l; i++) {
59558      childNodes[i].ownerNode = ownerNode;
59559    }
59560  };
59561
59562  RenderResult.prototype.render = function () {
59563    this.root.lastResult = this;
59564    this.root.rendered = true;
59565    this.populateNodes(_htmlbarsRuntimeNodeVisitor.AlwaysDirtyVisitor);
59566
59567    if (this.shouldSetContent && this.root.setContent) {
59568      this.root.setContent(this.fragment);
59569    }
59570  };
59571
59572  RenderResult.prototype.dirty = function () {
59573    _htmlbarsUtilMorphUtils.visitChildren([this.root], function (node) {
59574      node.isDirty = true;
59575    });
59576  };
59577
59578  RenderResult.prototype.revalidate = function (env, self, blockArguments, scope) {
59579    this.revalidateWith(env, scope, self, blockArguments, _htmlbarsRuntimeNodeVisitor.default);
59580  };
59581
59582  RenderResult.prototype.rerender = function (env, self, blockArguments, scope) {
59583    this.revalidateWith(env, scope, self, blockArguments, _htmlbarsRuntimeNodeVisitor.AlwaysDirtyVisitor);
59584  };
59585
59586  RenderResult.prototype.revalidateWith = function (env, scope, self, blockArguments, visitor) {
59587    if (env !== undefined) {
59588      this.env = env;
59589    }
59590    if (scope !== undefined) {
59591      this.scope = scope;
59592    }
59593    this.updateScope();
59594
59595    if (self !== undefined) {
59596      this.updateSelf(self);
59597    }
59598    if (blockArguments !== undefined) {
59599      this.updateLocals(blockArguments);
59600    }
59601
59602    this.populateNodes(visitor);
59603  };
59604
59605  RenderResult.prototype.destroy = function () {
59606    var rootNode = this.root;
59607    _htmlbarsUtilTemplateUtils.clearMorph(rootNode, this.env, true);
59608  };
59609
59610  RenderResult.prototype.populateNodes = function (visitor) {
59611    var env = this.env;
59612    var scope = this.scope;
59613    var template = this.template;
59614    var nodes = this.nodes;
59615    var statements = this.statements;
59616    var i, l;
59617
59618    for (i = 0, l = statements.length; i < l; i++) {
59619      var statement = statements[i];
59620      var morph = nodes[i];
59621
59622      if (env.hooks.willRenderNode) {
59623        env.hooks.willRenderNode(morph, env, scope);
59624      }
59625
59626      switch (statement[0]) {
59627        case 'block':
59628          visitor.block(statement, morph, env, scope, template, visitor);break;
59629        case 'inline':
59630          visitor.inline(statement, morph, env, scope, visitor);break;
59631        case 'content':
59632          visitor.content(statement, morph, env, scope, visitor);break;
59633        case 'element':
59634          visitor.element(statement, morph, env, scope, template, visitor);break;
59635        case 'attribute':
59636          visitor.attribute(statement, morph, env, scope);break;
59637        case 'component':
59638          visitor.component(statement, morph, env, scope, template, visitor);break;
59639      }
59640
59641      if (env.hooks.didRenderNode) {
59642        env.hooks.didRenderNode(morph, env, scope);
59643      }
59644    }
59645  };
59646
59647  RenderResult.prototype.bindScope = function () {
59648    this.env.hooks.bindScope(this.env, this.scope);
59649  };
59650
59651  RenderResult.prototype.updateScope = function () {
59652    this.env.hooks.updateScope(this.env, this.scope);
59653  };
59654
59655  RenderResult.prototype.bindSelf = function (self) {
59656    this.env.hooks.bindSelf(this.env, this.scope, self);
59657  };
59658
59659  RenderResult.prototype.updateSelf = function (self) {
59660    this.env.hooks.updateSelf(this.env, this.scope, self);
59661  };
59662
59663  RenderResult.prototype.bindLocals = function (blockArguments) {
59664    var localNames = this.template.locals;
59665
59666    for (var i = 0, l = localNames.length; i < l; i++) {
59667      this.env.hooks.bindLocal(this.env, this.scope, localNames[i], blockArguments[i]);
59668    }
59669  };
59670
59671  RenderResult.prototype.updateLocals = function (blockArguments) {
59672    var localNames = this.template.locals;
59673
59674    for (var i = 0, l = localNames.length; i < l; i++) {
59675      this.env.hooks.updateLocal(this.env, this.scope, localNames[i], blockArguments[i]);
59676    }
59677  };
59678
59679  function initializeNode(node, owner) {
59680    node.ownerNode = owner;
59681  }
59682
59683  function createChildMorph(dom, parentMorph, contextualElement) {
59684    var morph = _htmlbarsRuntimeMorph.default.empty(dom, contextualElement || parentMorph.contextualElement);
59685    initializeNode(morph, parentMorph.ownerNode);
59686    return morph;
59687  }
59688
59689  function getCachedFragment(template, env) {
59690    var dom = env.dom,
59691        fragment;
59692    if (env.useFragmentCache && dom.canClone) {
59693      if (template.cachedFragment === null) {
59694        fragment = template.buildFragment(dom);
59695        if (template.hasRendered) {
59696          template.cachedFragment = fragment;
59697        } else {
59698          template.hasRendered = true;
59699        }
59700      }
59701      if (template.cachedFragment) {
59702        fragment = dom.cloneNode(template.cachedFragment, true);
59703      }
59704    } else if (!fragment) {
59705      fragment = template.buildFragment(dom);
59706    }
59707
59708    return fragment;
59709  }
59710});
59711enifed('htmlbars-runtime', ['exports', 'htmlbars-runtime/hooks', 'htmlbars-runtime/render', 'htmlbars-util/morph-utils', 'htmlbars-util/template-utils'], function (exports, _htmlbarsRuntimeHooks, _htmlbarsRuntimeRender, _htmlbarsUtilMorphUtils, _htmlbarsUtilTemplateUtils) {
59712  'use strict';
59713
59714  var internal = {
59715    blockFor: _htmlbarsUtilTemplateUtils.blockFor,
59716    manualElement: _htmlbarsRuntimeRender.manualElement,
59717    hostBlock: _htmlbarsRuntimeHooks.hostBlock,
59718    continueBlock: _htmlbarsRuntimeHooks.continueBlock,
59719    hostYieldWithShadowTemplate: _htmlbarsRuntimeHooks.hostYieldWithShadowTemplate,
59720    visitChildren: _htmlbarsUtilMorphUtils.visitChildren,
59721    validateChildMorphs: _htmlbarsUtilMorphUtils.validateChildMorphs,
59722    clearMorph: _htmlbarsUtilTemplateUtils.clearMorph
59723  };
59724
59725  exports.hooks = _htmlbarsRuntimeHooks.default;
59726  exports.render = _htmlbarsRuntimeRender.default;
59727  exports.internal = internal;
59728});
59729enifed('htmlbars-util/array-utils', ['exports'], function (exports) {
59730  'use strict';
59731
59732  exports.forEach = forEach;
59733  exports.map = map;
59734
59735  function forEach(array, callback, binding) {
59736    var i, l;
59737    if (binding === undefined) {
59738      for (i = 0, l = array.length; i < l; i++) {
59739        callback(array[i], i, array);
59740      }
59741    } else {
59742      for (i = 0, l = array.length; i < l; i++) {
59743        callback.call(binding, array[i], i, array);
59744      }
59745    }
59746  }
59747
59748  function map(array, callback) {
59749    var output = [];
59750    var i, l;
59751
59752    for (i = 0, l = array.length; i < l; i++) {
59753      output.push(callback(array[i], i, array));
59754    }
59755
59756    return output;
59757  }
59758
59759  var getIdx;
59760  if (Array.prototype.indexOf) {
59761    getIdx = function (array, obj, from) {
59762      return array.indexOf(obj, from);
59763    };
59764  } else {
59765    getIdx = function (array, obj, from) {
59766      if (from === undefined || from === null) {
59767        from = 0;
59768      } else if (from < 0) {
59769        from = Math.max(0, array.length + from);
59770      }
59771      for (var i = from, l = array.length; i < l; i++) {
59772        if (array[i] === obj) {
59773          return i;
59774        }
59775      }
59776      return -1;
59777    };
59778  }
59779
59780  var isArray = Array.isArray || function (array) {
59781    return Object.prototype.toString.call(array) === '[object Array]';
59782  };
59783
59784  exports.isArray = isArray;
59785  var indexOfArray = getIdx;
59786  exports.indexOfArray = indexOfArray;
59787});
59788enifed('htmlbars-util/handlebars/safe-string', ['exports'], function (exports) {
59789  // Build out our basic SafeString type
59790  'use strict';
59791
59792  function SafeString(string) {
59793    this.string = string;
59794  }
59795
59796  SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
59797    return '' + this.string;
59798  };
59799
59800  exports.default = SafeString;
59801});
59802enifed('htmlbars-util/handlebars/utils', ['exports'], function (exports) {
59803  'use strict';
59804
59805  exports.extend = extend;
59806  exports.indexOf = indexOf;
59807  exports.escapeExpression = escapeExpression;
59808  exports.isEmpty = isEmpty;
59809  exports.blockParams = blockParams;
59810  exports.appendContextPath = appendContextPath;
59811  var escape = {
59812    '&': '&amp;',
59813    '<': '&lt;',
59814    '>': '&gt;',
59815    '"': '&quot;',
59816    "'": '&#x27;',
59817    '`': '&#x60;'
59818  };
59819
59820  var badChars = /[&<>"'`]/g,
59821      possible = /[&<>"'`]/;
59822
59823  function escapeChar(chr) {
59824    return escape[chr];
59825  }
59826
59827  function extend(obj /* , ...source */) {
59828    for (var i = 1; i < arguments.length; i++) {
59829      for (var key in arguments[i]) {
59830        if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
59831          obj[key] = arguments[i][key];
59832        }
59833      }
59834    }
59835
59836    return obj;
59837  }
59838
59839  var toString = Object.prototype.toString;
59840
59841  exports.toString = toString;
59842  // Sourced from lodash
59843  // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
59844  /*eslint-disable func-style, no-var */
59845  var isFunction = function (value) {
59846    return typeof value === 'function';
59847  };
59848  // fallback for older versions of Chrome and Safari
59849  /* istanbul ignore next */
59850  if (isFunction(/x/)) {
59851    exports.isFunction = isFunction = function (value) {
59852      return typeof value === 'function' && toString.call(value) === '[object Function]';
59853    };
59854  }
59855  var isFunction;
59856  exports.isFunction = isFunction;
59857  /*eslint-enable func-style, no-var */
59858
59859  /* istanbul ignore next */
59860  var isArray = Array.isArray || function (value) {
59861    return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
59862  };
59863
59864  exports.isArray = isArray;
59865  // Older IE versions do not directly support indexOf so we must implement our own, sadly.
59866
59867  function indexOf(array, value) {
59868    for (var i = 0, len = array.length; i < len; i++) {
59869      if (array[i] === value) {
59870        return i;
59871      }
59872    }
59873    return -1;
59874  }
59875
59876  function escapeExpression(string) {
59877    if (typeof string !== 'string') {
59878      // don't escape SafeStrings, since they're already safe
59879      if (string && string.toHTML) {
59880        return string.toHTML();
59881      } else if (string == null) {
59882        return '';
59883      } else if (!string) {
59884        return string + '';
59885      }
59886
59887      // Force a string conversion as this will be done by the append regardless and
59888      // the regex test will do this transparently behind the scenes, causing issues if
59889      // an object's to string has escaped characters in it.
59890      string = '' + string;
59891    }
59892
59893    if (!possible.test(string)) {
59894      return string;
59895    }
59896    return string.replace(badChars, escapeChar);
59897  }
59898
59899  function isEmpty(value) {
59900    if (!value && value !== 0) {
59901      return true;
59902    } else if (isArray(value) && value.length === 0) {
59903      return true;
59904    } else {
59905      return false;
59906    }
59907  }
59908
59909  function blockParams(params, ids) {
59910    params.path = ids;
59911    return params;
59912  }
59913
59914  function appendContextPath(contextPath, id) {
59915    return (contextPath ? contextPath + '.' : '') + id;
59916  }
59917});
59918enifed("htmlbars-util/morph-utils", ["exports"], function (exports) {
59919  /*globals console*/
59920
59921  "use strict";
59922
59923  exports.visitChildren = visitChildren;
59924  exports.validateChildMorphs = validateChildMorphs;
59925  exports.linkParams = linkParams;
59926  exports.dump = dump;
59927
59928  function visitChildren(nodes, callback) {
59929    if (!nodes || nodes.length === 0) {
59930      return;
59931    }
59932
59933    nodes = nodes.slice();
59934
59935    while (nodes.length) {
59936      var node = nodes.pop();
59937      callback(node);
59938
59939      if (node.childNodes) {
59940        nodes.push.apply(nodes, node.childNodes);
59941      } else if (node.firstChildMorph) {
59942        var current = node.firstChildMorph;
59943
59944        while (current) {
59945          nodes.push(current);
59946          current = current.nextMorph;
59947        }
59948      } else if (node.morphList) {
59949        var current = node.morphList.firstChildMorph;
59950
59951        while (current) {
59952          nodes.push(current);
59953          current = current.nextMorph;
59954        }
59955      }
59956    }
59957  }
59958
59959  function validateChildMorphs(env, morph, visitor) {
59960    var morphList = morph.morphList;
59961    if (morph.morphList) {
59962      var current = morphList.firstChildMorph;
59963
59964      while (current) {
59965        var next = current.nextMorph;
59966        validateChildMorphs(env, current, visitor);
59967        current = next;
59968      }
59969    } else if (morph.lastResult) {
59970      morph.lastResult.revalidateWith(env, undefined, undefined, undefined, visitor);
59971    } else if (morph.childNodes) {
59972      // This means that the childNodes were wired up manually
59973      for (var i = 0, l = morph.childNodes.length; i < l; i++) {
59974        validateChildMorphs(env, morph.childNodes[i], visitor);
59975      }
59976    }
59977  }
59978
59979  function linkParams(env, scope, morph, path, params, hash) {
59980    if (morph.linkedParams) {
59981      return;
59982    }
59983
59984    if (env.hooks.linkRenderNode(morph, env, scope, path, params, hash)) {
59985      morph.linkedParams = { params: params, hash: hash };
59986    }
59987  }
59988
59989  function dump(node) {
59990    console.group(node, node.isDirty);
59991
59992    if (node.childNodes) {
59993      map(node.childNodes, dump);
59994    } else if (node.firstChildMorph) {
59995      var current = node.firstChildMorph;
59996
59997      while (current) {
59998        dump(current);
59999        current = current.nextMorph;
60000      }
60001    } else if (node.morphList) {
60002      dump(node.morphList);
60003    }
60004
60005    console.groupEnd();
60006  }
60007
60008  function map(nodes, cb) {
60009    for (var i = 0, l = nodes.length; i < l; i++) {
60010      cb(nodes[i]);
60011    }
60012  }
60013});
60014enifed('htmlbars-util/namespaces', ['exports'], function (exports) {
60015  // ref http://dev.w3.org/html5/spec-LC/namespaces.html
60016  'use strict';
60017
60018  exports.getAttrNamespace = getAttrNamespace;
60019  var defaultNamespaces = {
60020    html: 'http://www.w3.org/1999/xhtml',
60021    mathml: 'http://www.w3.org/1998/Math/MathML',
60022    svg: 'http://www.w3.org/2000/svg',
60023    xlink: 'http://www.w3.org/1999/xlink',
60024    xml: 'http://www.w3.org/XML/1998/namespace'
60025  };
60026
60027  function getAttrNamespace(attrName, detectedNamespace) {
60028    if (detectedNamespace) {
60029      return detectedNamespace;
60030    }
60031
60032    var namespace;
60033
60034    var colonIndex = attrName.indexOf(':');
60035    if (colonIndex !== -1) {
60036      var prefix = attrName.slice(0, colonIndex);
60037      namespace = defaultNamespaces[prefix];
60038    }
60039
60040    return namespace || null;
60041  }
60042});
60043enifed("htmlbars-util/object-utils", ["exports"], function (exports) {
60044  "use strict";
60045
60046  exports.merge = merge;
60047  exports.shallowCopy = shallowCopy;
60048  exports.keySet = keySet;
60049  exports.keyLength = keyLength;
60050
60051  function merge(options, defaults) {
60052    for (var prop in defaults) {
60053      if (options.hasOwnProperty(prop)) {
60054        continue;
60055      }
60056      options[prop] = defaults[prop];
60057    }
60058    return options;
60059  }
60060
60061  function shallowCopy(obj) {
60062    return merge({}, obj);
60063  }
60064
60065  function keySet(obj) {
60066    var set = {};
60067
60068    for (var prop in obj) {
60069      if (obj.hasOwnProperty(prop)) {
60070        set[prop] = true;
60071      }
60072    }
60073
60074    return set;
60075  }
60076
60077  function keyLength(obj) {
60078    var count = 0;
60079
60080    for (var prop in obj) {
60081      if (obj.hasOwnProperty(prop)) {
60082        count++;
60083      }
60084    }
60085
60086    return count;
60087  }
60088});
60089enifed("htmlbars-util/quoting", ["exports"], function (exports) {
60090  "use strict";
60091
60092  exports.hash = hash;
60093  exports.repeat = repeat;
60094  function escapeString(str) {
60095    str = str.replace(/\\/g, "\\\\");
60096    str = str.replace(/"/g, '\\"');
60097    str = str.replace(/\n/g, "\\n");
60098    return str;
60099  }
60100
60101  exports.escapeString = escapeString;
60102
60103  function string(str) {
60104    return '"' + escapeString(str) + '"';
60105  }
60106
60107  exports.string = string;
60108
60109  function array(a) {
60110    return "[" + a + "]";
60111  }
60112
60113  exports.array = array;
60114
60115  function hash(pairs) {
60116    return "{" + pairs.join(", ") + "}";
60117  }
60118
60119  function repeat(chars, times) {
60120    var str = "";
60121    while (times--) {
60122      str += chars;
60123    }
60124    return str;
60125  }
60126});
60127enifed('htmlbars-util/safe-string', ['exports', 'htmlbars-util/handlebars/safe-string'], function (exports, _htmlbarsUtilHandlebarsSafeString) {
60128  'use strict';
60129
60130  exports.default = _htmlbarsUtilHandlebarsSafeString.default;
60131});
60132enifed("htmlbars-util/template-utils", ["exports", "htmlbars-util/morph-utils", "htmlbars-runtime/render"], function (exports, _htmlbarsUtilMorphUtils, _htmlbarsRuntimeRender) {
60133  "use strict";
60134
60135  exports.RenderState = RenderState;
60136  exports.blockFor = blockFor;
60137  exports.renderAndCleanup = renderAndCleanup;
60138  exports.clearMorph = clearMorph;
60139  exports.clearMorphList = clearMorphList;
60140
60141  function RenderState(renderNode, morphList) {
60142    // The morph list that is no longer needed and can be
60143    // destroyed.
60144    this.morphListToClear = morphList;
60145
60146    // The morph list that needs to be pruned of any items
60147    // that were not yielded on a subsequent render.
60148    this.morphListToPrune = null;
60149
60150    // A map of morphs for each item yielded in during this
60151    // rendering pass. Any morphs in the DOM but not in this map
60152    // will be pruned during cleanup.
60153    this.handledMorphs = {};
60154    this.collisions = undefined;
60155
60156    // The morph to clear once rendering is complete. By
60157    // default, we set this to the previous morph (to catch
60158    // the case where nothing is yielded; in that case, we
60159    // should just clear the morph). Otherwise this gets set
60160    // to null if anything is rendered.
60161    this.morphToClear = renderNode;
60162
60163    this.shadowOptions = null;
60164  }
60165
60166  function Block(render, template, blockOptions) {
60167    this.render = render;
60168    this.template = template;
60169    this.blockOptions = blockOptions;
60170    this.arity = template.arity;
60171  }
60172
60173  Block.prototype.invoke = function (env, blockArguments, _self, renderNode, parentScope, visitor) {
60174    if (renderNode.lastResult) {
60175      renderNode.lastResult.revalidateWith(env, undefined, _self, blockArguments, visitor);
60176    } else {
60177      this._firstRender(env, blockArguments, _self, renderNode, parentScope);
60178    }
60179  };
60180
60181  Block.prototype._firstRender = function (env, blockArguments, _self, renderNode, parentScope) {
60182    var options = { renderState: new RenderState(renderNode) };
60183    var render = this.render;
60184    var template = this.template;
60185    var scope = this.blockOptions.scope;
60186
60187    var shadowScope = scope ? env.hooks.createChildScope(scope) : env.hooks.createFreshScope();
60188
60189    env.hooks.bindShadowScope(env, parentScope, shadowScope, this.blockOptions.options);
60190
60191    if (_self !== undefined) {
60192      env.hooks.bindSelf(env, shadowScope, _self);
60193    } else if (this.blockOptions.self !== undefined) {
60194      env.hooks.bindSelf(env, shadowScope, this.blockOptions.self);
60195    }
60196
60197    bindBlocks(env, shadowScope, this.blockOptions.yieldTo);
60198
60199    renderAndCleanup(renderNode, env, options, null, function () {
60200      options.renderState.morphToClear = null;
60201      var renderOptions = new _htmlbarsRuntimeRender.RenderOptions(renderNode, undefined, blockArguments);
60202      render(template, env, shadowScope, renderOptions);
60203    });
60204  };
60205
60206  function blockFor(render, template, blockOptions) {
60207    return new Block(render, template, blockOptions);
60208  }
60209
60210  function bindBlocks(env, shadowScope, blocks) {
60211    if (!blocks) {
60212      return;
60213    }
60214    if (blocks instanceof Block) {
60215      env.hooks.bindBlock(env, shadowScope, blocks);
60216    } else {
60217      for (var name in blocks) {
60218        if (blocks.hasOwnProperty(name)) {
60219          env.hooks.bindBlock(env, shadowScope, blocks[name], name);
60220        }
60221      }
60222    }
60223  }
60224
60225  function renderAndCleanup(morph, env, options, shadowOptions, callback) {
60226    // The RenderState object is used to collect information about what the
60227    // helper or hook being invoked has yielded. Once it has finished either
60228    // yielding multiple items (via yieldItem) or a single template (via
60229    // yieldTemplate), we detect what was rendered and how it differs from
60230    // the previous render, cleaning up old state in DOM as appropriate.
60231    var renderState = options.renderState;
60232    renderState.collisions = undefined;
60233    renderState.shadowOptions = shadowOptions;
60234
60235    // Invoke the callback, instructing it to save information about what it
60236    // renders into RenderState.
60237    var result = callback(options);
60238
60239    // The hook can opt-out of cleanup if it handled cleanup itself.
60240    if (result && result.handled) {
60241      return;
60242    }
60243
60244    var morphMap = morph.morphMap;
60245
60246    // Walk the morph list, clearing any items that were yielded in a previous
60247    // render but were not yielded during this render.
60248    var morphList = renderState.morphListToPrune;
60249    if (morphList) {
60250      var handledMorphs = renderState.handledMorphs;
60251      var item = morphList.firstChildMorph;
60252
60253      while (item) {
60254        var next = item.nextMorph;
60255
60256        // If we don't see the key in handledMorphs, it wasn't
60257        // yielded in and we can safely remove it from DOM.
60258        if (!(item.key in handledMorphs)) {
60259          morphMap[item.key] = undefined;
60260          clearMorph(item, env, true);
60261          item.destroy();
60262        }
60263
60264        item = next;
60265      }
60266    }
60267
60268    morphList = renderState.morphListToClear;
60269    if (morphList) {
60270      clearMorphList(morphList, morph, env);
60271    }
60272
60273    var toClear = renderState.morphToClear;
60274    if (toClear) {
60275      clearMorph(toClear, env);
60276    }
60277  }
60278
60279  function clearMorph(morph, env, destroySelf) {
60280    var cleanup = env.hooks.cleanupRenderNode;
60281    var destroy = env.hooks.destroyRenderNode;
60282    var willCleanup = env.hooks.willCleanupTree;
60283    var didCleanup = env.hooks.didCleanupTree;
60284
60285    function destroyNode(node) {
60286      if (cleanup) {
60287        cleanup(node);
60288      }
60289      if (destroy) {
60290        destroy(node);
60291      }
60292    }
60293
60294    if (willCleanup) {
60295      willCleanup(env, morph, destroySelf);
60296    }
60297    if (cleanup) {
60298      cleanup(morph);
60299    }
60300    if (destroySelf && destroy) {
60301      destroy(morph);
60302    }
60303
60304    _htmlbarsUtilMorphUtils.visitChildren(morph.childNodes, destroyNode);
60305
60306    // TODO: Deal with logical children that are not in the DOM tree
60307    morph.clear();
60308    if (didCleanup) {
60309      didCleanup(env, morph, destroySelf);
60310    }
60311
60312    morph.lastResult = null;
60313    morph.lastYielded = null;
60314    morph.childNodes = null;
60315  }
60316
60317  function clearMorphList(morphList, morph, env) {
60318    var item = morphList.firstChildMorph;
60319
60320    while (item) {
60321      var next = item.nextMorph;
60322      morph.morphMap[item.key] = undefined;
60323      clearMorph(item, env, true);
60324      item.destroy();
60325
60326      item = next;
60327    }
60328
60329    // Remove the MorphList from the morph.
60330    morphList.clear();
60331    morph.morphList = null;
60332  }
60333});
60334enifed("htmlbars-util/void-tag-names", ["exports", "htmlbars-util/array-utils"], function (exports, _htmlbarsUtilArrayUtils) {
60335  "use strict";
60336
60337  // The HTML elements in this list are speced by
60338  // http://www.w3.org/TR/html-markup/syntax.html#syntax-elements,
60339  // and will be forced to close regardless of if they have a
60340  // self-closing /> at the end.
60341  var voidTagNames = "area base br col command embed hr img input keygen link meta param source track wbr";
60342  var voidMap = {};
60343
60344  _htmlbarsUtilArrayUtils.forEach(voidTagNames.split(" "), function (tagName) {
60345    voidMap[tagName] = true;
60346  });
60347
60348  exports.default = voidMap;
60349});
60350enifed('htmlbars-util', ['exports', 'htmlbars-util/safe-string', 'htmlbars-util/handlebars/utils', 'htmlbars-util/namespaces', 'htmlbars-util/morph-utils'], function (exports, _htmlbarsUtilSafeString, _htmlbarsUtilHandlebarsUtils, _htmlbarsUtilNamespaces, _htmlbarsUtilMorphUtils) {
60351  'use strict';
60352
60353  exports.SafeString = _htmlbarsUtilSafeString.default;
60354  exports.escapeExpression = _htmlbarsUtilHandlebarsUtils.escapeExpression;
60355  exports.getAttrNamespace = _htmlbarsUtilNamespaces.getAttrNamespace;
60356  exports.validateChildMorphs = _htmlbarsUtilMorphUtils.validateChildMorphs;
60357  exports.linkParams = _htmlbarsUtilMorphUtils.linkParams;
60358  exports.dump = _htmlbarsUtilMorphUtils.dump;
60359});
60360enifed('morph-attr/sanitize-attribute-value', ['exports'], function (exports) {
60361  /* jshint scripturl:true */
60362
60363  'use strict';
60364
60365  exports.sanitizeAttributeValue = sanitizeAttributeValue;
60366  var badProtocols = {
60367    'javascript:': true,
60368    'vbscript:': true
60369  };
60370
60371  var badTags = {
60372    'A': true,
60373    'BODY': true,
60374    'LINK': true,
60375    'IMG': true,
60376    'IFRAME': true,
60377    'BASE': true,
60378    'FORM': true
60379  };
60380
60381  var badTagsForDataURI = {
60382    'EMBED': true
60383  };
60384
60385  var badAttributes = {
60386    'href': true,
60387    'src': true,
60388    'background': true,
60389    'action': true
60390  };
60391
60392  exports.badAttributes = badAttributes;
60393  var badAttributesForDataURI = {
60394    'src': true
60395  };
60396
60397  function sanitizeAttributeValue(dom, element, attribute, value) {
60398    var tagName;
60399
60400    if (!element) {
60401      tagName = null;
60402    } else {
60403      tagName = element.tagName.toUpperCase();
60404    }
60405
60406    if (value && value.toHTML) {
60407      return value.toHTML();
60408    }
60409
60410    if ((tagName === null || badTags[tagName]) && badAttributes[attribute]) {
60411      var protocol = dom.protocolForURL(value);
60412      if (badProtocols[protocol] === true) {
60413        return 'unsafe:' + value;
60414      }
60415    }
60416
60417    if (badTagsForDataURI[tagName] && badAttributesForDataURI[attribute]) {
60418      return 'unsafe:' + value;
60419    }
60420
60421    return value;
60422  }
60423});
60424enifed("morph-attr", ["exports", "morph-attr/sanitize-attribute-value", "dom-helper/prop", "dom-helper/build-html-dom", "htmlbars-util"], function (exports, _morphAttrSanitizeAttributeValue, _domHelperProp, _domHelperBuildHtmlDom, _htmlbarsUtil) {
60425  "use strict";
60426
60427  function getProperty() {
60428    return this.domHelper.getPropertyStrict(this.element, this.attrName);
60429  }
60430
60431  function updateProperty(value) {
60432    if (this._renderedInitially === true || !_domHelperProp.isAttrRemovalValue(value)) {
60433      var element = this.element;
60434      var attrName = this.attrName;
60435
60436      if (attrName === 'value' && element.tagName === 'INPUT' && element.value === value) {
60437        // Do nothing. Attempts to avoid accidently changing the input cursor location.
60438        // See https://github.com/tildeio/htmlbars/pull/447 for more details.
60439      } else {
60440          // do not render if initial value is undefined or null
60441          this.domHelper.setPropertyStrict(element, attrName, value);
60442        }
60443    }
60444
60445    this._renderedInitially = true;
60446  }
60447
60448  function getAttribute() {
60449    return this.domHelper.getAttribute(this.element, this.attrName);
60450  }
60451
60452  function updateAttribute(value) {
60453    if (_domHelperProp.isAttrRemovalValue(value)) {
60454      this.domHelper.removeAttribute(this.element, this.attrName);
60455    } else {
60456      this.domHelper.setAttribute(this.element, this.attrName, value);
60457    }
60458  }
60459
60460  function getAttributeNS() {
60461    return this.domHelper.getAttributeNS(this.element, this.namespace, this.attrName);
60462  }
60463
60464  function updateAttributeNS(value) {
60465    if (_domHelperProp.isAttrRemovalValue(value)) {
60466      this.domHelper.removeAttribute(this.element, this.attrName);
60467    } else {
60468      this.domHelper.setAttributeNS(this.element, this.namespace, this.attrName, value);
60469    }
60470  }
60471
60472  var UNSET = { unset: true };
60473
60474  var guid = 1;
60475
60476  AttrMorph.create = function (element, attrName, domHelper, namespace) {
60477    var ns = _htmlbarsUtil.getAttrNamespace(attrName, namespace);
60478
60479    if (ns) {
60480      return new AttributeNSAttrMorph(element, attrName, domHelper, ns);
60481    } else {
60482      return createNonNamespacedAttrMorph(element, attrName, domHelper);
60483    }
60484  };
60485
60486  function createNonNamespacedAttrMorph(element, attrName, domHelper) {
60487    var _normalizeProperty = _domHelperProp.normalizeProperty(element, attrName);
60488
60489    var normalized = _normalizeProperty.normalized;
60490    var type = _normalizeProperty.type;
60491
60492    if (element.namespaceURI === _domHelperBuildHtmlDom.svgNamespace || attrName === 'style' || type === 'attr') {
60493      return new AttributeAttrMorph(element, normalized, domHelper);
60494    } else {
60495      return new PropertyAttrMorph(element, normalized, domHelper);
60496    }
60497  }
60498
60499  function AttrMorph(element, attrName, domHelper) {
60500    this.element = element;
60501    this.domHelper = domHelper;
60502    this.attrName = attrName;
60503    this._state = undefined;
60504    this.isDirty = false;
60505    this.isSubtreeDirty = false;
60506    this.escaped = true;
60507    this.lastValue = UNSET;
60508    this.lastResult = null;
60509    this.lastYielded = null;
60510    this.childNodes = null;
60511    this.linkedParams = null;
60512    this.linkedResult = null;
60513    this.guid = "attr" + guid++;
60514    this.seen = false;
60515    this.ownerNode = null;
60516    this.rendered = false;
60517    this._renderedInitially = false;
60518    this.namespace = undefined;
60519    this.didInit();
60520  }
60521
60522  AttrMorph.prototype.getState = function () {
60523    if (!this._state) {
60524      this._state = {};
60525    }
60526
60527    return this._state;
60528  };
60529
60530  AttrMorph.prototype.setState = function (newState) {
60531    /*jshint -W093 */
60532
60533    return this._state = newState;
60534  };
60535
60536  AttrMorph.prototype.didInit = function () {};
60537  AttrMorph.prototype.willSetContent = function () {};
60538
60539  AttrMorph.prototype.setContent = function (value) {
60540    this.willSetContent(value);
60541
60542    if (this.lastValue === value) {
60543      return;
60544    }
60545    this.lastValue = value;
60546
60547    if (this.escaped) {
60548      var sanitized = _morphAttrSanitizeAttributeValue.sanitizeAttributeValue(this.domHelper, this.element, this.attrName, value);
60549      this._update(sanitized, this.namespace);
60550    } else {
60551      this._update(value, this.namespace);
60552    }
60553  };
60554
60555  AttrMorph.prototype.getContent = function () {
60556    var value = this.lastValue = this._get();
60557    return value;
60558  };
60559
60560  // renderAndCleanup calls `clear` on all items in the morph map
60561  // just before calling `destroy` on the morph.
60562  //
60563  // As a future refactor this could be changed to set the property
60564  // back to its original/default value.
60565  AttrMorph.prototype.clear = function () {};
60566
60567  AttrMorph.prototype.destroy = function () {
60568    this.element = null;
60569    this.domHelper = null;
60570  };
60571
60572  AttrMorph.prototype._$superAttrMorph = AttrMorph;
60573
60574  function PropertyAttrMorph(element, attrName, domHelper) {
60575    this._$superAttrMorph(element, attrName, domHelper);
60576  }
60577
60578  PropertyAttrMorph.prototype = Object.create(AttrMorph.prototype);
60579  PropertyAttrMorph.prototype._update = updateProperty;
60580  PropertyAttrMorph.prototype._get = getProperty;
60581
60582  function AttributeNSAttrMorph(element, attrName, domHelper, namespace) {
60583    this._$superAttrMorph(element, attrName, domHelper);
60584    this.namespace = namespace;
60585  }
60586
60587  AttributeNSAttrMorph.prototype = Object.create(AttrMorph.prototype);
60588  AttributeNSAttrMorph.prototype._update = updateAttributeNS;
60589  AttributeNSAttrMorph.prototype._get = getAttributeNS;
60590
60591  function AttributeAttrMorph(element, attrName, domHelper) {
60592    this._$superAttrMorph(element, attrName, domHelper);
60593  }
60594
60595  AttributeAttrMorph.prototype = Object.create(AttrMorph.prototype);
60596  AttributeAttrMorph.prototype._update = updateAttribute;
60597  AttributeAttrMorph.prototype._get = getAttribute;
60598
60599  exports.default = AttrMorph;
60600  exports.sanitizeAttributeValue = _morphAttrSanitizeAttributeValue.sanitizeAttributeValue;
60601});
60602enifed('morph-range/morph-list', ['exports', 'morph-range/utils'], function (exports, _morphRangeUtils) {
60603  'use strict';
60604
60605  function MorphList() {
60606    // morph graph
60607    this.firstChildMorph = null;
60608    this.lastChildMorph = null;
60609
60610    this.mountedMorph = null;
60611  }
60612
60613  var prototype = MorphList.prototype;
60614
60615  prototype.clear = function MorphList$clear() {
60616    var current = this.firstChildMorph;
60617
60618    while (current) {
60619      var next = current.nextMorph;
60620      current.previousMorph = null;
60621      current.nextMorph = null;
60622      current.parentMorphList = null;
60623      current = next;
60624    }
60625
60626    this.firstChildMorph = this.lastChildMorph = null;
60627  };
60628
60629  prototype.destroy = function MorphList$destroy() {};
60630
60631  prototype.appendMorph = function MorphList$appendMorph(morph) {
60632    this.insertBeforeMorph(morph, null);
60633  };
60634
60635  prototype.insertBeforeMorph = function MorphList$insertBeforeMorph(morph, referenceMorph) {
60636    if (morph.parentMorphList !== null) {
60637      morph.unlink();
60638    }
60639    if (referenceMorph && referenceMorph.parentMorphList !== this) {
60640      throw new Error('The morph before which the new morph is to be inserted is not a child of this morph.');
60641    }
60642
60643    var mountedMorph = this.mountedMorph;
60644
60645    if (mountedMorph) {
60646
60647      var parentNode = mountedMorph.firstNode.parentNode;
60648      var referenceNode = referenceMorph ? referenceMorph.firstNode : mountedMorph.lastNode.nextSibling;
60649
60650      _morphRangeUtils.insertBefore(parentNode, morph.firstNode, morph.lastNode, referenceNode);
60651
60652      // was not in list mode replace current content
60653      if (!this.firstChildMorph) {
60654        _morphRangeUtils.clear(this.mountedMorph.firstNode.parentNode, this.mountedMorph.firstNode, this.mountedMorph.lastNode);
60655      }
60656    }
60657
60658    morph.parentMorphList = this;
60659
60660    var previousMorph = referenceMorph ? referenceMorph.previousMorph : this.lastChildMorph;
60661    if (previousMorph) {
60662      previousMorph.nextMorph = morph;
60663      morph.previousMorph = previousMorph;
60664    } else {
60665      this.firstChildMorph = morph;
60666    }
60667
60668    if (referenceMorph) {
60669      referenceMorph.previousMorph = morph;
60670      morph.nextMorph = referenceMorph;
60671    } else {
60672      this.lastChildMorph = morph;
60673    }
60674
60675    this.firstChildMorph._syncFirstNode();
60676    this.lastChildMorph._syncLastNode();
60677  };
60678
60679  prototype.removeChildMorph = function MorphList$removeChildMorph(morph) {
60680    if (morph.parentMorphList !== this) {
60681      throw new Error("Cannot remove a morph from a parent it is not inside of");
60682    }
60683
60684    morph.destroy();
60685  };
60686
60687  exports.default = MorphList;
60688});
60689enifed('morph-range/morph-list.umd', ['exports', 'morph-range/morph-list'], function (exports, _morphRangeMorphList) {
60690  'use strict';
60691
60692  (function (root, factory) {
60693    if (typeof define === 'function' && define.amd) {
60694      define([], factory);
60695    } else if (typeof exports === 'object') {
60696      module.exports = factory();
60697    } else {
60698      root.MorphList = factory();
60699    }
60700  })(undefined, function () {
60701    return _morphRangeMorphList.default;
60702  });
60703});
60704enifed("morph-range/utils", ["exports"], function (exports) {
60705  // inclusive of both nodes
60706  "use strict";
60707
60708  exports.clear = clear;
60709  exports.insertBefore = insertBefore;
60710
60711  function clear(parentNode, firstNode, lastNode) {
60712    if (!parentNode) {
60713      return;
60714    }
60715
60716    var node = firstNode;
60717    var nextNode;
60718    do {
60719      nextNode = node.nextSibling;
60720      parentNode.removeChild(node);
60721      if (node === lastNode) {
60722        break;
60723      }
60724      node = nextNode;
60725    } while (node);
60726  }
60727
60728  function insertBefore(parentNode, firstNode, lastNode, refNode) {
60729    var node = firstNode;
60730    var nextNode;
60731    do {
60732      nextNode = node.nextSibling;
60733      parentNode.insertBefore(node, refNode);
60734      if (node === lastNode) {
60735        break;
60736      }
60737      node = nextNode;
60738    } while (node);
60739  }
60740});
60741enifed('morph-range', ['exports', 'morph-range/utils'], function (exports, _morphRangeUtils) {
60742  'use strict';
60743
60744  // constructor just initializes the fields
60745  // use one of the static initializers to create a valid morph.
60746  function Morph(domHelper, contextualElement) {
60747    this.domHelper = domHelper;
60748    // context if content if current content is detached
60749    this.contextualElement = contextualElement;
60750    // inclusive range of morph
60751    // these should be nodeType 1, 3, or 8
60752    this.firstNode = null;
60753    this.lastNode = null;
60754
60755    // flag to force text to setContent to be treated as html
60756    this.parseTextAsHTML = false;
60757
60758    // morph list graph
60759    this.parentMorphList = null;
60760    this.previousMorph = null;
60761    this.nextMorph = null;
60762  }
60763
60764  Morph.empty = function (domHelper, contextualElement) {
60765    var morph = new Morph(domHelper, contextualElement);
60766    morph.clear();
60767    return morph;
60768  };
60769
60770  Morph.create = function (domHelper, contextualElement, node) {
60771    var morph = new Morph(domHelper, contextualElement);
60772    morph.setNode(node);
60773    return morph;
60774  };
60775
60776  Morph.attach = function (domHelper, contextualElement, firstNode, lastNode) {
60777    var morph = new Morph(domHelper, contextualElement);
60778    morph.setRange(firstNode, lastNode);
60779    return morph;
60780  };
60781
60782  Morph.prototype.setContent = function Morph$setContent(content) {
60783    if (content === null || content === undefined) {
60784      return this.clear();
60785    }
60786
60787    var type = typeof content;
60788    switch (type) {
60789      case 'string':
60790        if (this.parseTextAsHTML) {
60791          return this.domHelper.setMorphHTML(this, content);
60792        }
60793        return this.setText(content);
60794      case 'object':
60795        if (typeof content.nodeType === 'number') {
60796          return this.setNode(content);
60797        }
60798        /* Handlebars.SafeString */
60799        if (typeof content.toHTML === 'function') {
60800          return this.setHTML(content.toHTML());
60801        }
60802        if (this.parseTextAsHTML) {
60803          return this.setHTML(content.toString());
60804        }
60805      /* falls through */
60806      case 'boolean':
60807      case 'number':
60808        return this.setText(content.toString());
60809      case 'function':
60810        raiseCannotBindToFunction(content);
60811      default:
60812        throw new TypeError('unsupported content');
60813    }
60814  };
60815
60816  function raiseCannotBindToFunction(content) {
60817    var functionName = content.name;
60818    var message;
60819
60820    if (functionName) {
60821      message = 'Unsupported Content: Cannot bind to function `' + functionName + '`';
60822    } else {
60823      message = 'Unsupported Content: Cannot bind to function';
60824    }
60825
60826    throw new TypeError(message);
60827  }
60828
60829  Morph.prototype.clear = function Morph$clear() {
60830    var node = this.setNode(this.domHelper.createComment(''));
60831    return node;
60832  };
60833
60834  Morph.prototype.setText = function Morph$setText(text) {
60835    var firstNode = this.firstNode;
60836    var lastNode = this.lastNode;
60837
60838    if (firstNode && lastNode === firstNode && firstNode.nodeType === 3) {
60839      firstNode.nodeValue = text;
60840      return firstNode;
60841    }
60842
60843    return this.setNode(text ? this.domHelper.createTextNode(text) : this.domHelper.createComment(''));
60844  };
60845
60846  Morph.prototype.setNode = function Morph$setNode(newNode) {
60847    var firstNode, lastNode;
60848    switch (newNode.nodeType) {
60849      case 3:
60850        firstNode = newNode;
60851        lastNode = newNode;
60852        break;
60853      case 11:
60854        firstNode = newNode.firstChild;
60855        lastNode = newNode.lastChild;
60856        if (firstNode === null) {
60857          firstNode = this.domHelper.createComment('');
60858          newNode.appendChild(firstNode);
60859          lastNode = firstNode;
60860        }
60861        break;
60862      default:
60863        firstNode = newNode;
60864        lastNode = newNode;
60865        break;
60866    }
60867
60868    this.setRange(firstNode, lastNode);
60869
60870    return newNode;
60871  };
60872
60873  Morph.prototype.setRange = function (firstNode, lastNode) {
60874    var previousFirstNode = this.firstNode;
60875    if (previousFirstNode !== null) {
60876
60877      var parentNode = previousFirstNode.parentNode;
60878      if (parentNode !== null) {
60879        _morphRangeUtils.insertBefore(parentNode, firstNode, lastNode, previousFirstNode);
60880        _morphRangeUtils.clear(parentNode, previousFirstNode, this.lastNode);
60881      }
60882    }
60883
60884    this.firstNode = firstNode;
60885    this.lastNode = lastNode;
60886
60887    if (this.parentMorphList) {
60888      this._syncFirstNode();
60889      this._syncLastNode();
60890    }
60891  };
60892
60893  Morph.prototype.destroy = function Morph$destroy() {
60894    this.unlink();
60895
60896    var firstNode = this.firstNode;
60897    var lastNode = this.lastNode;
60898    var parentNode = firstNode && firstNode.parentNode;
60899
60900    this.firstNode = null;
60901    this.lastNode = null;
60902
60903    _morphRangeUtils.clear(parentNode, firstNode, lastNode);
60904  };
60905
60906  Morph.prototype.unlink = function Morph$unlink() {
60907    var parentMorphList = this.parentMorphList;
60908    var previousMorph = this.previousMorph;
60909    var nextMorph = this.nextMorph;
60910
60911    if (previousMorph) {
60912      if (nextMorph) {
60913        previousMorph.nextMorph = nextMorph;
60914        nextMorph.previousMorph = previousMorph;
60915      } else {
60916        previousMorph.nextMorph = null;
60917        parentMorphList.lastChildMorph = previousMorph;
60918      }
60919    } else {
60920      if (nextMorph) {
60921        nextMorph.previousMorph = null;
60922        parentMorphList.firstChildMorph = nextMorph;
60923      } else if (parentMorphList) {
60924        parentMorphList.lastChildMorph = parentMorphList.firstChildMorph = null;
60925      }
60926    }
60927
60928    this.parentMorphList = null;
60929    this.nextMorph = null;
60930    this.previousMorph = null;
60931
60932    if (parentMorphList && parentMorphList.mountedMorph) {
60933      if (!parentMorphList.firstChildMorph) {
60934        // list is empty
60935        parentMorphList.mountedMorph.clear();
60936        return;
60937      } else {
60938        parentMorphList.firstChildMorph._syncFirstNode();
60939        parentMorphList.lastChildMorph._syncLastNode();
60940      }
60941    }
60942  };
60943
60944  Morph.prototype.setHTML = function (text) {
60945    var fragment = this.domHelper.parseHTML(text, this.contextualElement);
60946    return this.setNode(fragment);
60947  };
60948
60949  Morph.prototype.setMorphList = function Morph$appendMorphList(morphList) {
60950    morphList.mountedMorph = this;
60951    this.clear();
60952
60953    var originalFirstNode = this.firstNode;
60954
60955    if (morphList.firstChildMorph) {
60956      this.firstNode = morphList.firstChildMorph.firstNode;
60957      this.lastNode = morphList.lastChildMorph.lastNode;
60958
60959      var current = morphList.firstChildMorph;
60960
60961      while (current) {
60962        var next = current.nextMorph;
60963        current.insertBeforeNode(originalFirstNode, null);
60964        current = next;
60965      }
60966      originalFirstNode.parentNode.removeChild(originalFirstNode);
60967    }
60968  };
60969
60970  Morph.prototype._syncFirstNode = function Morph$syncFirstNode() {
60971    var morph = this;
60972    var parentMorphList;
60973    while (parentMorphList = morph.parentMorphList) {
60974      if (parentMorphList.mountedMorph === null) {
60975        break;
60976      }
60977      if (morph !== parentMorphList.firstChildMorph) {
60978        break;
60979      }
60980      if (morph.firstNode === parentMorphList.mountedMorph.firstNode) {
60981        break;
60982      }
60983
60984      parentMorphList.mountedMorph.firstNode = morph.firstNode;
60985
60986      morph = parentMorphList.mountedMorph;
60987    }
60988  };
60989
60990  Morph.prototype._syncLastNode = function Morph$syncLastNode() {
60991    var morph = this;
60992    var parentMorphList;
60993    while (parentMorphList = morph.parentMorphList) {
60994      if (parentMorphList.mountedMorph === null) {
60995        break;
60996      }
60997      if (morph !== parentMorphList.lastChildMorph) {
60998        break;
60999      }
61000      if (morph.lastNode === parentMorphList.mountedMorph.lastNode) {
61001        break;
61002      }
61003
61004      parentMorphList.mountedMorph.lastNode = morph.lastNode;
61005
61006      morph = parentMorphList.mountedMorph;
61007    }
61008  };
61009
61010  Morph.prototype.insertBeforeNode = function Morph$insertBeforeNode(parentNode, refNode) {
61011    _morphRangeUtils.insertBefore(parentNode, this.firstNode, this.lastNode, refNode);
61012  };
61013
61014  Morph.prototype.appendToNode = function Morph$appendToNode(parentNode) {
61015    _morphRangeUtils.insertBefore(parentNode, this.firstNode, this.lastNode, null);
61016  };
61017
61018  exports.default = Morph;
61019});
61020enifed("route-recognizer/dsl", ["exports"], function (exports) {
61021  "use strict";
61022
61023  function Target(path, matcher, delegate) {
61024    this.path = path;
61025    this.matcher = matcher;
61026    this.delegate = delegate;
61027  }
61028
61029  Target.prototype = {
61030    to: function (target, callback) {
61031      var delegate = this.delegate;
61032
61033      if (delegate && delegate.willAddRoute) {
61034        target = delegate.willAddRoute(this.matcher.target, target);
61035      }
61036
61037      this.matcher.add(this.path, target);
61038
61039      if (callback) {
61040        if (callback.length === 0) {
61041          throw new Error("You must have an argument in the function passed to `to`");
61042        }
61043        this.matcher.addChild(this.path, target, callback, this.delegate);
61044      }
61045      return this;
61046    }
61047  };
61048
61049  function Matcher(target) {
61050    this.routes = {};
61051    this.children = {};
61052    this.target = target;
61053  }
61054
61055  Matcher.prototype = {
61056    add: function (path, handler) {
61057      this.routes[path] = handler;
61058    },
61059
61060    addChild: function (path, target, callback, delegate) {
61061      var matcher = new Matcher(target);
61062      this.children[path] = matcher;
61063
61064      var match = generateMatch(path, matcher, delegate);
61065
61066      if (delegate && delegate.contextEntered) {
61067        delegate.contextEntered(target, match);
61068      }
61069
61070      callback(match);
61071    }
61072  };
61073
61074  function generateMatch(startingPath, matcher, delegate) {
61075    return function (path, nestedCallback) {
61076      var fullPath = startingPath + path;
61077
61078      if (nestedCallback) {
61079        nestedCallback(generateMatch(fullPath, matcher, delegate));
61080      } else {
61081        return new Target(startingPath + path, matcher, delegate);
61082      }
61083    };
61084  }
61085
61086  function addRoute(routeArray, path, handler) {
61087    var len = 0;
61088    for (var i = 0, l = routeArray.length; i < l; i++) {
61089      len += routeArray[i].path.length;
61090    }
61091
61092    path = path.substr(len);
61093    var route = { path: path, handler: handler };
61094    routeArray.push(route);
61095  }
61096
61097  function eachRoute(baseRoute, matcher, callback, binding) {
61098    var routes = matcher.routes;
61099
61100    for (var path in routes) {
61101      if (routes.hasOwnProperty(path)) {
61102        var routeArray = baseRoute.slice();
61103        addRoute(routeArray, path, routes[path]);
61104
61105        if (matcher.children[path]) {
61106          eachRoute(routeArray, matcher.children[path], callback, binding);
61107        } else {
61108          callback.call(binding, routeArray);
61109        }
61110      }
61111    }
61112  }
61113
61114  exports.default = function (callback, addRouteCallback) {
61115    var matcher = new Matcher();
61116
61117    callback(generateMatch("", matcher, this.delegate));
61118
61119    eachRoute([], matcher, function (route) {
61120      if (addRouteCallback) {
61121        addRouteCallback(this, route);
61122      } else {
61123        this.add(route);
61124      }
61125    }, this);
61126  };
61127});
61128enifed('route-recognizer', ['exports', 'route-recognizer/dsl'], function (exports, _routeRecognizerDsl) {
61129  'use strict';
61130
61131  var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
61132
61133  var escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
61134
61135  function isArray(test) {
61136    return Object.prototype.toString.call(test) === "[object Array]";
61137  }
61138
61139  // A Segment represents a segment in the original route description.
61140  // Each Segment type provides an `eachChar` and `regex` method.
61141  //
61142  // The `eachChar` method invokes the callback with one or more character
61143  // specifications. A character specification consumes one or more input
61144  // characters.
61145  //
61146  // The `regex` method returns a regex fragment for the segment. If the
61147  // segment is a dynamic of star segment, the regex fragment also includes
61148  // a capture.
61149  //
61150  // A character specification contains:
61151  //
61152  // * `validChars`: a String with a list of all valid characters, or
61153  // * `invalidChars`: a String with a list of all invalid characters
61154  // * `repeat`: true if the character specification can repeat
61155
61156  function StaticSegment(string) {
61157    this.string = string;
61158  }
61159  StaticSegment.prototype = {
61160    eachChar: function (callback) {
61161      var string = this.string,
61162          ch;
61163
61164      for (var i = 0, l = string.length; i < l; i++) {
61165        ch = string.charAt(i);
61166        callback({ validChars: ch });
61167      }
61168    },
61169
61170    regex: function () {
61171      return this.string.replace(escapeRegex, '\\$1');
61172    },
61173
61174    generate: function () {
61175      return this.string;
61176    }
61177  };
61178
61179  function DynamicSegment(name) {
61180    this.name = name;
61181  }
61182  DynamicSegment.prototype = {
61183    eachChar: function (callback) {
61184      callback({ invalidChars: "/", repeat: true });
61185    },
61186
61187    regex: function () {
61188      return "([^/]+)";
61189    },
61190
61191    generate: function (params) {
61192      return params[this.name];
61193    }
61194  };
61195
61196  function StarSegment(name) {
61197    this.name = name;
61198  }
61199  StarSegment.prototype = {
61200    eachChar: function (callback) {
61201      callback({ invalidChars: "", repeat: true });
61202    },
61203
61204    regex: function () {
61205      return "(.+)";
61206    },
61207
61208    generate: function (params) {
61209      return params[this.name];
61210    }
61211  };
61212
61213  function EpsilonSegment() {}
61214  EpsilonSegment.prototype = {
61215    eachChar: function () {},
61216    regex: function () {
61217      return "";
61218    },
61219    generate: function () {
61220      return "";
61221    }
61222  };
61223
61224  function parse(route, names, types) {
61225    // normalize route as not starting with a "/". Recognition will
61226    // also normalize.
61227    if (route.charAt(0) === "/") {
61228      route = route.substr(1);
61229    }
61230
61231    var segments = route.split("/"),
61232        results = [];
61233
61234    for (var i = 0, l = segments.length; i < l; i++) {
61235      var segment = segments[i],
61236          match;
61237
61238      if (match = segment.match(/^:([^\/]+)$/)) {
61239        results.push(new DynamicSegment(match[1]));
61240        names.push(match[1]);
61241        types.dynamics++;
61242      } else if (match = segment.match(/^\*([^\/]+)$/)) {
61243        results.push(new StarSegment(match[1]));
61244        names.push(match[1]);
61245        types.stars++;
61246      } else if (segment === "") {
61247        results.push(new EpsilonSegment());
61248      } else {
61249        results.push(new StaticSegment(segment));
61250        types.statics++;
61251      }
61252    }
61253
61254    return results;
61255  }
61256
61257  // A State has a character specification and (`charSpec`) and a list of possible
61258  // subsequent states (`nextStates`).
61259  //
61260  // If a State is an accepting state, it will also have several additional
61261  // properties:
61262  //
61263  // * `regex`: A regular expression that is used to extract parameters from paths
61264  //   that reached this accepting state.
61265  // * `handlers`: Information on how to convert the list of captures into calls
61266  //   to registered handlers with the specified parameters
61267  // * `types`: How many static, dynamic or star segments in this route. Used to
61268  //   decide which route to use if multiple registered routes match a path.
61269  //
61270  // Currently, State is implemented naively by looping over `nextStates` and
61271  // comparing a character specification against a character. A more efficient
61272  // implementation would use a hash of keys pointing at one or more next states.
61273
61274  function State(charSpec) {
61275    this.charSpec = charSpec;
61276    this.nextStates = [];
61277  }
61278
61279  State.prototype = {
61280    get: function (charSpec) {
61281      var nextStates = this.nextStates;
61282
61283      for (var i = 0, l = nextStates.length; i < l; i++) {
61284        var child = nextStates[i];
61285
61286        var isEqual = child.charSpec.validChars === charSpec.validChars;
61287        isEqual = isEqual && child.charSpec.invalidChars === charSpec.invalidChars;
61288
61289        if (isEqual) {
61290          return child;
61291        }
61292      }
61293    },
61294
61295    put: function (charSpec) {
61296      var state;
61297
61298      // If the character specification already exists in a child of the current
61299      // state, just return that state.
61300      if (state = this.get(charSpec)) {
61301        return state;
61302      }
61303
61304      // Make a new state for the character spec
61305      state = new State(charSpec);
61306
61307      // Insert the new state as a child of the current state
61308      this.nextStates.push(state);
61309
61310      // If this character specification repeats, insert the new state as a child
61311      // of itself. Note that this will not trigger an infinite loop because each
61312      // transition during recognition consumes a character.
61313      if (charSpec.repeat) {
61314        state.nextStates.push(state);
61315      }
61316
61317      // Return the new state
61318      return state;
61319    },
61320
61321    // Find a list of child states matching the next character
61322    match: function (ch) {
61323      // DEBUG "Processing `" + ch + "`:"
61324      var nextStates = this.nextStates,
61325          child,
61326          charSpec,
61327          chars;
61328
61329      // DEBUG "  " + debugState(this)
61330      var returned = [];
61331
61332      for (var i = 0, l = nextStates.length; i < l; i++) {
61333        child = nextStates[i];
61334
61335        charSpec = child.charSpec;
61336
61337        if (typeof (chars = charSpec.validChars) !== 'undefined') {
61338          if (chars.indexOf(ch) !== -1) {
61339            returned.push(child);
61340          }
61341        } else if (typeof (chars = charSpec.invalidChars) !== 'undefined') {
61342          if (chars.indexOf(ch) === -1) {
61343            returned.push(child);
61344          }
61345        }
61346      }
61347
61348      return returned;
61349    }
61350
61351    /** IF DEBUG
61352    , debug: function() {
61353      var charSpec = this.charSpec,
61354          debug = "[",
61355          chars = charSpec.validChars || charSpec.invalidChars;
61356       if (charSpec.invalidChars) { debug += "^"; }
61357      debug += chars;
61358      debug += "]";
61359       if (charSpec.repeat) { debug += "+"; }
61360       return debug;
61361    }
61362    END IF **/
61363  };
61364
61365  /** IF DEBUG
61366  function debug(log) {
61367    console.log(log);
61368  }
61369  
61370  function debugState(state) {
61371    return state.nextStates.map(function(n) {
61372      if (n.nextStates.length === 0) { return "( " + n.debug() + " [accepting] )"; }
61373      return "( " + n.debug() + " <then> " + n.nextStates.map(function(s) { return s.debug() }).join(" or ") + " )";
61374    }).join(", ")
61375  }
61376  END IF **/
61377
61378  // This is a somewhat naive strategy, but should work in a lot of cases
61379  // A better strategy would properly resolve /posts/:id/new and /posts/edit/:id.
61380  //
61381  // This strategy generally prefers more static and less dynamic matching.
61382  // Specifically, it
61383  //
61384  //  * prefers fewer stars to more, then
61385  //  * prefers using stars for less of the match to more, then
61386  //  * prefers fewer dynamic segments to more, then
61387  //  * prefers more static segments to more
61388  function sortSolutions(states) {
61389    return states.sort(function (a, b) {
61390      if (a.types.stars !== b.types.stars) {
61391        return a.types.stars - b.types.stars;
61392      }
61393
61394      if (a.types.stars) {
61395        if (a.types.statics !== b.types.statics) {
61396          return b.types.statics - a.types.statics;
61397        }
61398        if (a.types.dynamics !== b.types.dynamics) {
61399          return b.types.dynamics - a.types.dynamics;
61400        }
61401      }
61402
61403      if (a.types.dynamics !== b.types.dynamics) {
61404        return a.types.dynamics - b.types.dynamics;
61405      }
61406      if (a.types.statics !== b.types.statics) {
61407        return b.types.statics - a.types.statics;
61408      }
61409
61410      return 0;
61411    });
61412  }
61413
61414  function recognizeChar(states, ch) {
61415    var nextStates = [];
61416
61417    for (var i = 0, l = states.length; i < l; i++) {
61418      var state = states[i];
61419
61420      nextStates = nextStates.concat(state.match(ch));
61421    }
61422
61423    return nextStates;
61424  }
61425
61426  var oCreate = Object.create || function (proto) {
61427    function F() {}
61428    F.prototype = proto;
61429    return new F();
61430  };
61431
61432  function RecognizeResults(queryParams) {
61433    this.queryParams = queryParams || {};
61434  }
61435  RecognizeResults.prototype = oCreate({
61436    splice: Array.prototype.splice,
61437    slice: Array.prototype.slice,
61438    push: Array.prototype.push,
61439    length: 0,
61440    queryParams: null
61441  });
61442
61443  function findHandler(state, path, queryParams) {
61444    var handlers = state.handlers,
61445        regex = state.regex;
61446    var captures = path.match(regex),
61447        currentCapture = 1;
61448    var result = new RecognizeResults(queryParams);
61449
61450    for (var i = 0, l = handlers.length; i < l; i++) {
61451      var handler = handlers[i],
61452          names = handler.names,
61453          params = {};
61454
61455      for (var j = 0, m = names.length; j < m; j++) {
61456        params[names[j]] = captures[currentCapture++];
61457      }
61458
61459      result.push({ handler: handler.handler, params: params, isDynamic: !!names.length });
61460    }
61461
61462    return result;
61463  }
61464
61465  function addSegment(currentState, segment) {
61466    segment.eachChar(function (ch) {
61467      var state;
61468
61469      currentState = currentState.put(ch);
61470    });
61471
61472    return currentState;
61473  }
61474
61475  function decodeQueryParamPart(part) {
61476    // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
61477    part = part.replace(/\+/gm, '%20');
61478    return decodeURIComponent(part);
61479  }
61480
61481  // The main interface
61482
61483  var RouteRecognizer = function () {
61484    this.rootState = new State();
61485    this.names = {};
61486  };
61487
61488  RouteRecognizer.prototype = {
61489    add: function (routes, options) {
61490      var currentState = this.rootState,
61491          regex = "^",
61492          types = { statics: 0, dynamics: 0, stars: 0 },
61493          handlers = [],
61494          allSegments = [],
61495          name;
61496
61497      var isEmpty = true;
61498
61499      for (var i = 0, l = routes.length; i < l; i++) {
61500 
vendor: 4,272 bytes, lines 61500-61666
61500       var route = routes[i],
61501            names = [];
61502
61503        var segments = parse(route.path, names, types);
61504
61505        allSegments = allSegments.concat(segments);
61506
61507        for (var j = 0, m = segments.length; j < m; j++) {
61508          var segment = segments[j];
61509
61510          if (segment instanceof EpsilonSegment) {
61511            continue;
61512          }
61513
61514          isEmpty = false;
61515
61516          // Add a "/" for the new segment
61517          currentState = currentState.put({ validChars: "/" });
61518          regex += "/";
61519
61520          // Add a representation of the segment to the NFA and regex
61521          currentState = addSegment(currentState, segment);
61522          regex += segment.regex();
61523        }
61524
61525        var handler = { handler: route.handler, names: names };
61526        handlers.push(handler);
61527      }
61528
61529      if (isEmpty) {
61530        currentState = currentState.put({ validChars: "/" });
61531        regex += "/";
61532      }
61533
61534      currentState.handlers = handlers;
61535      currentState.regex = new RegExp(regex + "$");
61536      currentState.types = types;
61537
61538      if (name = options && options.as) {
61539        this.names[name] = {
61540          segments: allSegments,
61541          handlers: handlers
61542        };
61543      }
61544    },
61545
61546    handlersFor: function (name) {
61547      var route = this.names[name],
61548          result = [];
61549      if (!route) {
61550        throw new Error("There is no route named " + name);
61551      }
61552
61553      for (var i = 0, l = route.handlers.length; i < l; i++) {
61554        result.push(route.handlers[i]);
61555      }
61556
61557      return result;
61558    },
61559
61560    hasRoute: function (name) {
61561      return !!this.names[name];
61562    },
61563
61564    generate: function (name, params) {
61565      var route = this.names[name],
61566          output = "";
61567      if (!route) {
61568        throw new Error("There is no route named " + name);
61569      }
61570
61571      var segments = route.segments;
61572
61573      for (var i = 0, l = segments.length; i < l; i++) {
61574        var segment = segments[i];
61575
61576        if (segment instanceof EpsilonSegment) {
61577          continue;
61578        }
61579
61580        output += "/";
61581        output += segment.generate(params);
61582      }
61583
61584      if (output.charAt(0) !== '/') {
61585        output = '/' + output;
61586      }
61587
61588      if (params && params.queryParams) {
61589        output += this.generateQueryString(params.queryParams, route.handlers);
61590      }
61591
61592      return output;
61593    },
61594
61595    generateQueryString: function (params, handlers) {
61596      var pairs = [];
61597      var keys = [];
61598      for (var key in params) {
61599        if (params.hasOwnProperty(key)) {
61600          keys.push(key);
61601        }
61602      }
61603      keys.sort();
61604      for (var i = 0, len = keys.length; i < len; i++) {
61605        key = keys[i];
61606        var value = params[key];
61607        if (value == null) {
61608          continue;
61609        }
61610        var pair = encodeURIComponent(key);
61611        if (isArray(value)) {
61612          for (var j = 0, l = value.length; j < l; j++) {
61613            var arrayPair = key + '[]' + '=' + encodeURIComponent(value[j]);
61614            pairs.push(arrayPair);
61615          }
61616        } else {
61617          pair += "=" + encodeURIComponent(value);
61618          pairs.push(pair);
61619        }
61620      }
61621
61622      if (pairs.length === 0) {
61623        return '';
61624      }
61625
61626      return "?" + pairs.join("&");
61627    },
61628
61629    parseQueryString: function (queryString) {
61630      var pairs = queryString.split("&"),
61631          queryParams = {};
61632      for (var i = 0; i < pairs.length; i++) {
61633        var pair = pairs[i].split('='),
61634            key = decodeQueryParamPart(pair[0]),
61635            keyLength = key.length,
61636            isArray = false,
61637            value;
61638        if (pair.length === 1) {
61639          value = 'true';
61640        } else {
61641          //Handle arrays
61642          if (keyLength > 2 && key.slice(keyLength - 2) === '[]') {
61643            isArray = true;
61644            key = key.slice(0, keyLength - 2);
61645            if (!queryParams[key]) {
61646              queryParams[key] = [];
61647            }
61648          }
61649          value = pair[1] ? decodeQueryParamPart(pair[1]) : '';
61650        }
61651        if (isArray) {
61652          queryParams[key].push(value);
61653        } else {
61654          queryParams[key] = value;
61655        }
61656      }
61657      return queryParams;
61658    },
61659
61660    recognize: function (path) {
61661      var states = [this.rootState],
61662          pathLen,
61663          i,
61664          l,
61665          queryStart,
61666          queryParams = {},
61667          isSlashDropped = false;
61668
61669      queryStart = path.indexOf('?');
61670      if (queryStart !== -1) {
61671        var queryString = path.substr(queryStart + 1, path.length);
61672        path = path.substr(0, queryStart);
61673        queryParams = this.parseQueryString(queryString);
61674      }
61675
61676      path = decodeURI(path);
61677
61678      // DEBUG GROUP path
61679
61680      if (path.charAt(0) !== "/") {
61681        path = "/" + path;
61682      }
61683
61684      pathLen = path.length;
61685      if (pathLen > 1 && path.charAt(pathLen - 1) === "/") {
61686        path = path.substr(0, pathLen - 1);
61687        isSlashDropped = true;
61688      }
61689
61690      for (i = 0, l = path.length; i < l; i++) {
61691        states = recognizeChar(states, path.charAt(i));
61692        if (!states.length) {
61693          break;
61694        }
61695      }
61696
61697      // END DEBUG GROUP
61698
61699      var solutions = [];
61700      for (i = 0, l = states.length; i < l; i++) {
61701        if (states[i].handlers) {
61702          solutions.push(states[i]);
61703        }
61704      }
61705
61706      states = sortSolutions(solutions);
61707
61708      var state = solutions[0];
61709
61710      if (state && state.handlers) {
61711        // if a trailing slash was dropped and a star segment is the last segment
61712        // specified, put the trailing slash back
61713        if (isSlashDropped && state.regex.source.slice(-5) === "(.+)$") {
61714          path = path + "/";
61715        }
61716        return findHandler(state, path, queryParams);
61717      }
61718    }
61719  };
61720
61721  RouteRecognizer.prototype.map = _routeRecognizerDsl.default;
61722
61723  RouteRecognizer.VERSION = '0.1.5';
61724
61725  exports.default = RouteRecognizer;
61726});
61727enifed('router/handler-info/factory', ['exports', 'router/handler-info/resolved-handler-info', 'router/handler-info/unresolved-handler-info-by-object', 'router/handler-info/unresolved-handler-info-by-param'], function (exports, _routerHandlerInfoResolvedHandlerInfo, _routerHandlerInfoUnresolvedHandlerInfoByObject, _routerHandlerInfoUnresolvedHandlerInfoByParam) {
61728  'use strict';
61729
61730  handlerInfoFactory.klasses = {
61731    resolved: _routerHandlerInfoResolvedHandlerInfo.default,
61732    param: _routerHandlerInfoUnresolvedHandlerInfoByParam.default,
61733    object: _routerHandlerInfoUnresolvedHandlerInfoByObject.default
61734  };
61735
61736  function handlerInfoFactory(name, props) {
61737    var Ctor = handlerInfoFactory.klasses[name],
61738        handlerInfo = new Ctor(props || {});
61739    handlerInfo.factory = handlerInfoFactory;
61740    return handlerInfo;
61741  }
61742
61743  exports.default = handlerInfoFactory;
61744});
61745enifed('router/handler-info/resolved-handler-info', ['exports', 'router/handler-info', 'router/utils', 'rsvp/promise'], function (exports, _routerHandlerInfo, _routerUtils, _rsvpPromise) {
61746  'use strict';
61747
61748  var ResolvedHandlerInfo = _routerUtils.subclass(_routerHandlerInfo.default, {
61749    resolve: function (shouldContinue, payload) {
61750      // A ResolvedHandlerInfo just resolved with itself.
61751      if (payload && payload.resolvedModels) {
61752        payload.resolvedModels[this.name] = this.context;
61753      }
61754      return _rsvpPromise.default.resolve(this, this.promiseLabel("Resolve"));
61755    },
61756
61757    getUnresolved: function () {
61758      return this.factory('param', {
61759        name: this.name,
61760        handler: this.handler,
61761        params: this.params
61762      });
61763    },
61764
61765    isResolved: true
61766  });
61767
61768  exports.default = ResolvedHandlerInfo;
61769});
61770enifed('router/handler-info/unresolved-handler-info-by-object', ['exports', 'router/handler-info', 'router/utils', 'rsvp/promise'], function (exports, _routerHandlerInfo, _routerUtils, _rsvpPromise) {
61771  'use strict';
61772
61773  var UnresolvedHandlerInfoByObject = _routerUtils.subclass(_routerHandlerInfo.default, {
61774    getModel: function (payload) {
61775      this.log(payload, this.name + ": resolving provided model");
61776      return _rsvpPromise.default.resolve(this.context);
61777    },
61778
61779    initialize: function (props) {
61780      this.names = props.names || [];
61781      this.context = props.context;
61782    },
61783
61784    /**
61785      @private
61786       Serializes a handler using its custom `serialize` method or
61787      by a default that looks up the expected property name from
61788      the dynamic segment.
61789       @param {Object} model the model to be serialized for this handler
61790    */
61791    serialize: function (_model) {
61792      var model = _model || this.context,
61793          names = this.names,
61794          handler = this.handler;
61795
61796      var object = {};
61797      if (_routerUtils.isParam(model)) {
61798        object[names[0]] = model;
61799        return object;
61800      }
61801
61802      // Use custom serialize if it exists.
61803      if (handler.serialize) {
61804        return handler.serialize(model, names);
61805      }
61806
61807      if (names.length !== 1) {
61808        return;
61809      }
61810
61811      var name = names[0];
61812
61813      if (/_id$/.test(name)) {
61814        object[name] = model.id;
61815      } else {
61816        object[name] = model;
61817      }
61818      return object;
61819    }
61820  });
61821
61822  exports.default = UnresolvedHandlerInfoByObject;
61823});
61824enifed('router/handler-info/unresolved-handler-info-by-param', ['exports', 'router/handler-info', 'router/utils'], function (exports, _routerHandlerInfo, _routerUtils) {
61825  'use strict';
61826
61827  // Generated by URL transitions and non-dynamic route segments in named Transitions.
61828  var UnresolvedHandlerInfoByParam = _routerUtils.subclass(_routerHandlerInfo.default, {
61829    initialize: function (props) {
61830      this.params = props.params || {};
61831    },
61832
61833    getModel: function (payload) {
61834      var fullParams = this.params;
61835      if (payload && payload.queryParams) {
61836        fullParams = {};
61837        _routerUtils.merge(fullParams, this.params);
61838        fullParams.queryParams = payload.queryParams;
61839      }
61840
61841      var handler = this.handler;
61842      var hookName = _routerUtils.resolveHook(handler, 'deserialize') || _routerUtils.resolveHook(handler, 'model');
61843
61844      return this.runSharedModelHook(payload, hookName, [fullParams]);
61845    }
61846  });
61847
61848  exports.default = UnresolvedHandlerInfoByParam;
61849});
61850enifed('router/handler-info', ['exports', 'router/utils', 'rsvp/promise'], function (exports, _routerUtils, _rsvpPromise) {
61851  'use strict';
61852
61853  function HandlerInfo(_props) {
61854    var props = _props || {};
61855    _routerUtils.merge(this, props);
61856    this.initialize(props);
61857  }
61858
61859  HandlerInfo.prototype = {
61860    name: null,
61861    handler: null,
61862    params: null,
61863    context: null,
61864
61865    // Injected by the handler info factory.
61866    factory: null,
61867
61868    initialize: function () {},
61869
61870    log: function (payload, message) {
61871      if (payload.log) {
61872        payload.log(this.name + ': ' + message);
61873      }
61874    },
61875
61876    promiseLabel: function (label) {
61877      return _routerUtils.promiseLabel("'" + this.name + "' " + label);
61878    },
61879
61880    getUnresolved: function () {
61881      return this;
61882    },
61883
61884    serialize: function () {
61885      return this.params || {};
61886    },
61887
61888    resolve: function (shouldContinue, payload) {
61889      var checkForAbort = _routerUtils.bind(this, this.checkForAbort, shouldContinue),
61890          beforeModel = _routerUtils.bind(this, this.runBeforeModelHook, payload),
61891          model = _routerUtils.bind(this, this.getModel, payload),
61892          afterModel = _routerUtils.bind(this, this.runAfterModelHook, payload),
61893          becomeResolved = _routerUtils.bind(this, this.becomeResolved, payload);
61894
61895      return _rsvpPromise.default.resolve(undefined, this.promiseLabel("Start handler")).then(checkForAbort, null, this.promiseLabel("Check for abort")).then(beforeModel, null, this.promiseLabel("Before model")).then(checkForAbort, null, this.promiseLabel("Check if aborted during 'beforeModel' hook")).then(model, null, this.promiseLabel("Model")).then(checkForAbort, null, this.promiseLabel("Check if aborted in 'model' hook")).then(afterModel, null, this.promiseLabel("After model")).then(checkForAbort, null, this.promiseLabel("Check if aborted in 'afterModel' hook")).then(becomeResolved, null, this.promiseLabel("Become resolved"));
61896    },
61897
61898    runBeforeModelHook: function (payload) {
61899      if (payload.trigger) {
61900        payload.trigger(true, 'willResolveModel', payload, this.handler);
61901      }
61902      return this.runSharedModelHook(payload, 'beforeModel', []);
61903    },
61904
61905    runAfterModelHook: function (payload, resolvedModel) {
61906      // Stash the resolved model on the payload.
61907      // This makes it possible for users to swap out
61908      // the resolved model in afterModel.
61909      var name = this.name;
61910      this.stashResolvedModel(payload, resolvedModel);
61911
61912      return this.runSharedModelHook(payload, 'afterModel', [resolvedModel]).then(function () {
61913        // Ignore the fulfilled value returned from afterModel.
61914        // Return the value stashed in resolvedModels, which
61915        // might have been swapped out in afterModel.
61916        return payload.resolvedModels[name];
61917      }, null, this.promiseLabel("Ignore fulfillment value and return model value"));
61918    },
61919
61920    runSharedModelHook: function (payload, hookName, args) {
61921      this.log(payload, "calling " + hookName + " hook");
61922
61923      if (this.queryParams) {
61924        args.push(this.queryParams);
61925      }
61926      args.push(payload);
61927
61928      var result = _routerUtils.applyHook(this.handler, hookName, args);
61929
61930      if (result && result.isTransition) {
61931        result = null;
61932      }
61933
61934      return _rsvpPromise.default.resolve(result, this.promiseLabel("Resolve value returned from one of the model hooks"));
61935    },
61936
61937    // overridden by subclasses
61938    getModel: null,
61939
61940    checkForAbort: function (shouldContinue, promiseValue) {
61941      return _rsvpPromise.default.resolve(shouldContinue(), this.promiseLabel("Check for abort")).then(function () {
61942        // We don't care about shouldContinue's resolve value;
61943        // pass along the original value passed to this fn.
61944        return promiseValue;
61945      }, null, this.promiseLabel("Ignore fulfillment value and continue"));
61946    },
61947
61948    stashResolvedModel: function (payload, resolvedModel) {
61949      payload.resolvedModels = payload.resolvedModels || {};
61950      payload.resolvedModels[this.name] = resolvedModel;
61951    },
61952
61953    becomeResolved: function (payload, resolvedContext) {
61954      var params = this.serialize(resolvedContext);
61955
61956      if (payload) {
61957        this.stashResolvedModel(payload, resolvedContext);
61958        payload.params = payload.params || {};
61959        payload.params[this.name] = params;
61960      }
61961
61962      return this.factory('resolved', {
61963        context: resolvedContext,
61964        name: this.name,
61965        handler: this.handler,
61966        params: params
61967      });
61968    },
61969
61970    shouldSupercede: function (other) {
61971      // Prefer this newer handlerInfo over `other` if:
61972      // 1) The other one doesn't exist
61973      // 2) The names don't match
61974      // 3) This handler has a context that doesn't match
61975      //    the other one (or the other one doesn't have one).
61976      // 4) This handler has parameters that don't match the other.
61977      if (!other) {
61978        return true;
61979      }
61980
61981      var contextsMatch = other.context === this.context;
61982      return other.name !== this.name || this.hasOwnProperty('context') && !contextsMatch || this.hasOwnProperty('params') && !paramsMatch(this.params, other.params);
61983    }
61984  };
61985
61986  function paramsMatch(a, b) {
61987    if (!a ^ !b) {
61988      // Only one is null.
61989      return false;
61990    }
61991
61992    if (!a) {
61993      // Both must be null.
61994      return true;
61995    }
61996
61997    // Note: this assumes that both params have the same
61998    // number of keys, but since we're comparing the
61999    // same handlers, they should.
62000    for (var k in a) {
62001      if (a.hasOwnProperty(k) && a[k] !== b[k]) {
62002        return false;
62003      }
62004    }
62005    return true;
62006  }
62007
62008  exports.default = HandlerInfo;
62009});
62010enifed('router/router', ['exports', 'route-recognizer', 'rsvp/promise', 'router/utils', 'router/transition-state', 'router/transition', 'router/transition-intent/named-transition-intent', 'router/transition-intent/url-transition-intent', 'router/handler-info'], function (exports, _routeRecognizer, _rsvpPromise, _routerUtils, _routerTransitionState, _routerTransition, _routerTransitionIntentNamedTransitionIntent, _routerTransitionIntentUrlTransitionIntent, _routerHandlerInfo) {
62011  'use strict';
62012
62013  var pop = Array.prototype.pop;
62014
62015  function Router(_options) {
62016    var options = _options || {};
62017    this.getHandler = options.getHandler || this.getHandler;
62018    this.updateURL = options.updateURL || this.updateURL;
62019    this.replaceURL = options.replaceURL || this.replaceURL;
62020    this.didTransition = options.didTransition || this.didTransition;
62021    this.willTransition = options.willTransition || this.willTransition;
62022    this.delegate = options.delegate || this.delegate;
62023    this.triggerEvent = options.triggerEvent || this.triggerEvent;
62024    this.log = options.log || this.log;
62025
62026    this.recognizer = new _routeRecognizer.default();
62027    this.reset();
62028  }
62029
62030  function getTransitionByIntent(intent, isIntermediate) {
62031    var wasTransitioning = !!this.activeTransition;
62032    var oldState = wasTransitioning ? this.activeTransition.state : this.state;
62033    var newTransition;
62034
62035    var newState = intent.applyToState(oldState, this.recognizer, this.getHandler, isIntermediate);
62036    var queryParamChangelist = _routerUtils.getChangelist(oldState.queryParams, newState.queryParams);
62037
62038    if (handlerInfosEqual(newState.handlerInfos, oldState.handlerInfos)) {
62039
62040      // This is a no-op transition. See if query params changed.
62041      if (queryParamChangelist) {
62042        newTransition = this.queryParamsTransition(queryParamChangelist, wasTransitioning, oldState, newState);
62043        if (newTransition) {
62044          return newTransition;
62045        }
62046      }
62047
62048      // No-op. No need to create a new transition.
62049      return this.activeTransition || new _routerTransition.Transition(this);
62050    }
62051
62052    if (isIntermediate) {
62053      setupContexts(this, newState);
62054      return;
62055    }
62056
62057    // Create a new transition to the destination route.
62058    newTransition = new _routerTransition.Transition(this, intent, newState);
62059
62060    // Abort and usurp any previously active transition.
62061    if (this.activeTransition) {
62062      this.activeTransition.abort();
62063    }
62064    this.activeTransition = newTransition;
62065
62066    // Transition promises by default resolve with resolved state.
62067    // For our purposes, swap out the promise to resolve
62068    // after the transition has been finalized.
62069    newTransition.promise = newTransition.promise.then(function (result) {
62070      return finalizeTransition(newTransition, result.state);
62071    }, null, _routerUtils.promiseLabel("Settle transition promise when transition is finalized"));
62072
62073    if (!wasTransitioning) {
62074      notifyExistingHandlers(this, newState, newTransition);
62075    }
62076
62077    fireQueryParamDidChange(this, newState, queryParamChangelist);
62078
62079    return newTransition;
62080  }
62081
62082  Router.prototype = {
62083
62084    /**
62085      The main entry point into the router. The API is essentially
62086      the same as the `map` method in `route-recognizer`.
62087       This method extracts the String handler at the last `.to()`
62088      call and uses it as the name of the whole route.
62089       @param {Function} callback
62090    */
62091    map: function (callback) {
62092      this.recognizer.delegate = this.delegate;
62093
62094      this.recognizer.map(callback, function (recognizer, routes) {
62095        for (var i = routes.length - 1, proceed = true; i >= 0 && proceed; --i) {
62096          var route = routes[i];
62097          recognizer.add(routes, { as: route.handler });
62098          proceed = route.path === '/' || route.path === '' || route.handler.slice(-6) === '.index';
62099        }
62100      });
62101    },
62102
62103    hasRoute: function (route) {
62104      return this.recognizer.hasRoute(route);
62105    },
62106
62107    getHandler: function () {},
62108
62109    queryParamsTransition: function (changelist, wasTransitioning, oldState, newState) {
62110      var router = this;
62111
62112      fireQueryParamDidChange(this, newState, changelist);
62113
62114      if (!wasTransitioning && this.activeTransition) {
62115        // One of the handlers in queryParamsDidChange
62116        // caused a transition. Just return that transition.
62117        return this.activeTransition;
62118      } else {
62119        // Running queryParamsDidChange didn't change anything.
62120        // Just update query params and be on our way.
62121
62122        // We have to return a noop transition that will
62123        // perform a URL update at the end. This gives
62124        // the user the ability to set the url update
62125        // method (default is replaceState).
62126        var newTransition = new _routerTransition.Transition(this);
62127        newTransition.queryParamsOnly = true;
62128
62129        oldState.queryParams = finalizeQueryParamChange(this, newState.handlerInfos, newState.queryParams, newTransition);
62130
62131        newTransition.promise = newTransition.promise.then(function (result) {
62132          updateURL(newTransition, oldState, true);
62133          if (router.didTransition) {
62134            router.didTransition(router.currentHandlerInfos);
62135          }
62136          return result;
62137        }, null, _routerUtils.promiseLabel("Transition complete"));
62138        return newTransition;
62139      }
62140    },
62141
62142    // NOTE: this doesn't really belong here, but here
62143    // it shall remain until our ES6 transpiler can
62144    // handle cyclical deps.
62145    transitionByIntent: function (intent, isIntermediate) {
62146      try {
62147        return getTransitionByIntent.apply(this, arguments);
62148      } catch (e) {
62149        return new _routerTransition.Transition(this, intent, null, e);
62150      }
62151    },
62152
62153    /**
62154      Clears the current and target route handlers and triggers exit
62155      on each of them starting at the leaf and traversing up through
62156      its ancestors.
62157    */
62158    reset: function () {
62159      if (this.state) {
62160        _routerUtils.forEach(this.state.handlerInfos.slice().reverse(), function (handlerInfo) {
62161          var handler = handlerInfo.handler;
62162          _routerUtils.callHook(handler, 'exit');
62163        });
62164      }
62165
62166      this.state = new _routerTransitionState.default();
62167      this.currentHandlerInfos = null;
62168    },
62169
62170    activeTransition: null,
62171
62172    /**
62173      var handler = handlerInfo.handler;
62174      The entry point for handling a change to the URL (usually
62175      via the back and forward button).
62176       Returns an Array of handlers and the parameters associated
62177      with those parameters.
62178       @param {String} url a URL to process
62179       @return {Array} an Array of `[handler, parameter]` tuples
62180    */
62181    handleURL: function (url) {
62182      // Perform a URL-based transition, but don't change
62183      // the URL afterward, since it already happened.
62184      var args = _routerUtils.slice.call(arguments);
62185      if (url.charAt(0) !== '/') {
62186        args[0] = '/' + url;
62187      }
62188
62189      return doTransition(this, args).method(null);
62190    },
62191
62192    /**
62193      Hook point for updating the URL.
62194       @param {String} url a URL to update to
62195    */
62196    updateURL: function () {
62197      throw new Error("updateURL is not implemented");
62198    },
62199
62200    /**
62201      Hook point for replacing the current URL, i.e. with replaceState
62202       By default this behaves the same as `updateURL`
62203       @param {String} url a URL to update to
62204    */
62205    replaceURL: function (url) {
62206      this.updateURL(url);
62207    },
62208
62209    /**
62210      Transition into the specified named route.
62211       If necessary, trigger the exit callback on any handlers
62212      that are no longer represented by the target route.
62213       @param {String} name the name of the route
62214    */
62215    transitionTo: function (name) {
62216      return doTransition(this, arguments);
62217    },
62218
62219    intermediateTransitionTo: function (name) {
62220      return doTransition(this, arguments, true);
62221    },
62222
62223    refresh: function (pivotHandler) {
62224      var state = this.activeTransition ? this.activeTransition.state : this.state;
62225      var handlerInfos = state.handlerInfos;
62226      var params = {};
62227      for (var i = 0, len = handlerInfos.length; i < len; ++i) {
62228        var handlerInfo = handlerInfos[i];
62229        params[handlerInfo.name] = handlerInfo.params || {};
62230      }
62231
62232      _routerUtils.log(this, "Starting a refresh transition");
62233      var intent = new _routerTransitionIntentNamedTransitionIntent.default({
62234        name: handlerInfos[handlerInfos.length - 1].name,
62235        pivotHandler: pivotHandler || handlerInfos[0].handler,
62236        contexts: [], // TODO collect contexts...?
62237        queryParams: this._changedQueryParams || state.queryParams || {}
62238      });
62239
62240      return this.transitionByIntent(intent, false);
62241    },
62242
62243    /**
62244      Identical to `transitionTo` except that the current URL will be replaced
62245      if possible.
62246       This method is intended primarily for use with `replaceState`.
62247       @param {String} name the name of the route
62248    */
62249    replaceWith: function (name) {
62250      return doTransition(this, arguments).method('replace');
62251    },
62252
62253    /**
62254      Take a named route and context objects and generate a
62255      URL.
62256       @param {String} name the name of the route to generate
62257        a URL for
62258      @param {...Object} objects a list of objects to serialize
62259       @return {String} a URL
62260    */
62261    generate: function (handlerName) {
62262
62263      var partitionedArgs = _routerUtils.extractQueryParams(_routerUtils.slice.call(arguments, 1)),
62264          suppliedParams = partitionedArgs[0],
62265          queryParams = partitionedArgs[1];
62266
62267      // Construct a TransitionIntent with the provided params
62268      // and apply it to the present state of the router.
62269      var intent = new _routerTransitionIntentNamedTransitionIntent.default({ name: handlerName, contexts: suppliedParams });
62270      var state = intent.applyToState(this.state, this.recognizer, this.getHandler);
62271      var params = {};
62272
62273      for (var i = 0, len = state.handlerInfos.length; i < len; ++i) {
62274        var handlerInfo = state.handlerInfos[i];
62275        var handlerParams = handlerInfo.serialize();
62276        _routerUtils.merge(params, handlerParams);
62277      }
62278      params.queryParams = queryParams;
62279
62280      return this.recognizer.generate(handlerName, params);
62281    },
62282
62283    applyIntent: function (handlerName, contexts) {
62284      var intent = new _routerTransitionIntentNamedTransitionIntent.default({
62285        name: handlerName,
62286        contexts: contexts
62287      });
62288
62289      var state = this.activeTransition && this.activeTransition.state || this.state;
62290      return intent.applyToState(state, this.recognizer, this.getHandler);
62291    },
62292
62293    isActiveIntent: function (handlerName, contexts, queryParams, _state) {
62294      var state = _state || this.state,
62295          targetHandlerInfos = state.handlerInfos,
62296          found = false,
62297          names,
62298          object,
62299          handlerInfo,
62300          handlerObj,
62301          i,
62302          len;
62303
62304      if (!targetHandlerInfos.length) {
62305        return false;
62306      }
62307
62308      var targetHandler = targetHandlerInfos[targetHandlerInfos.length - 1].name;
62309      var recogHandlers = this.recognizer.handlersFor(targetHandler);
62310
62311      var index = 0;
62312      for (len = recogHandlers.length; index < len; ++index) {
62313        handlerInfo = targetHandlerInfos[index];
62314        if (handlerInfo.name === handlerName) {
62315          break;
62316        }
62317      }
62318
62319      if (index === recogHandlers.length) {
62320        // The provided route name isn't even in the route hierarchy.
62321        return false;
62322      }
62323
62324      var testState = new _routerTransitionState.default();
62325      testState.handlerInfos = targetHandlerInfos.slice(0, index + 1);
62326      recogHandlers = recogHandlers.slice(0, index + 1);
62327
62328      var intent = new _routerTransitionIntentNamedTransitionIntent.default({
62329        name: targetHandler,
62330        contexts: contexts
62331      });
62332
62333      var newState = intent.applyToHandlers(testState, recogHandlers, this.getHandler, targetHandler, true, true);
62334
62335      var handlersEqual = handlerInfosEqual(newState.handlerInfos, testState.handlerInfos);
62336      if (!queryParams || !handlersEqual) {
62337        return handlersEqual;
62338      }
62339
62340      // Get a hash of QPs that will still be active on new route
62341      var activeQPsOnNewHandler = {};
62342      _routerUtils.merge(activeQPsOnNewHandler, queryParams);
62343
62344      var activeQueryParams = state.queryParams;
62345      for (var key in activeQueryParams) {
62346        if (activeQueryParams.hasOwnProperty(key) && activeQPsOnNewHandler.hasOwnProperty(key)) {
62347          activeQPsOnNewHandler[key] = activeQueryParams[key];
62348        }
62349      }
62350
62351      return handlersEqual && !_routerUtils.getChangelist(activeQPsOnNewHandler, queryParams);
62352    },
62353
62354    isActive: function (handlerName) {
62355      var partitionedArgs = _routerUtils.extractQueryParams(_routerUtils.slice.call(arguments, 1));
62356      return this.isActiveIntent(handlerName, partitionedArgs[0], partitionedArgs[1]);
62357    },
62358
62359    trigger: function (name) {
62360      var args = _routerUtils.slice.call(arguments);
62361      _routerUtils.trigger(this, this.currentHandlerInfos, false, args);
62362    },
62363
62364    /**
62365      Hook point for logging transition status updates.
62366       @param {String} message The message to log.
62367    */
62368    log: null
62369  };
62370
62371  /**
62372    @private
62373  
62374    Fires queryParamsDidChange event
62375  */
62376  function fireQueryParamDidChange(router, newState, queryParamChangelist) {
62377    // If queryParams changed trigger event
62378    if (queryParamChangelist) {
62379
62380      // This is a little hacky but we need some way of storing
62381      // changed query params given that no activeTransition
62382      // is guaranteed to have occurred.
62383      router._changedQueryParams = queryParamChangelist.all;
62384      _routerUtils.trigger(router, newState.handlerInfos, true, ['queryParamsDidChange', queryParamChangelist.changed, queryParamChangelist.all, queryParamChangelist.removed]);
62385      router._changedQueryParams = null;
62386    }
62387  }
62388
62389  /**
62390    @private
62391  
62392    Takes an Array of `HandlerInfo`s, figures out which ones are
62393    exiting, entering, or changing contexts, and calls the
62394    proper handler hooks.
62395  
62396    For example, consider the following tree of handlers. Each handler is
62397    followed by the URL segment it handles.
62398  
62399    ```
62400    |~index ("/")
62401    | |~posts ("/posts")
62402    | | |-showPost ("/:id")
62403    | | |-newPost ("/new")
62404    | | |-editPost ("/edit")
62405    | |~about ("/about/:id")
62406    ```
62407  
62408    Consider the following transitions:
62409  
62410    1. A URL transition to `/posts/1`.
62411       1. Triggers the `*model` callbacks on the
62412          `index`, `posts`, and `showPost` handlers
62413       2. Triggers the `enter` callback on the same
62414       3. Triggers the `setup` callback on the same
62415    2. A direct transition to `newPost`
62416       1. Triggers the `exit` callback on `showPost`
62417       2. Triggers the `enter` callback on `newPost`
62418       3. Triggers the `setup` callback on `newPost`
62419    3. A direct transition to `about` with a specified
62420       context object
62421       1. Triggers the `exit` callback on `newPost`
62422          and `posts`
62423       2. Triggers the `serialize` callback on `about`
62424       3. Triggers the `enter` callback on `about`
62425       4. Triggers the `setup` callback on `about`
62426  
62427    @param {Router} transition
62428    @param {TransitionState} newState
62429  */
62430  function setupContexts(router, newState, transition) {
62431    var partition = partitionHandlers(router.state, newState);
62432    var i, l, handler;
62433
62434    for (i = 0, l = partition.exited.length; i < l; i++) {
62435      handler = partition.exited[i].handler;
62436      delete handler.context;
62437
62438      _routerUtils.callHook(handler, 'reset', true, transition);
62439      _routerUtils.callHook(handler, 'exit', transition);
62440    }
62441
62442    var oldState = router.oldState = router.state;
62443    router.state = newState;
62444    var currentHandlerInfos = router.currentHandlerInfos = partition.unchanged.slice();
62445
62446    try {
62447      for (i = 0, l = partition.reset.length; i < l; i++) {
62448        handler = partition.reset[i].handler;
62449        _routerUtils.callHook(handler, 'reset', false, transition);
62450      }
62451
62452      for (i = 0, l = partition.updatedContext.length; i < l; i++) {
62453        handlerEnteredOrUpdated(currentHandlerInfos, partition.updatedContext[i], false, transition);
62454      }
62455
62456      for (i = 0, l = partition.entered.length; i < l; i++) {
62457        handlerEnteredOrUpdated(currentHandlerInfos, partition.entered[i], true, transition);
62458      }
62459    } catch (e) {
62460      router.state = oldState;
62461      router.currentHandlerInfos = oldState.handlerInfos;
62462      throw e;
62463    }
62464
62465    router.state.queryParams = finalizeQueryParamChange(router, currentHandlerInfos, newState.queryParams, transition);
62466  }
62467
62468  /**
62469    @private
62470  
62471    Helper method used by setupContexts. Handles errors or redirects
62472    that may happen in enter/setup.
62473  */
62474  function handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, enter, transition) {
62475
62476    var handler = handlerInfo.handler,
62477        context = handlerInfo.context;
62478
62479    if (enter) {
62480      _routerUtils.callHook(handler, 'enter', transition);
62481    }
62482    if (transition && transition.isAborted) {
62483      throw new _routerTransition.TransitionAborted();
62484    }
62485
62486    handler.context = context;
62487    _routerUtils.callHook(handler, 'contextDidChange');
62488
62489    _routerUtils.callHook(handler, 'setup', context, transition);
62490    if (transition && transition.isAborted) {
62491      throw new _routerTransition.TransitionAborted();
62492    }
62493
62494    currentHandlerInfos.push(handlerInfo);
62495
62496    return true;
62497  }
62498
62499  /**
62500    @private
62501  
62502    This function is called when transitioning from one URL to
62503    another to determine which handlers are no longer active,
62504    which handlers are newly active, and which handlers remain
62505    active but have their context changed.
62506  
62507    Take a list of old handlers and new handlers and partition
62508    them into four buckets:
62509  
62510    * unchanged: the handler was active in both the old and
62511      new URL, and its context remains the same
62512    * updated context: the handler was active in both the
62513      old and new URL, but its context changed. The handler's
62514      `setup` method, if any, will be called with the new
62515      context.
62516    * exited: the handler was active in the old URL, but is
62517      no longer active.
62518    * entered: the handler was not active in the old URL, but
62519      is now active.
62520  
62521    The PartitionedHandlers structure has four fields:
62522  
62523    * `updatedContext`: a list of `HandlerInfo` objects that
62524      represent handlers that remain active but have a changed
62525      context
62526    * `entered`: a list of `HandlerInfo` objects that represent
62527      handlers that are newly active
62528    * `exited`: a list of `HandlerInfo` objects that are no
62529      longer active.
62530    * `unchanged`: a list of `HanderInfo` objects that remain active.
62531  
62532    @param {Array[HandlerInfo]} oldHandlers a list of the handler
62533      information for the previous URL (or `[]` if this is the
62534      first handled transition)
62535    @param {Array[HandlerInfo]} newHandlers a list of the handler
62536      information for the new URL
62537  
62538    @return {Partition}
62539  */
62540  function partitionHandlers(oldState, newState) {
62541    var oldHandlers = oldState.handlerInfos;
62542    var newHandlers = newState.handlerInfos;
62543
62544    var handlers = {
62545      updatedContext: [],
62546      exited: [],
62547      entered: [],
62548      unchanged: []
62549    };
62550
62551    var handlerChanged,
62552        contextChanged = false,
62553        i,
62554        l;
62555
62556    for (i = 0, l = newHandlers.length; i < l; i++) {
62557      var oldHandler = oldHandlers[i],
62558          newHandler = newHandlers[i];
62559
62560      if (!oldHandler || oldHandler.handler !== newHandler.handler) {
62561        handlerChanged = true;
62562      }
62563
62564      if (handlerChanged) {
62565        handlers.entered.push(newHandler);
62566        if (oldHandler) {
62567          handlers.exited.unshift(oldHandler);
62568        }
62569      } else if (contextChanged || oldHandler.context !== newHandler.context) {
62570        contextChanged = true;
62571        handlers.updatedContext.push(newHandler);
62572      } else {
62573        handlers.unchanged.push(oldHandler);
62574      }
62575    }
62576
62577    for (i = newHandlers.length, l = oldHandlers.length; i < l; i++) {
62578      handlers.exited.unshift(oldHandlers[i]);
62579    }
62580
62581    handlers.reset = handlers.updatedContext.slice();
62582    handlers.reset.reverse();
62583
62584    return handlers;
62585  }
62586
62587  function updateURL(transition, state, inputUrl) {
62588    var urlMethod = transition.urlMethod;
62589
62590    if (!urlMethod) {
62591      return;
62592    }
62593
62594    var router = transition.router,
62595        handlerInfos = state.handlerInfos,
62596        handlerName = handlerInfos[handlerInfos.length - 1].name,
62597        params = {};
62598
62599    for (var i = handlerInfos.length - 1; i >= 0; --i) {
62600      var handlerInfo = handlerInfos[i];
62601      _routerUtils.merge(params, handlerInfo.params);
62602      if (handlerInfo.handler.inaccessibleByURL) {
62603        urlMethod = null;
62604      }
62605    }
62606
62607    if (urlMethod) {
62608      params.queryParams = transition._visibleQueryParams || state.queryParams;
62609      var url = router.recognizer.generate(handlerName, params);
62610
62611      if (urlMethod === 'replace') {
62612        router.replaceURL(url);
62613      } else {
62614        router.updateURL(url);
62615      }
62616    }
62617  }
62618
62619  /**
62620    @private
62621  
62622    Updates the URL (if necessary) and calls `setupContexts`
62623    to update the router's array of `currentHandlerInfos`.
62624   */
62625  function finalizeTransition(transition, newState) {
62626
62627    try {
62628      _routerUtils.log(transition.router, transition.sequence, "Resolved all models on destination route; finalizing transition.");
62629
62630      var router = transition.router,
62631          handlerInfos = newState.handlerInfos,
62632          seq = transition.sequence;
62633
62634      // Run all the necessary enter/setup/exit hooks
62635      setupContexts(router, newState, transition);
62636
62637      // Check if a redirect occurred in enter/setup
62638      if (transition.isAborted) {
62639        // TODO: cleaner way? distinguish b/w targetHandlerInfos?
62640        router.state.handlerInfos = router.currentHandlerInfos;
62641        return _rsvpPromise.default.reject(_routerTransition.logAbort(transition));
62642      }
62643
62644      updateURL(transition, newState, transition.intent.url);
62645
62646      transition.isActive = false;
62647      router.activeTransition = null;
62648
62649      _routerUtils.trigger(router, router.currentHandlerInfos, true, ['didTransition']);
62650
62651      if (router.didTransition) {
62652        router.didTransition(router.currentHandlerInfos);
62653      }
62654
62655      _routerUtils.log(router, transition.sequence, "TRANSITION COMPLETE.");
62656
62657      // Resolve with the final handler.
62658      return handlerInfos[handlerInfos.length - 1].handler;
62659    } catch (e) {
62660      if (!(e instanceof _routerTransition.TransitionAborted)) {
62661        //var erroneousHandler = handlerInfos.pop();
62662        var infos = transition.state.handlerInfos;
62663        transition.trigger(true, 'error', e, transition, infos[infos.length - 1].handler);
62664        transition.abort();
62665      }
62666
62667      throw e;
62668    }
62669  }
62670
62671  /**
62672    @private
62673  
62674    Begins and returns a Transition based on the provided
62675    arguments. Accepts arguments in the form of both URL
62676    transitions and named transitions.
62677  
62678    @param {Router} router
62679    @param {Array[Object]} args arguments passed to transitionTo,
62680      replaceWith, or handleURL
62681  */
62682  function doTransition(router, args, isIntermediate) {
62683    // Normalize blank transitions to root URL transitions.
62684    var name = args[0] || '/';
62685
62686    var lastArg = args[args.length - 1];
62687    var queryParams = {};
62688    if (lastArg && lastArg.hasOwnProperty('queryParams')) {
62689      queryParams = pop.call(args).queryParams;
62690    }
62691
62692    var intent;
62693    if (args.length === 0) {
62694
62695      _routerUtils.log(router, "Updating query params");
62696
62697      // A query param update is really just a transition
62698      // into the route you're already on.
62699      var handlerInfos = router.state.handlerInfos;
62700      intent = new _routerTransitionIntentNamedTransitionIntent.default({
62701        name: handlerInfos[handlerInfos.length - 1].name,
62702        contexts: [],
62703        queryParams: queryParams
62704      });
62705    } else if (name.charAt(0) === '/') {
62706
62707      _routerUtils.log(router, "Attempting URL transition to " + name);
62708      intent = new _routerTransitionIntentUrlTransitionIntent.default({ url: name });
62709    } else {
62710
62711      _routerUtils.log(router, "Attempting transition to " + name);
62712      intent = new _routerTransitionIntentNamedTransitionIntent.default({
62713        name: args[0],
62714        contexts: _routerUtils.slice.call(args, 1),
62715        queryParams: queryParams
62716      });
62717    }
62718
62719    return router.transitionByIntent(intent, isIntermediate);
62720  }
62721
62722  function handlerInfosEqual(handlerInfos, otherHandlerInfos) {
62723    if (handlerInfos.length !== otherHandlerInfos.length) {
62724      return false;
62725    }
62726
62727    for (var i = 0, len = handlerInfos.length; i < len; ++i) {
62728      if (handlerInfos[i] !== otherHandlerInfos[i]) {
62729        return false;
62730      }
62731    }
62732    return true;
62733  }
62734
62735  function finalizeQueryParamChange(router, resolvedHandlers, newQueryParams, transition) {
62736    // We fire a finalizeQueryParamChange event which
62737    // gives the new route hierarchy a chance to tell
62738    // us which query params it's consuming and what
62739    // their final values are. If a query param is
62740    // no longer consumed in the final route hierarchy,
62741    // its serialized segment will be removed
62742    // from the URL.
62743
62744    for (var k in newQueryParams) {
62745      if (newQueryParams.hasOwnProperty(k) && newQueryParams[k] === null) {
62746        delete newQueryParams[k];
62747      }
62748    }
62749
62750    var finalQueryParamsArray = [];
62751    _routerUtils.trigger(router, resolvedHandlers, true, ['finalizeQueryParamChange', newQueryParams, finalQueryParamsArray, transition]);
62752
62753    if (transition) {
62754      transition._visibleQueryParams = {};
62755    }
62756
62757    var finalQueryParams = {};
62758    for (var i = 0, len = finalQueryParamsArray.length; i < len; ++i) {
62759      var qp = finalQueryParamsArray[i];
62760      finalQueryParams[qp.key] = qp.value;
62761      if (transition && qp.visible !== false) {
62762        transition._visibleQueryParams[qp.key] = qp.value;
62763      }
62764    }
62765    return finalQueryParams;
62766  }
62767
62768  function notifyExistingHandlers(router, newState, newTransition) {
62769    var oldHandlers = router.state.handlerInfos,
62770        changing = [],
62771        leavingIndex = null,
62772        leaving,
62773        leavingChecker,
62774        i,
62775        oldHandlerLen,
62776        oldHandler,
62777        newHandler;
62778
62779    oldHandlerLen = oldHandlers.length;
62780    for (i = 0; i < oldHandlerLen; i++) {
62781      oldHandler = oldHandlers[i];
62782      newHandler = newState.handlerInfos[i];
62783
62784      if (!newHandler || oldHandler.name !== newHandler.name) {
62785        leavingIndex = i;
62786        break;
62787      }
62788
62789      if (!newHandler.isResolved) {
62790        changing.push(oldHandler);
62791      }
62792    }
62793
62794    if (leavingIndex !== null) {
62795      leaving = oldHandlers.slice(leavingIndex, oldHandlerLen);
62796      leavingChecker = function (name) {
62797        for (var h = 0, len = leaving.length; h < len; h++) {
62798          if (leaving[h].name === name) {
62799            return true;
62800          }
62801        }
62802        return false;
62803      };
62804    }
62805
62806    _routerUtils.trigger(router, oldHandlers, true, ['willTransition', newTransition]);
62807
62808    if (router.willTransition) {
62809      router.willTransition(oldHandlers, newState.handlerInfos, newTransition);
62810    }
62811  }
62812
62813  exports.default = Router;
62814});
62815enifed('router/transition-intent/named-transition-intent', ['exports', 'router/transition-intent', 'router/transition-state', 'router/handler-info/factory', 'router/utils'], function (exports, _routerTransitionIntent, _routerTransitionState, _routerHandlerInfoFactory, _routerUtils) {
62816  'use strict';
62817
62818  exports.default = _routerUtils.subclass(_routerTransitionIntent.default, {
62819    name: null,
62820    pivotHandler: null,
62821    contexts: null,
62822    queryParams: null,
62823
62824    initialize: function (props) {
62825      this.name = props.name;
62826      this.pivotHandler = props.pivotHandler;
62827      this.contexts = props.contexts || [];
62828      this.queryParams = props.queryParams;
62829    },
62830
62831    applyToState: function (oldState, recognizer, getHandler, isIntermediate) {
62832
62833      var partitionedArgs = _routerUtils.extractQueryParams([this.name].concat(this.contexts)),
62834          pureArgs = partitionedArgs[0],
62835          queryParams = partitionedArgs[1],
62836          handlers = recognizer.handlersFor(pureArgs[0]);
62837
62838      var targetRouteName = handlers[handlers.length - 1].handler;
62839
62840      return this.applyToHandlers(oldState, handlers, getHandler, targetRouteName, isIntermediate);
62841    },
62842
62843    applyToHandlers: function (oldState, handlers, getHandler, targetRouteName, isIntermediate, checkingIfActive) {
62844
62845      var i, len;
62846      var newState = new _routerTransitionState.default();
62847      var objects = this.contexts.slice(0);
62848
62849      var invalidateIndex = handlers.length;
62850
62851      // Pivot handlers are provided for refresh transitions
62852      if (this.pivotHandler) {
62853        for (i = 0, len = handlers.length; i < len; ++i) {
62854          if (getHandler(handlers[i].handler) === this.pivotHandler) {
62855            invalidateIndex = i;
62856            break;
62857          }
62858        }
62859      }
62860
62861      var pivotHandlerFound = !this.pivotHandler;
62862
62863      for (i = handlers.length - 1; i >= 0; --i) {
62864        var result = handlers[i];
62865        var name = result.handler;
62866        var handler = getHandler(name);
62867
62868        var oldHandlerInfo = oldState.handlerInfos[i];
62869        var newHandlerInfo = null;
62870
62871        if (result.names.length > 0) {
62872          if (i >= invalidateIndex) {
62873            newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
62874          } else {
62875            newHandlerInfo = this.getHandlerInfoForDynamicSegment(name, handler, result.names, objects, oldHandlerInfo, targetRouteName, i);
62876          }
62877        } else {
62878          // This route has no dynamic segment.
62879          // Therefore treat as a param-based handlerInfo
62880          // with empty params. This will cause the `model`
62881          // hook to be called with empty params, which is desirable.
62882          newHandlerInfo = this.createParamHandlerInfo(name, handler, result.names, objects, oldHandlerInfo);
62883        }
62884
62885        if (checkingIfActive) {
62886          // If we're performing an isActive check, we want to
62887          // serialize URL params with the provided context, but
62888          // ignore mismatches between old and new context.
62889          newHandlerInfo = newHandlerInfo.becomeResolved(null, newHandlerInfo.context);
62890          var oldContext = oldHandlerInfo && oldHandlerInfo.context;
62891          if (result.names.length > 0 && newHandlerInfo.context === oldContext) {
62892            // If contexts match in isActive test, assume params also match.
62893            // This allows for flexibility in not requiring that every last
62894            // handler provide a `serialize` method
62895            newHandlerInfo.params = oldHandlerInfo && oldHandlerInfo.params;
62896          }
62897          newHandlerInfo.context = oldContext;
62898        }
62899
62900        var handlerToUse = oldHandlerInfo;
62901        if (i >= invalidateIndex || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
62902          invalidateIndex = Math.min(i, invalidateIndex);
62903          handlerToUse = newHandlerInfo;
62904        }
62905
62906        if (isIntermediate && !checkingIfActive) {
62907          handlerToUse = handlerToUse.becomeResolved(null, handlerToUse.context);
62908        }
62909
62910        newState.handlerInfos.unshift(handlerToUse);
62911      }
62912
62913      if (objects.length > 0) {
62914        throw new Error("More context objects were passed than there are dynamic segments for the route: " + targetRouteName);
62915      }
62916
62917      if (!isIntermediate) {
62918        this.invalidateChildren(newState.handlerInfos, invalidateIndex);
62919      }
62920
62921      _routerUtils.merge(newState.queryParams, this.queryParams || {});
62922
62923      return newState;
62924    },
62925
62926    invalidateChildren: function (handlerInfos, invalidateIndex) {
62927      for (var i = invalidateIndex, l = handlerInfos.length; i < l; ++i) {
62928        var handlerInfo = handlerInfos[i];
62929        handlerInfos[i] = handlerInfos[i].getUnresolved();
62930      }
62931    },
62932
62933    getHandlerInfoForDynamicSegment: function (name, handler, names, objects, oldHandlerInfo, targetRouteName, i) {
62934
62935      var numNames = names.length;
62936      var objectToUse;
62937      if (objects.length > 0) {
62938
62939        // Use the objects provided for this transition.
62940        objectToUse = objects[objects.length - 1];
62941        if (_routerUtils.isParam(objectToUse)) {
62942          return this.createParamHandlerInfo(name, handler, names, objects, oldHandlerInfo);
62943        } else {
62944          objects.pop();
62945        }
62946      } else if (oldHandlerInfo && oldHandlerInfo.name === name) {
62947        // Reuse the matching oldHandlerInfo
62948        return oldHandlerInfo;
62949      } else {
62950        if (this.preTransitionState) {
62951          var preTransitionHandlerInfo = this.preTransitionState.handlerInfos[i];
62952          objectToUse = preTransitionHandlerInfo && preTransitionHandlerInfo.context;
62953        } else {
62954          // Ideally we should throw this error to provide maximal
62955          // information to the user that not enough context objects
62956          // were provided, but this proves too cumbersome in Ember
62957          // in cases where inner template helpers are evaluated
62958          // before parent helpers un-render, in which cases this
62959          // error somewhat prematurely fires.
62960          //throw new Error("Not enough context objects were provided to complete a transition to " + targetRouteName + ". Specifically, the " + name + " route needs an object that can be serialized into its dynamic URL segments [" + names.join(', ') + "]");
62961          return oldHandlerInfo;
62962        }
62963      }
62964
62965      return _routerHandlerInfoFactory.default('object', {
62966        name: name,
62967        handler: handler,
62968        context: objectToUse,
62969        names: names
62970      });
62971    },
62972
62973    createParamHandlerInfo: function (name, handler, names, objects, oldHandlerInfo) {
62974      var params = {};
62975
62976      // Soak up all the provided string/numbers
62977      var numNames = names.length;
62978      while (numNames--) {
62979
62980        // Only use old params if the names match with the new handler
62981        var oldParams = oldHandlerInfo && name === oldHandlerInfo.name && oldHandlerInfo.params || {};
62982
62983        var peek = objects[objects.length - 1];
62984        var paramName = names[numNames];
62985        if (_routerUtils.isParam(peek)) {
62986          params[paramName] = "" + objects.pop();
62987        } else {
62988          // If we're here, this means only some of the params
62989          // were string/number params, so try and use a param
62990          // value from a previous handler.
62991          if (oldParams.hasOwnProperty(paramName)) {
62992            params[paramName] = oldParams[paramName];
62993          } else {
62994            throw new Error("You didn't provide enough string/numeric parameters to 
62994satisfy all of the dynamic segments for route " + name);
62995          }
62996        }
62997      }
62998
62999      return _routerHandlerInfoFactory.default('param', {
63000        name: name,
63001        handler: handler,
63002        params: params
63003      });
63004    }
63005  });
63006});
63007enifed('router/transition-intent/url-transition-intent', ['exports', 'router/transition-intent', 'router/transition-state', 'router/handler-info/factory', 'router/utils', 'router/unrecognized-url-error'], function (exports, _routerTransitionIntent, _routerTransitionState, _routerHandlerInfoFactory, _routerUtils, _routerUnrecognizedUrlError) {
63008  'use strict';
63009
63010  exports.default = _routerUtils.subclass(_routerTransitionIntent.default, {
63011    url: null,
63012
63013    initialize: function (props) {
63014      this.url = props.url;
63015    },
63016
63017    applyToState: function (oldState, recognizer, getHandler) {
63018      var newState = new _routerTransitionState.default();
63019
63020      var results = recognizer.recognize(this.url),
63021          queryParams = {},
63022          i,
63023          len;
63024
63025      if (!results) {
63026        throw new _routerUnrecognizedUrlError.default(this.url);
63027      }
63028
63029      var statesDiffer = false;
63030
63031      for (i = 0, len = results.length; i < len; ++i) {
63032        var result = results[i];
63033        var name = result.handler;
63034        var handler = getHandler(name);
63035
63036        if (handler.inaccessibleByURL) {
63037          throw new _routerUnrecognizedUrlError.default(this.url);
63038        }
63039
63040        var newHandlerInfo = _routerHandlerInfoFactory.default('param', {
63041          name: name,
63042          handler: handler,
63043          params: result.params
63044        });
63045
63046        var oldHandlerInfo = oldState.handlerInfos[i];
63047        if (statesDiffer || newHandlerInfo.shouldSupercede(oldHandlerInfo)) {
63048          statesDiffer = true;
63049          newState.handlerInfos[i] = newHandlerInfo;
63050        } else {
63051          newState.handlerInfos[i] = oldHandlerInfo;
63052        }
63053      }
63054
63055      _routerUtils.merge(newState.queryParams, results.queryParams);
63056
63057      return newState;
63058    }
63059  });
63060});
63061enifed('router/transition-intent', ['exports', 'router/utils'], function (exports, _routerUtils) {
63062  'use strict';
63063
63064  function TransitionIntent(props) {
63065    this.initialize(props);
63066
63067    // TODO: wat
63068    this.data = this.data || {};
63069  }
63070
63071  TransitionIntent.prototype = {
63072    initialize: null,
63073    applyToState: null
63074  };
63075
63076  exports.default = TransitionIntent;
63077});
63078enifed('router/transition-state', ['exports', 'router/handler-info', 'router/utils', 'rsvp/promise'], function (exports, _routerHandlerInfo, _routerUtils, _rsvpPromise) {
63079  'use strict';
63080
63081  function TransitionState(other) {
63082    this.handlerInfos = [];
63083    this.queryParams = {};
63084    this.params = {};
63085  }
63086
63087  TransitionState.prototype = {
63088    handlerInfos: null,
63089    queryParams: null,
63090    params: null,
63091
63092    promiseLabel: function (label) {
63093      var targetName = '';
63094      _routerUtils.forEach(this.handlerInfos, function (handlerInfo) {
63095        if (targetName !== '') {
63096          targetName += '.';
63097        }
63098        targetName += handlerInfo.name;
63099      });
63100      return _routerUtils.promiseLabel("'" + targetName + "': " + label);
63101    },
63102
63103    resolve: function (shouldContinue, payload) {
63104      var self = this;
63105      // First, calculate params for this state. This is useful
63106      // information to provide to the various route hooks.
63107      var params = this.params;
63108      _routerUtils.forEach(this.handlerInfos, function (handlerInfo) {
63109        params[handlerInfo.name] = handlerInfo.params || {};
63110      });
63111
63112      payload = payload || {};
63113      payload.resolveIndex = 0;
63114
63115      var currentState = this;
63116      var wasAborted = false;
63117
63118      // The prelude RSVP.resolve() asyncs us into the promise land.
63119      return _rsvpPromise.default.resolve(null, this.promiseLabel("Start transition")).then(resolveOneHandlerInfo, null, this.promiseLabel('Resolve handler'))['catch'](handleError, this.promiseLabel('Handle error'));
63120
63121      function innerShouldContinue() {
63122        return _rsvpPromise.default.resolve(shouldContinue(), currentState.promiseLabel("Check if should continue"))['catch'](function (reason) {
63123          // We distinguish between errors that occurred
63124          // during resolution (e.g. beforeModel/model/afterModel),
63125          // and aborts due to a rejecting promise from shouldContinue().
63126          wasAborted = true;
63127          return _rsvpPromise.default.reject(reason);
63128        }, currentState.promiseLabel("Handle abort"));
63129      }
63130
63131      function handleError(error) {
63132        // This is the only possible
63133        // reject value of TransitionState#resolve
63134        var handlerInfos = currentState.handlerInfos;
63135        var errorHandlerIndex = payload.resolveIndex >= handlerInfos.length ? handlerInfos.length - 1 : payload.resolveIndex;
63136        return _rsvpPromise.default.reject({
63137          error: error,
63138          handlerWithError: currentState.handlerInfos[errorHandlerIndex].handler,
63139          wasAborted: wasAborted,
63140          state: currentState
63141        });
63142      }
63143
63144      function proceed(resolvedHandlerInfo) {
63145        var wasAlreadyResolved = currentState.handlerInfos[payload.resolveIndex].isResolved;
63146
63147        // Swap the previously unresolved handlerInfo with
63148        // the resolved handlerInfo
63149        currentState.handlerInfos[payload.resolveIndex++] = resolvedHandlerInfo;
63150
63151        if (!wasAlreadyResolved) {
63152          // Call the redirect hook. The reason we call it here
63153          // vs. afterModel is so that redirects into child
63154          // routes don't re-run the model hooks for this
63155          // already-resolved route.
63156          var handler = resolvedHandlerInfo.handler;
63157          _routerUtils.callHook(handler, 'redirect', resolvedHandlerInfo.context, payload);
63158        }
63159
63160        // Proceed after ensuring that the redirect hook
63161        // didn't abort this transition by transitioning elsewhere.
63162        return innerShouldContinue().then(resolveOneHandlerInfo, null, currentState.promiseLabel('Resolve handler'));
63163      }
63164
63165      function resolveOneHandlerInfo() {
63166        if (payload.resolveIndex === currentState.handlerInfos.length) {
63167          // This is is the only possible
63168          // fulfill value of TransitionState#resolve
63169          return {
63170            error: null,
63171            state: currentState
63172          };
63173        }
63174
63175        var handlerInfo = currentState.handlerInfos[payload.resolveIndex];
63176
63177        return handlerInfo.resolve(innerShouldContinue, payload).then(proceed, null, currentState.promiseLabel('Proceed'));
63178      }
63179    }
63180  };
63181
63182  exports.default = TransitionState;
63183});
63184enifed('router/transition', ['exports', 'rsvp/promise', 'router/handler-info', 'router/utils'], function (exports, _rsvpPromise, _routerHandlerInfo, _routerUtils) {
63185  'use strict';
63186
63187  /**
63188    @private
63189  
63190    A Transition is a thennable (a promise-like object) that represents
63191    an attempt to transition to another route. It can be aborted, either
63192    explicitly via `abort` or by attempting another transition while a
63193    previous one is still underway. An aborted transition can also
63194    be `retry()`d later.
63195   */
63196  function Transition(router, intent, state, error) {
63197    var transition = this;
63198    this.state = state || router.state;
63199    this.intent = intent;
63200    this.router = router;
63201    this.data = this.intent && this.intent.data || {};
63202    this.resolvedModels = {};
63203    this.queryParams = {};
63204
63205    if (error) {
63206      this.promise = _rsvpPromise.default.reject(error);
63207      this.error = error;
63208      return;
63209    }
63210
63211    if (state) {
63212      this.params = state.params;
63213      this.queryParams = state.queryParams;
63214      this.handlerInfos = state.handlerInfos;
63215
63216      var len = state.handlerInfos.length;
63217      if (len) {
63218        this.targetName = state.handlerInfos[len - 1].name;
63219      }
63220
63221      for (var i = 0; i < len; ++i) {
63222        var handlerInfo = state.handlerInfos[i];
63223
63224        // TODO: this all seems hacky
63225        if (!handlerInfo.isResolved) {
63226          break;
63227        }
63228        this.pivotHandler = handlerInfo.handler;
63229      }
63230
63231      this.sequence = Transition.currentSequence++;
63232      this.promise = state.resolve(checkForAbort, this)['catch'](function (result) {
63233        if (result.wasAborted || transition.isAborted) {
63234          return _rsvpPromise.default.reject(logAbort(transition));
63235        } else {
63236          transition.trigger('error', result.error, transition, result.handlerWithError);
63237          transition.abort();
63238          return _rsvpPromise.default.reject(result.error);
63239        }
63240      }, _routerUtils.promiseLabel('Handle Abort'));
63241    } else {
63242      this.promise = _rsvpPromise.default.resolve(this.state);
63243      this.params = {};
63244    }
63245
63246    function checkForAbort() {
63247      if (transition.isAborted) {
63248        return _rsvpPromise.default.reject(undefined, _routerUtils.promiseLabel("Transition aborted - reject"));
63249      }
63250    }
63251  }
63252
63253  Transition.currentSequence = 0;
63254
63255  Transition.prototype = {
63256    targetName: null,
63257    urlMethod: 'update',
63258    intent: null,
63259    params: null,
63260    pivotHandler: null,
63261    resolveIndex: 0,
63262    handlerInfos: null,
63263    resolvedModels: null,
63264    isActive: true,
63265    state: null,
63266    queryParamsOnly: false,
63267
63268    isTransition: true,
63269
63270    isExiting: function (handler) {
63271      var handlerInfos = this.handlerInfos;
63272      for (var i = 0, len = handlerInfos.length; i < len; ++i) {
63273        var handlerInfo = handlerInfos[i];
63274        if (handlerInfo.name === handler || handlerInfo.handler === handler) {
63275          return false;
63276        }
63277      }
63278      return true;
63279    },
63280
63281    /**
63282      @public
63283       The Transition's internal promise. Calling `.then` on this property
63284      is that same as calling `.then` on the Transition object itself, but
63285      this property is exposed for when you want to pass around a
63286      Transition's promise, but not the Transition object itself, since
63287      Transition object can be externally `abort`ed, while the promise
63288      cannot.
63289     */
63290    promise: null,
63291
63292    /**
63293      @public
63294       Custom state can be stored on a Transition's `data` object.
63295      This can be useful for decorating a Transition within an earlier
63296      hook and shared with a later hook. Properties set on `data` will
63297      be copied to new transitions generated by calling `retry` on this
63298      transition.
63299     */
63300    data: null,
63301
63302    /**
63303      @public
63304       A standard promise hook that resolves if the transition
63305      succeeds and rejects if it fails/redirects/aborts.
63306       Forwards to the internal `promise` property which you can
63307      use in situations where you want to pass around a thennable,
63308      but not the Transition itself.
63309       @param {Function} onFulfilled
63310      @param {Function} onRejected
63311      @param {String} label optional string for labeling the promise.
63312      Useful for tooling.
63313      @return {Promise}
63314     */
63315    then: function (onFulfilled, onRejected, label) {
63316      return this.promise.then(onFulfilled, onRejected, label);
63317    },
63318
63319    /**
63320      @public
63321       Forwards to the internal `promise` property which you can
63322      use in situations where you want to pass around a thennable,
63323      but not the Transition itself.
63324       @method catch
63325      @param {Function} onRejection
63326      @param {String} label optional string for labeling the promise.
63327      Useful for tooling.
63328      @return {Promise}
63329     */
63330    catch: function (onRejection, label) {
63331      return this.promise.catch(onRejection, label);
63332    },
63333
63334    /**
63335      @public
63336       Forwards to the internal `promise` property which you can
63337      use in situations where you want to pass around a thennable,
63338      but not the Transition itself.
63339       @method finally
63340      @param {Function} callback
63341      @param {String} label optional string for labeling the promise.
63342      Useful for tooling.
63343      @return {Promise}
63344     */
63345    finally: function (callback, label) {
63346      return this.promise.finally(callback, label);
63347    },
63348
63349    /**
63350      @public
63351       Aborts the Transition. Note you can also implicitly abort a transition
63352      by initiating another transition while a previous one is underway.
63353     */
63354    abort: function () {
63355      if (this.isAborted) {
63356        return this;
63357      }
63358      _routerUtils.log(this.router, this.sequence, this.targetName + ": transition was aborted");
63359      this.intent.preTransitionState = this.router.state;
63360      this.isAborted = true;
63361      this.isActive = false;
63362      this.router.activeTransition = null;
63363      return this;
63364    },
63365
63366    /**
63367      @public
63368       Retries a previously-aborted transition (making sure to abort the
63369      transition if it's still active). Returns a new transition that
63370      represents the new attempt to transition.
63371     */
63372    retry: function () {
63373      // TODO: add tests for merged state retry()s
63374      this.abort();
63375      return this.router.transitionByIntent(this.intent, false);
63376    },
63377
63378    /**
63379      @public
63380       Sets the URL-changing method to be employed at the end of a
63381      successful transition. By default, a new Transition will just
63382      use `updateURL`, but passing 'replace' to this method will
63383      cause the URL to update using 'replaceWith' instead. Omitting
63384      a parameter will disable the URL change, allowing for transitions
63385      that don't update the URL at completion (this is also used for
63386      handleURL, since the URL has already changed before the
63387      transition took place).
63388       @param {String} method the type of URL-changing method to use
63389        at the end of a transition. Accepted values are 'replace',
63390        falsy values, or any other non-falsy value (which is
63391        interpreted as an updateURL transition).
63392       @return {Transition} this transition
63393     */
63394    method: function (method) {
63395      this.urlMethod = method;
63396      return this;
63397    },
63398
63399    /**
63400      @public
63401       Fires an event on the current list of resolved/resolving
63402      handlers within this transition. Useful for firing events
63403      on route hierarchies that haven't fully been entered yet.
63404       Note: This method is also aliased as `send`
63405       @param {Boolean} [ignoreFailure=false] a boolean specifying whether unhandled events throw an error
63406      @param {String} name the name of the event to fire
63407     */
63408    trigger: function (ignoreFailure) {
63409      var args = _routerUtils.slice.call(arguments);
63410      if (typeof ignoreFailure === 'boolean') {
63411        args.shift();
63412      } else {
63413        // Throw errors on unhandled trigger events by default
63414        ignoreFailure = false;
63415      }
63416      _routerUtils.trigger(this.router, this.state.handlerInfos.slice(0, this.resolveIndex + 1), ignoreFailure, args);
63417    },
63418
63419    /**
63420      @public
63421       Transitions are aborted and their promises rejected
63422      when redirects occur; this method returns a promise
63423      that will follow any redirects that occur and fulfill
63424      with the value fulfilled by any redirecting transitions
63425      that occur.
63426       @return {Promise} a promise that fulfills with the same
63427        value that the final redirecting transition fulfills with
63428     */
63429    followRedirects: function () {
63430      var router = this.router;
63431      return this.promise['catch'](function (reason) {
63432        if (router.activeTransition) {
63433          return router.activeTransition.followRedirects();
63434        }
63435        return _rsvpPromise.default.reject(reason);
63436      });
63437    },
63438
63439    toString: function () {
63440      return "Transition (sequence " + this.sequence + ")";
63441    },
63442
63443    /**
63444      @private
63445     */
63446    log: function (message) {
63447      _routerUtils.log(this.router, this.sequence, message);
63448    }
63449  };
63450
63451  // Alias 'trigger' as 'send'
63452  Transition.prototype.send = Transition.prototype.trigger;
63453
63454  /**
63455    @private
63456  
63457    Logs and returns a TransitionAborted error.
63458   */
63459  function logAbort(transition) {
63460    _routerUtils.log(transition.router, transition.sequence, "detected abort.");
63461    return new TransitionAborted();
63462  }
63463
63464  function TransitionAborted(message) {
63465    this.message = message || "TransitionAborted";
63466    this.name = "TransitionAborted";
63467  }
63468
63469  exports.Transition = Transition;
63470  exports.logAbort = logAbort;
63471  exports.TransitionAborted = TransitionAborted;
63472});
63473enifed("router/unrecognized-url-error", ["exports", "router/utils"], function (exports, _routerUtils) {
63474  "use strict";
63475
63476  /**
63477    Promise reject reasons passed to promise rejection
63478    handlers for failed transitions.
63479   */
63480  function UnrecognizedURLError(message) {
63481    this.message = message || "UnrecognizedURLError";
63482    this.name = "UnrecognizedURLError";
63483    Error.call(this);
63484  }
63485
63486  UnrecognizedURLError.prototype = _routerUtils.oCreate(Error.prototype);
63487
63488  exports.default = UnrecognizedURLError;
63489});
63490enifed('router/utils', ['exports'], function (exports) {
63491  'use strict';
63492
63493  exports.extractQueryParams = extractQueryParams;
63494  exports.log = log;
63495  exports.bind = bind;
63496  exports.forEach = forEach;
63497  exports.trigger = trigger;
63498  exports.getChangelist = getChangelist;
63499  exports.promiseLabel = promiseLabel;
63500  exports.subclass = subclass;
63501  var slice = Array.prototype.slice;
63502
63503  var _isArray;
63504  if (!Array.isArray) {
63505    _isArray = function (x) {
63506      return Object.prototype.toString.call(x) === "[object Array]";
63507    };
63508  } else {
63509    _isArray = Array.isArray;
63510  }
63511
63512  var isArray = _isArray;
63513
63514  exports.isArray = isArray;
63515  function merge(hash, other) {
63516    for (var prop in other) {
63517      if (other.hasOwnProperty(prop)) {
63518        hash[prop] = other[prop];
63519      }
63520    }
63521  }
63522
63523  var oCreate = Object.create || function (proto) {
63524    function F() {}
63525    F.prototype = proto;
63526    return new F();
63527  };
63528
63529  exports.oCreate = oCreate;
63530  /**
63531    @private
63532  
63533    Extracts query params from the end of an array
63534  **/
63535
63536  function extractQueryParams(array) {
63537    var len = array && array.length,
63538        head,
63539        queryParams;
63540
63541    if (len && len > 0 && array[len - 1] && array[len - 1].hasOwnProperty('queryParams')) {
63542      queryParams = array[len - 1].queryParams;
63543      head = slice.call(array, 0, len - 1);
63544      return [head, queryParams];
63545    } else {
63546      return [array, null];
63547    }
63548  }
63549
63550  /**
63551    @private
63552  
63553    Coerces query param properties and array elements into strings.
63554  **/
63555  function coerceQueryParamsToString(queryParams) {
63556    for (var key in queryParams) {
63557      if (typeof queryParams[key] === 'number') {
63558        queryParams[key] = '' + queryParams[key];
63559      } else if (isArray(queryParams[key])) {
63560        for (var i = 0, l = queryParams[key].length; i < l; i++) {
63561          queryParams[key][i] = '' + queryParams[key][i];
63562        }
63563      }
63564    }
63565  }
63566  /**
63567    @private
63568   */
63569
63570  function log(router, sequence, msg) {
63571    if (!router.log) {
63572      return;
63573    }
63574
63575    if (arguments.length === 3) {
63576      router.log("Transition #" + sequence + ": " + msg);
63577    } else {
63578      msg = sequence;
63579      router.log(msg);
63580    }
63581  }
63582
63583  function bind(context, fn) {
63584    var boundArgs = arguments;
63585    return function (value) {
63586      var args = slice.call(boundArgs, 2);
63587      args.push(value);
63588      return fn.apply(context, args);
63589    };
63590  }
63591
63592  function isParam(object) {
63593    return typeof object === "string" || object instanceof String || typeof object === "number" || object instanceof Number;
63594  }
63595
63596  function forEach(array, callback) {
63597    for (var i = 0, l = array.length; i < l && false !== callback(array[i]); i++) {}
63598  }
63599
63600  function trigger(router, handlerInfos, ignoreFailure, args) {
63601    if (router.triggerEvent) {
63602      router.triggerEvent(handlerInfos, ignoreFailure, args);
63603      return;
63604    }
63605
63606    var name = args.shift();
63607
63608    if (!handlerInfos) {
63609      if (ignoreFailure) {
63610        return;
63611      }
63612      throw new Error("Could not trigger event '" + name + "'. There are no active handlers");
63613    }
63614
63615    var eventWasHandled = false;
63616
63617    for (var i = handlerInfos.length - 1; i >= 0; i--) {
63618      var handlerInfo = handlerInfos[i],
63619          handler = handlerInfo.handler;
63620
63621      if (handler.events && handler.events[name]) {
63622        if (handler.events[name].apply(handler, args) === true) {
63623          eventWasHandled = true;
63624        } else {
63625          return;
63626        }
63627      }
63628    }
63629
63630    if (!eventWasHandled && !ignoreFailure) {
63631      throw new Error("Nothing handled the event '" + name + "'.");
63632    }
63633  }
63634
63635  function getChangelist(oldObject, newObject) {
63636    var key;
63637    var results = {
63638      all: {},
63639      changed: {},
63640      removed: {}
63641    };
63642
63643    merge(results.all, newObject);
63644
63645    var didChange = false;
63646    coerceQueryParamsToString(oldObject);
63647    coerceQueryParamsToString(newObject);
63648
63649    // Calculate removals
63650    for (key in oldObject) {
63651      if (oldObject.hasOwnProperty(key)) {
63652        if (!newObject.hasOwnProperty(key)) {
63653          didChange = true;
63654          results.removed[key] = oldObject[key];
63655        }
63656      }
63657    }
63658
63659    // Calculate changes
63660    for (key in newObject) {
63661      if (newObject.hasOwnProperty(key)) {
63662        if (isArray(oldObject[key]) && isArray(newObject[key])) {
63663          if (oldObject[key].length !== newObject[key].length) {
63664            results.changed[key] = newObject[key];
63665            didChange = true;
63666          } else {
63667            for (var i = 0, l = oldObject[key].length; i < l; i++) {
63668              if (oldObject[key][i] !== newObject[key][i]) {
63669                results.changed[key] = newObject[key];
63670                didChange = true;
63671              }
63672            }
63673          }
63674        } else {
63675          if (oldObject[key] !== newObject[key]) {
63676            results.changed[key] = newObject[key];
63677            didChange = true;
63678          }
63679        }
63680      }
63681    }
63682
63683    return didChange && results;
63684  }
63685
63686  function promiseLabel(label) {
63687    return 'Router: ' + label;
63688  }
63689
63690  function subclass(parentConstructor, proto) {
63691    function C(props) {
63692      parentConstructor.call(this, props || {});
63693    }
63694    C.prototype = oCreate(parentConstructor.prototype);
63695    merge(C.prototype, proto);
63696    return C;
63697  }
63698
63699  function resolveHook(obj, hookName) {
63700    if (!obj) {
63701      return;
63702    }
63703    var underscored = "_" + hookName;
63704    return obj[underscored] && underscored || obj[hookName] && hookName;
63705  }
63706
63707  function callHook(obj, _hookName, arg1, arg2) {
63708    var hookName = resolveHook(obj, _hookName);
63709    return hookName && obj[hookName].call(obj, arg1, arg2);
63710  }
63711
63712  function applyHook(obj, _hookName, args) {
63713    var hookName = resolveHook(obj, _hookName);
63714    if (hookName) {
63715      if (args.length === 0) {
63716        return obj[hookName].call(obj);
63717      } else if (args.length === 1) {
63718        return obj[hookName].call(obj, args[0]);
63719      } else if (args.length === 2) {
63720        return obj[hookName].call(obj, args[0], args[1]);
63721      } else {
63722        return obj[hookName].apply(obj, args);
63723      }
63724    }
63725  }
63726
63727  exports.merge = merge;
63728  exports.slice = slice;
63729  exports.isParam = isParam;
63730  exports.coerceQueryParamsToString = coerceQueryParamsToString;
63731  exports.callHook = callHook;
63732  exports.resolveHook = resolveHook;
63733  exports.applyHook = applyHook;
63734});
63735enifed('router', ['exports', 'router/router'], function (exports, _routerRouter) {
63736  'use strict';
63737
63738  exports.default = _routerRouter.default;
63739});
63740enifed('rsvp/-internal', ['exports', 'rsvp/utils', 'rsvp/instrument', 'rsvp/config'], function (exports, _rsvpUtils, _rsvpInstrument, _rsvpConfig) {
63741  'use strict';
63742
63743  function withOwnPromise() {
63744    return new TypeError('A promises callback cannot return that same promise.');
63745  }
63746
63747  function noop() {}
63748
63749  var PENDING = void 0;
63750  var FULFILLED = 1;
63751  var REJECTED = 2;
63752
63753  var GET_THEN_ERROR = new ErrorObject();
63754
63755  function getThen(promise) {
63756    try {
63757      return promise.then;
63758    } catch (error) {
63759      GET_THEN_ERROR.error = error;
63760      return GET_THEN_ERROR;
63761    }
63762  }
63763
63764  function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
63765    try {
63766      then.call(value, fulfillmentHandler, rejectionHandler);
63767    } catch (e) {
63768      return e;
63769    }
63770  }
63771
63772  function handleForeignThenable(promise, thenable, then) {
63773    _rsvpConfig.config.async(function (promise) {
63774      var sealed = false;
63775      var error = tryThen(then, thenable, function (value) {
63776        if (sealed) {
63777          return;
63778        }
63779        sealed = true;
63780        if (thenable !== value) {
63781          resolve(promise, value);
63782        } else {
63783          fulfill(promise, value);
63784        }
63785      }, function (reason) {
63786        if (sealed) {
63787          return;
63788        }
63789        sealed = true;
63790
63791        reject(promise, reason);
63792      }, 'Settle: ' + (promise._label || ' unknown promise'));
63793
63794      if (!sealed && error) {
63795        sealed = true;
63796        reject(promise, error);
63797      }
63798    }, promise);
63799  }
63800
63801  function handleOwnThenable(promise, thenable) {
63802    if (thenable._state === FULFILLED) {
63803      fulfill(promise, thenable._result);
63804    } else if (thenable._state === REJECTED) {
63805      thenable._onError = null;
63806      reject(promise, thenable._result);
63807    } else {
63808      subscribe(thenable, undefined, function (value) {
63809        if (thenable !== value) {
63810          resolve(promise, value);
63811        } else {
63812          fulfill(promise, value);
63813        }
63814      }, function (reason) {
63815        reject(promise, reason);
63816      });
63817    }
63818  }
63819
63820  function handleMaybeThenable(promise, maybeThenable) {
63821    if (maybeThenable.constructor === promise.constructor) {
63822      handleOwnThenable(promise, maybeThenable);
63823    } else {
63824      var then = getThen(maybeThenable);
63825
63826      if (then === GET_THEN_ERROR) {
63827        reject(promise, GET_THEN_ERROR.error);
63828      } else if (then === undefined) {
63829        fulfill(promise, maybeThenable);
63830      } else if (_rsvpUtils.isFunction(then)) {
63831        handleForeignThenable(promise, maybeThenable, then);
63832      } else {
63833        fulfill(promise, maybeThenable);
63834      }
63835    }
63836  }
63837
63838  function resolve(promise, value) {
63839    if (promise === value) {
63840      fulfill(promise, value);
63841    } else if (_rsvpUtils.objectOrFunction(value)) {
63842      handleMaybeThenable(promise, value);
63843    } else {
63844      fulfill(promise, value);
63845    }
63846  }
63847
63848  function publishRejection(promise) {
63849    if (promise._onError) {
63850      promise._onError(promise._result);
63851    }
63852
63853    publish(promise);
63854  }
63855
63856  function fulfill(promise, value) {
63857    if (promise._state !== PENDING) {
63858      return;
63859    }
63860
63861    promise._result = value;
63862    promise._state = FULFILLED;
63863
63864    if (promise._subscribers.length === 0) {
63865      if (_rsvpConfig.config.instrument) {
63866        _rsvpInstrument.default('fulfilled', promise);
63867      }
63868    } else {
63869      _rsvpConfig.config.async(publish, promise);
63870    }
63871  }
63872
63873  function reject(promise, reason) {
63874    if (promise._state !== PENDING) {
63875      return;
63876    }
63877    promise._state = REJECTED;
63878    promise._result = reason;
63879    _rsvpConfig.config.async(publishRejection, promise);
63880  }
63881
63882  function subscribe(parent, child, onFulfillment, onRejection) {
63883    var subscribers = parent._subscribers;
63884    var length = subscribers.length;
63885
63886    parent._onError = null;
63887
63888    subscribers[length] = child;
63889    subscribers[length + FULFILLED] = onFulfillment;
63890    subscribers[length + REJECTED] = onRejection;
63891
63892    if (length === 0 && parent._state) {
63893      _rsvpConfig.config.async(publish, parent);
63894    }
63895  }
63896
63897  function publish(promise) {
63898    var subscribers = promise._subscribers;
63899    var settled = promise._state;
63900
63901    if (_rsvpConfig.config.instrument) {
63902      _rsvpInstrument.default(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
63903    }
63904
63905    if (subscribers.length === 0) {
63906      return;
63907    }
63908
63909    var child,
63910        callback,
63911        detail = promise._result;
63912
63913    for (var i = 0; i < subscribers.length; i += 3) {
63914      child = subscribers[i];
63915      callback = subscribers[i + settled];
63916
63917      if (child) {
63918        invokeCallback(settled, child, callback, detail);
63919      } else {
63920        callback(detail);
63921      }
63922    }
63923
63924    promise._subscribers.length = 0;
63925  }
63926
63927  function ErrorObject() {
63928    this.error = null;
63929  }
63930
63931  var TRY_CATCH_ERROR = new ErrorObject();
63932
63933  function tryCatch(callback, detail) {
63934    try {
63935      return callback(detail);
63936    } catch (e) {
63937      TRY_CATCH_ERROR.error = e;
63938      return TRY_CATCH_ERROR;
63939    }
63940  }
63941
63942  function invokeCallback(settled, promise, callback, detail) {
63943    var hasCallback = _rsvpUtils.isFunction(callback),
63944        value,
63945        error,
63946        succeeded,
63947        failed;
63948
63949    if (hasCallback) {
63950      value = tryCatch(callback, detail);
63951
63952      if (value === TRY_CATCH_ERROR) {
63953        failed = true;
63954        error = value.error;
63955        value = null;
63956      } else {
63957        succeeded = true;
63958      }
63959
63960      if (promise === value) {
63961        reject(promise, withOwnPromise());
63962        return;
63963      }
63964    } else {
63965      value = detail;
63966      succeeded = true;
63967    }
63968
63969    if (promise._state !== PENDING) {
63970      // noop
63971    } else if (hasCallback && succeeded) {
63972        resolve(promise, value);
63973      } else if (failed) {
63974        reject(promise, error);
63975      } else if (settled === FULFILLED) {
63976        fulfill(promise, value);
63977      } else if (settled === REJECTED) {
63978        reject(promise, value);
63979      }
63980  }
63981
63982  function initializePromise(promise, resolver) {
63983    var resolved = false;
63984    try {
63985      resolver(function resolvePromise(value) {
63986        if (resolved) {
63987          return;
63988        }
63989        resolved = true;
63990        resolve(promise, value);
63991      }, function rejectPromise(reason) {
63992        if (resolved) {
63993          return;
63994        }
63995        resolved = true;
63996        reject(promise, reason);
63997      });
63998    } catch (e) {
63999      reject(promise, e);
64000    }
64001  }
64002
64003  exports.noop = noop;
64004  exports.resolve = resolve;
64005  exports.reject = reject;
64006  exports.fulfill = fulfill;
64007  exports.subscribe = subscribe;
64008  exports.publish = publish;
64009  exports.publishRejection = publishRejection;
64010  exports.initializePromise = initializePromise;
64011  exports.invokeCallback = invokeCallback;
64012  exports.FULFILLED = FULFILLED;
64013  exports.REJECTED = REJECTED;
64014  exports.PENDING = PENDING;
64015});
64016enifed('rsvp/all-settled', ['exports', 'rsvp/enumerator', 'rsvp/promise', 'rsvp/utils'], function (exports, _rsvpEnumerator, _rsvpPromise, _rsvpUtils) {
64017  'use strict';
64018
64019  exports.default = allSettled;
64020
64021  function AllSettled(Constructor, entries, label) {
64022    this._superConstructor(Constructor, entries, false, /* don't abort on reject */label);
64023  }
64024
64025  AllSettled.prototype = _rsvpUtils.o_create(_rsvpEnumerator.default.prototype);
64026  AllSettled.prototype._superConstructor = _rsvpEnumerator.default;
64027  AllSettled.prototype._makeResult = _rsvpEnumerator.makeSettledResult;
64028  AllSettled.prototype._validationError = function () {
64029    return new Error('allSettled must be called with an array');
64030  };
64031
64032  /**
64033    `RSVP.allSettled` is similar to `RSVP.all`, but instead of implementing
64034    a fail-fast method, it waits until all the promises have returned and
64035    shows you all the results. This is useful if you want to handle multiple
64036    promises' failure states together as a set.
64037  
64038    Returns a promise that is fulfilled when all the given promises have been
64039    settled. The return promise is fulfilled with an array of the states of
64040    the promises passed into the `promises` array argument.
64041  
64042    Each state object will either indicate fulfillment or rejection, and
64043    provide the corresponding value or reason. The states will take one of
64044    the following formats:
64045  
64046    ```javascript
64047    { state: 'fulfilled', value: value }
64048      or
64049    { state: 'rejected', reason: reason }
64050    ```
64051  
64052    Example:
64053  
64054    ```javascript
64055    var promise1 = RSVP.Promise.resolve(1);
64056    var promise2 = RSVP.Promise.reject(new Error('2'));
64057    var promise3 = RSVP.Promise.reject(new Error('3'));
64058    var promises = [ promise1, promise2, promise3 ];
64059  
64060    RSVP.allSettled(promises).then(function(array){
64061      // array == [
64062      //   { state: 'fulfilled', value: 1 },
64063      //   { state: 'rejected', reason: Error },
64064      //   { state: 'rejected', reason: Error }
64065      // ]
64066      // Note that for the second item, reason.message will be '2', and for the
64067      // third item, reason.message will be '3'.
64068    }, function(error) {
64069      // Not run. (This block would only be called if allSettled had failed,
64070      // for instance if passed an incorrect argument type.)
64071    });
64072    ```
64073  
64074    @method allSettled
64075    @static
64076    @for RSVP
64077    @param {Array} entries
64078    @param {String} label - optional string that describes the promise.
64079    Useful for tooling.
64080    @return {Promise} promise that is fulfilled with an array of the settled
64081    states of the constituent promises.
64082  */
64083
64084  function allSettled(entries, label) {
64085    return new AllSettled(_rsvpPromise.default, entries, label).promise;
64086  }
64087});
64088enifed("rsvp/all", ["exports", "rsvp/promise"], function (exports, _rsvpPromise) {
64089  "use strict";
64090
64091  exports.default = all;
64092
64093  /**
64094    This is a convenient alias for `RSVP.Promise.all`.
64095  
64096    @method all
64097    @static
64098    @for RSVP
64099    @param {Array} array Array of promises.
64100    @param {String} label An optional label. This is useful
64101    for tooling.
64102  */
64103
64104  function all(array, label) {
64105    return _rsvpPromise.default.all(array, label);
64106  }
64107});
64108enifed('rsvp/asap', ['exports'], function (exports) {
64109  'use strict';
64110
64111  exports.default = asap;
64112  var len = 0;
64113  var toString = ({}).toString;
64114  var vertxNext;
64115
64116  function asap(callback, arg) {
64117    queue[len] = callback;
64118    queue[len + 1] = arg;
64119    len += 2;
64120    if (len === 2) {
64121      // If len is 1, that means that we need to schedule an async flush.
64122      // If additional callbacks are queued before the queue is flushed, they
64123      // will be processed by this flush that we are scheduling.
64124      scheduleFlush();
64125    }
64126  }
64127
64128  var browserWindow = typeof window !== 'undefined' ? window : undefined;
64129  var browserGlobal = browserWindow || {};
64130  var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
64131  var isNode = typeof window === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';
64132
64133  // test for web worker but not in IE10
64134  var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
64135
64136  // node
64137  function useNextTick() {
64138    var nextTick = process.nextTick;
64139    // node version 0.10.x displays a deprecation warning when nextTick is used recursively
64140    // setImmediate should be used instead instead
64141    var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
64142    if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
64143      nextTick = setImmediate;
64144    }
64145    return function () {
64146      nextTick(flush);
64147    };
64148  }
64149
64150  // vertx
64151  function useVertxTimer() {
64152    return function () {
64153      vertxNext(flush);
64154    };
64155  }
64156
64157  function useMutationObserver() {
64158    var iterations = 0;
64159    var observer = new BrowserMutationObserver(flush);
64160    var node = document.createTextNode('');
64161    observer.observe(node, { characterData: true });
64162
64163    return function () {
64164      node.data = iterations = ++iterations % 2;
64165    };
64166  }
64167
64168  // web worker
64169  function useMessageChannel() {
64170    var channel = new MessageChannel();
64171    channel.port1.onmessage = flush;
64172    return function () {
64173      channel.port2.postMessage(0);
64174    };
64175  }
64176
64177  function useSetTimeout() {
64178    return function () {
64179      setTimeout(flush, 1);
64180    };
64181  }
64182
64183  var queue = new Array(1000);
64184  function flush() {
64185    for (var i = 0; i < len; i += 2) {
64186      var callback = queue[i];
64187      var arg = queue[i + 1];
64188
64189      callback(arg);
64190
64191      queue[i] = undefined;
64192      queue[i + 1] = undefined;
64193    }
64194
64195    len = 0;
64196  }
64197
64198  function attemptVertex() {
64199    try {
64200      var r = require;
64201      var vertx = r('vertx');
64202      vertxNext = vertx.runOnLoop || vertx.runOnContext;
64203      return useVertxTimer();
64204    } catch (e) {
64205      return useSetTimeout();
64206    }
64207  }
64208
64209  var scheduleFlush;
64210  // Decide what async method to use to triggering processing of queued callbacks:
64211  if (isNode) {
64212    scheduleFlush = useNextTick();
64213  } else if (BrowserMutationObserver) {
64214    scheduleFlush = useMutationObserver();
64215  } else if (isWorker) {
64216    scheduleFlush = useMessageChannel();
64217  } else if (browserWindow === undefined && typeof require === 'function') {
64218    scheduleFlush = attemptVertex();
64219  } else {
64220    scheduleFlush = useSetTimeout();
64221  }
64222});
64223enifed('rsvp/config', ['exports', 'rsvp/events'], function (exports, _rsvpEvents) {
64224  'use strict';
64225
64226  var config = {
64227    instrument: false
64228  };
64229
64230  _rsvpEvents.default['mixin'](config);
64231
64232  function configure(name, value) {
64233    if (name === 'onerror') {
64234      // handle for legacy users that expect the actual
64235      // error to be passed to their function added via
64236      // `RSVP.configure('onerror', someFunctionHere);`
64237      config['on']('error', value);
64238      return;
64239    }
64240
64241    if (arguments.length === 2) {
64242      config[name] = value;
64243    } else {
64244      return config[name];
64245    }
64246  }
64247
64248  exports.config = config;
64249  exports.configure = configure;
64250});
64251enifed('rsvp/defer', ['exports', 'rsvp/promise'], function (exports, _rsvpPromise) {
64252  'use strict';
64253
64254  exports.default = defer;
64255
64256  /**
64257    `RSVP.defer` returns an object similar to jQuery's `$.Deferred`.
64258    `RSVP.defer` should be used when porting over code reliant on `$.Deferred`'s
64259    interface. New code should use the `RSVP.Promise` constructor instead.
64260  
64261    The object returned from `RSVP.defer` is a plain object with three properties:
64262  
64263    * promise - an `RSVP.Promise`.
64264    * reject - a function that causes the `promise` property on this object to
64265      become rejected
64266    * resolve - a function that causes the `promise` property on this object to
64267      become fulfilled.
64268  
64269    Example:
64270  
64271     ```javascript
64272     var deferred = RSVP.defer();
64273  
64274     deferred.resolve("Success!");
64275  
64276     deferred.promise.then(function(value){
64277       // value here is "Success!"
64278     });
64279     ```
64280  
64281    @method defer
64282    @static
64283    @for RSVP
64284    @param {String} label optional string for labeling the promise.
64285    Useful for tooling.
64286    @return {Object}
64287   */
64288
64289  function defer(label) {
64290    var deferred = {};
64291
64292    deferred['promise'] = new _rsvpPromise.default(function (resolve, reject) {
64293      deferred['resolve'] = resolve;
64294      deferred['reject'] = reject;
64295    }, label);
64296
64297    return deferred;
64298  }
64299});
64300enifed('rsvp/enumerator', ['exports', 'rsvp/utils', 'rsvp/-internal'], function (exports, _rsvpUtils, _rsvpInternal) {
64301  'use strict';
64302
64303  exports.makeSettledResult = makeSettledResult;
64304
64305  function makeSettledResult(state, position, value) {
64306    if (state === _rsvpInternal.FULFILLED) {
64307      return {
64308        state: 'fulfilled',
64309        value: value
64310      };
64311    } else {
64312      return {
64313        state: 'rejected',
64314        reason: value
64315      };
64316    }
64317  }
64318
64319  function Enumerator(Constructor, input, abortOnReject, label) {
64320    var enumerator = this;
64321
64322    enumerator._instanceConstructor = Constructor;
64323    enumerator.promise = new Constructor(_rsvpInternal.noop, label);
64324    enumerator._abortOnReject = abortOnReject;
64325
64326    if (enumerator._validateInput(input)) {
64327      enumerator._input = input;
64328      enumerator.length = input.length;
64329      enumerator._remaining = input.length;
64330
64331      enumerator._init();
64332
64333      if (enumerator.length === 0) {
64334        _rsvpInternal.fulfill(enumerator.promise, enumerator._result);
64335      } else {
64336        enumerator.length = enumerator.length || 0;
64337        enumerator._enumerate();
64338        if (enumerator._remaining === 0) {
64339          _rsvpInternal.fulfill(enumerator.promise, enumerator._result);
64340        }
64341      }
64342    } else {
64343      _rsvpInternal.reject(enumerator.promise, enumerator._validationError());
64344    }
64345  }
64346
64347  exports.default = Enumerator;
64348
64349  Enumerator.prototype._validateInput = function (input) {
64350    return _rsvpUtils.isArray(input);
64351  };
64352
64353  Enumerator.prototype._validationError = function () {
64354    return new Error('Array Methods must be provided an Array');
64355  };
64356
64357  Enumerator.prototype._init = function () {
64358    this._result = new Array(this.length);
64359  };
64360
64361  Enumerator.prototype._enumerate = function () {
64362    var enumerator = this;
64363    var length = enumerator.length;
64364    var promise = enumerator.promise;
64365    var input = enumerator._input;
64366
64367    for (var i = 0; promise._state === _rsvpInternal.PENDING && i < length; i++) {
64368      enumerator._eachEntry(input[i], i);
64369    }
64370  };
64371
64372  Enumerator.prototype._eachEntry = function (entry, i) {
64373    var enumerator = this;
64374    var c = enumerator._instanceConstructor;
64375    if (_rsvpUtils.isMaybeThenable(entry)) {
64376      if (entry.constructor === c && entry._state !== _rsvpInternal.PENDING) {
64377        entry._onError = null;
64378        enumerator._settledAt(entry._state, i, entry._result);
64379      } else {
64380        enumerator._willSettleAt(c.resolve(entry), i);
64381      }
64382    } else {
64383      enumerator._remaining--;
64384      enumerator._result[i] = enumerator._makeResult(_rsvpInternal.FULFILLED, i, entry);
64385    }
64386  };
64387
64388  Enumerator.prototype._settledAt = function (state, i, value) {
64389    var enumerator = this;
64390    var promise = enumerator.promise;
64391
64392    if (promise._state === _rsvpInternal.PENDING) {
64393      enumerator._remaining--;
64394
64395      if (enumerator._abortOnReject && state === _rsvpInternal.REJECTED) {
64396        _rsvpInternal.reject(promise, value);
64397      } else {
64398        enumerator._result[i] = enumerator._makeResult(state, i, value);
64399      }
64400    }
64401
64402    if (enumerator._remaining === 0) {
64403      _rsvpInternal.fulfill(promise, enumerator._result);
64404    }
64405  };
64406
64407  Enumerator.prototype._makeResult = function (state, i, value) {
64408    return value;
64409  };
64410
64411  Enumerator.prototype._willSettleAt = function (promise, i) {
64412    var enumerator = this;
64413
64414    _rsvpInternal.subscribe(promise, undefined, function (value) {
64415      enumerator._settledAt(_rsvpInternal.FULFILLED, i, value);
64416    }, function (reason) {
64417      enumerator._settledAt(_rsvpInternal.REJECTED, i, reason);
64418    });
64419  };
64420});
64421enifed('rsvp/events', ['exports'], function (exports) {
64422  'use strict';
64423
64424  function indexOf(callbacks, callback) {
64425    for (var i = 0, l = callbacks.length; i < l; i++) {
64426      if (callbacks[i] === callback) {
64427        return i;
64428      }
64429    }
64430
64431    return -1;
64432  }
64433
64434  function callbacksFor(object) {
64435    var callbacks = object._promiseCallbacks;
64436
64437    if (!callbacks) {
64438      callbacks = object._promiseCallbacks = {};
64439    }
64440
64441    return callbacks;
64442  }
64443
64444  /**
64445    @class RSVP.EventTarget
64446  */
64447  exports.default = {
64448
64449    /**
64450      `RSVP.EventTarget.mixin` extends an object with EventTarget methods. For
64451      Example:
64452       ```javascript
64453      var object = {};
64454       RSVP.EventTarget.mixin(object);
64455       object.on('finished', function(event) {
64456        // handle event
64457      });
64458       object.trigger('finished', { detail: value });
64459      ```
64460       `EventTarget.mixin` also works with prototypes:
64461       ```javascript
64462      var Person = function() {};
64463      RSVP.EventTarget.mixin(Person.prototype);
64464       var yehuda = new Person();
64465      var tom = new Person();
64466       yehuda.on('poke', function(event) {
64467        console.log('Yehuda says OW');
64468      });
64469       tom.on('poke', function(event) {
64470        console.log('Tom says OW');
64471      });
64472       yehuda.trigger('poke');
64473      tom.trigger('poke');
64474      ```
64475       @method mixin
64476      @for RSVP.EventTarget
64477      @private
64478      @param {Object} object object to extend with EventTarget methods
64479    */
64480    'mixin': function (object) {
64481      object['on'] = this['on'];
64482      object['off'] = this['off'];
64483      object['trigger'] = this['trigger'];
64484      object._promiseCallbacks = undefined;
64485      return object;
64486    },
64487
64488    /**
64489      Registers a callback to be executed when `eventName` is triggered
64490       ```javascript
64491      object.on('event', function(eventInfo){
64492        // handle the event
64493      });
64494       object.trigger('event');
64495      ```
64496       @method on
64497      @for RSVP.EventTarget
64498      @private
64499      @param {String} eventName name of the event to listen for
64500      @param {Function} callback function to be called when the event is triggered.
64501    */
64502    'on': function (eventName, callback) {
64503      if (typeof callback !== 'function') {
64504        throw new TypeError('Callback must be a function');
64505      }
64506
64507      var allCallbacks = callbacksFor(this),
64508          callbacks;
64509
64510      callbacks = allCallbacks[eventName];
64511
64512      if (!callbacks) {
64513        callbacks = allCallbacks[eventName] = [];
64514      }
64515
64516      if (indexOf(callbacks, callback) === -1) {
64517        callbacks.push(callback);
64518      }
64519    },
64520
64521    /**
64522      You can use `off` to stop firing a particular callback for an event:
64523       ```javascript
64524      function doStuff() { // do stuff! }
64525      object.on('stuff', doStuff);
64526       object.trigger('stuff'); // doStuff will be called
64527       // Unregister ONLY the doStuff callback
64528      object.off('stuff', doStuff);
64529      object.trigger('stuff'); // doStuff will NOT be called
64530      ```
64531       If you don't pass a `callback` argument to `off`, ALL callbacks for the
64532      event will not be executed when the event fires. For example:
64533       ```javascript
64534      var callback1 = function(){};
64535      var callback2 = function(){};
64536       object.on('stuff', callback1);
64537      object.on('stuff', callback2);
64538       object.trigger('stuff'); // callback1 and callback2 will be executed.
64539       object.off('stuff');
64540      object.trigger('stuff'); // callback1 and callback2 will not be executed!
64541      ```
64542       @method off
64543      @for RSVP.EventTarget
64544      @private
64545      @param {String} eventName event to stop listening to
64546      @param {Function} callback optional argument. If given, only the function
64547      given will be removed from the event's callback queue. If no `callback`
64548      argument is given, all callbacks will be removed from the event's callback
64549      queue.
64550    */
64551    'off': function (eventName, callback) {
64552      var allCallbacks = callbacksFor(this),
64553          callbacks,
64554          index;
64555
64556      if (!callback) {
64557        allCallbacks[eventName] = [];
64558        return;
64559      }
64560
64561      callbacks = allCallbacks[eventName];
64562
64563      index = indexOf(callbacks, callback);
64564
64565      if (index !== -1) {
64566        callbacks.splice(index, 1);
64567      }
64568    },
64569
64570    /**
64571      Use `trigger` to fire custom events. For example:
64572       ```javascript
64573      object.on('foo', function(){
64574        console.log('foo event happened!');
64575      });
64576      object.trigger('foo');
64577      // 'foo event happened!' logged to the console
64578      ```
64579       You can also pass a value as a second argument to `trigger` that will be
64580      passed as an argument to all event listeners for the event:
64581       ```javascript
64582      object.on('foo', function(value){
64583        console.log(value.name);
64584      });
64585       object.trigger('foo', { name: 'bar' });
64586      // 'bar' logged to the console
64587      ```
64588       @method trigger
64589      @for RSVP.EventTarget
64590      @private
64591      @param {String} eventName name of the event to be triggered
64592      @param {*} options optional value to be passed to any event handlers for
64593      the given `eventName`
64594    */
64595    'trigger': function (eventName, options) {
64596      var allCallbacks = callbacksFor(this),
64597          callbacks,
64598          callback;
64599
64600      if (callbacks = allCallbacks[eventName]) {
64601        // Don't cache the callbacks.length since it may grow
64602        for (var i = 0; i < callbacks.length; i++) {
64603          callback = callbacks[i];
64604
64605          callback(options);
64606        }
64607      }
64608    }
64609  };
64610});
64611enifed('rsvp/filter', ['exports', 'rsvp/promise', 'rsvp/utils'], function (exports, _rsvpPromise, _rsvpUtils) {
64612  'use strict';
64613
64614  exports.default = filter;
64615
64616  /**
64617   `RSVP.filter` is similar to JavaScript's native `filter` method, except that it
64618    waits for all promises to become fulfilled before running the `filterFn` on
64619    each item in given to `promises`. `RSVP.filter` returns a promise that will
64620    become fulfilled with the result of running `filterFn` on the values the
64621    promises become fulfilled with.
64622  
64623    For example:
64624  
64625    ```javascript
64626  
64627    var promise1 = RSVP.resolve(1);
64628    var promise2 = RSVP.resolve(2);
64629    var promise3 = RSVP.resolve(3);
64630  
64631    var promises = [promise1, promise2, promise3];
64632  
64633    var filterFn = function(item){
64634      return item > 1;
64635    };
64636  
64637    RSVP.filter(promises, filterFn).then(function(result){
64638      // result is [ 2, 3 ]
64639    });
64640    ```
64641  
64642    If any of the `promises` given to `RSVP.filter` are rejected, the first promise
64643    that is rejected will be given as an argument to the returned promise's
64644    rejection handler. For example:
64645  
64646    ```javascript
64647    var promise1 = RSVP.resolve(1);
64648    var promise2 = RSVP.reject(new Error('2'));
64649    var promise3 = RSVP.reject(new Error('3'));
64650    var promises = [ promise1, promise2, promise3 ];
64651  
64652    var filterFn = function(item){
64653      return item > 1;
64654    };
64655  
64656    RSVP.filter(promises, filterFn).then(function(array){
64657      // Code here never runs because there are rejected promises!
64658    }, function(reason) {
64659      // reason.message === '2'
64660    });
64661    ```
64662  
64663    `RSVP.filter` will also wait for any promises returned from `filterFn`.
64664    For instance, you may want to fetch a list of users then return a subset
64665    of those users based on some asynchronous operation:
64666  
64667    ```javascript
64668  
64669    var alice = { name: 'alice' };
64670    var bob   = { name: 'bob' };
64671    var users = [ alice, bob ];
64672  
64673    var promises = users.map(function(user){
64674      return RSVP.resolve(user);
64675    });
64676  
64677    var filterFn = function(user){
64678      // Here, Alice has permissions to create a blog post, but Bob does not.
64679      return getPrivilegesForUser(user).then(function(privs){
64680        return privs.can_create_blog_post === true;
64681      });
64682    };
64683    RSVP.filter(promises, filterFn).then(function(users){
64684      // true, because the server told us only Alice can create a blog post.
64685      users.length
64685 === 1;
64686      // false, because Alice is the only user present in `users`
64687      users[0] === bob;
64688    });
64689    ```
64690  
64691    @method filter
64692    @static
64693    @for RSVP
64694    @param {Array} promises
64695    @param {Function} filterFn - function to be called on each resolved value to
64696    filter the final results.
64697    @param {String} label optional string describing the promise. Useful for
64698    tooling.
64699    @return {Promise}
64700  */
64701
64702  function filter(promises, filterFn, label) {
64703    return _rsvpPromise.default.all(promises, label).then(function (values) {
64704      if (!_rsvpUtils.isFunction(filterFn)) {
64705        throw new TypeError("You must pass a function as filter's second argument.");
64706      }
64707
64708      var length = values.length;
64709      var filtered = new Array(length);
64710
64711      for (var i = 0; i < length; i++) {
64712        filtered[i] = filterFn(values[i]);
64713      }
64714
64715      return _rsvpPromise.default.all(filtered, label).then(function (filtered) {
64716        var results = new Array(length);
64717        var newLength = 0;
64718
64719        for (var i = 0; i < length; i++) {
64720          if (filtered[i]) {
64721            results[newLength] = values[i];
64722            newLength++;
64723          }
64724        }
64725
64726        results.length = newLength;
64727
64728        return results;
64729      });
64730    });
64731  }
64732});
64733enifed('rsvp/hash-settled', ['exports', 'rsvp/promise', 'rsvp/enumerator', 'rsvp/promise-hash', 'rsvp/utils'], function (exports, _rsvpPromise, _rsvpEnumerator, _rsvpPromiseHash, _rsvpUtils) {
64734  'use strict';
64735
64736  exports.default = hashSettled;
64737
64738  function HashSettled(Constructor, object, label) {
64739    this._superConstructor(Constructor, object, false, label);
64740  }
64741
64742  HashSettled.prototype = _rsvpUtils.o_create(_rsvpPromiseHash.default.prototype);
64743  HashSettled.prototype._superConstructor = _rsvpEnumerator.default;
64744  HashSettled.prototype._makeResult = _rsvpEnumerator.makeSettledResult;
64745
64746  HashSettled.prototype._validationError = function () {
64747    return new Error('hashSettled must be called with an object');
64748  };
64749
64750  /**
64751    `RSVP.hashSettled` is similar to `RSVP.allSettled`, but takes an object
64752    instead of an array for its `promises` argument.
64753  
64754    Unlike `RSVP.all` or `RSVP.hash`, which implement a fail-fast method,
64755    but like `RSVP.allSettled`, `hashSettled` waits until all the
64756    constituent promises have returned and then shows you all the results
64757    with their states and values/reasons. This is useful if you want to
64758    handle multiple promises' failure states together as a set.
64759  
64760    Returns a promise that is fulfilled when all the given promises have been
64761    settled, or rejected if the passed parameters are invalid.
64762  
64763    The returned promise is fulfilled with a hash that has the same key names as
64764    the `promises` object argument. If any of the values in the object are not
64765    promises, they will be copied over to the fulfilled object and marked with state
64766    'fulfilled'.
64767  
64768    Example:
64769  
64770    ```javascript
64771    var promises = {
64772      myPromise: RSVP.Promise.resolve(1),
64773      yourPromise: RSVP.Promise.resolve(2),
64774      theirPromise: RSVP.Promise.resolve(3),
64775      notAPromise: 4
64776    };
64777  
64778    RSVP.hashSettled(promises).then(function(hash){
64779      // hash here is an object that looks like:
64780      // {
64781      //   myPromise: { state: 'fulfilled', value: 1 },
64782      //   yourPromise: { state: 'fulfilled', value: 2 },
64783      //   theirPromise: { state: 'fulfilled', value: 3 },
64784      //   notAPromise: { state: 'fulfilled', value: 4 }
64785      // }
64786    });
64787    ```
64788  
64789    If any of the `promises` given to `RSVP.hash` are rejected, the state will
64790    be set to 'rejected' and the reason for rejection provided.
64791  
64792    Example:
64793  
64794    ```javascript
64795    var promises = {
64796      myPromise: RSVP.Promise.resolve(1),
64797      rejectedPromise: RSVP.Promise.reject(new Error('rejection')),
64798      anotherRejectedPromise: RSVP.Promise.reject(new Error('more rejection')),
64799    };
64800  
64801    RSVP.hashSettled(promises).then(function(hash){
64802      // hash here is an object that looks like:
64803      // {
64804      //   myPromise:              { state: 'fulfilled', value: 1 },
64805      //   rejectedPromise:        { state: 'rejected', reason: Error },
64806      //   anotherRejectedPromise: { state: 'rejected', reason: Error },
64807      // }
64808      // Note that for rejectedPromise, reason.message == 'rejection',
64809      // and for anotherRejectedPromise, reason.message == 'more rejection'.
64810    });
64811    ```
64812  
64813    An important note: `RSVP.hashSettled` is intended for plain JavaScript objects that
64814    are just a set of keys and values. `RSVP.hashSettled` will NOT preserve prototype
64815    chains.
64816  
64817    Example:
64818  
64819    ```javascript
64820    function MyConstructor(){
64821      this.example = RSVP.Promise.resolve('Example');
64822    }
64823  
64824    MyConstructor.prototype = {
64825      protoProperty: RSVP.Promise.resolve('Proto Property')
64826    };
64827  
64828    var myObject = new MyConstructor();
64829  
64830    RSVP.hashSettled(myObject).then(function(hash){
64831      // protoProperty will not be present, instead you will just have an
64832      // object that looks like:
64833      // {
64834      //   example: { state: 'fulfilled', value: 'Example' }
64835      // }
64836      //
64837      // hash.hasOwnProperty('protoProperty'); // false
64838      // 'undefined' === typeof hash.protoProperty
64839    });
64840    ```
64841  
64842    @method hashSettled
64843    @for RSVP
64844    @param {Object} object
64845    @param {String} label optional string that describes the promise.
64846    Useful for tooling.
64847    @return {Promise} promise that is fulfilled when when all properties of `promises`
64848    have been settled.
64849    @static
64850  */
64851
64852  function hashSettled(object, label) {
64853    return new HashSettled(_rsvpPromise.default, object, label).promise;
64854  }
64855});
64856enifed('rsvp/hash', ['exports', 'rsvp/promise', 'rsvp/promise-hash'], function (exports, _rsvpPromise, _rsvpPromiseHash) {
64857  'use strict';
64858
64859  exports.default = hash;
64860
64861  /**
64862    `RSVP.hash` is similar to `RSVP.all`, but takes an object instead of an array
64863    for its `promises` argument.
64864  
64865    Returns a promise that is fulfilled when all the given promises have been
64866    fulfilled, or rejected if any of them become rejected. The returned promise
64867    is fulfilled with a hash that has the same key names as the `promises` object
64868    argument. If any of the values in the object are not promises, they will
64869    simply be copied over to the fulfilled object.
64870  
64871    Example:
64872  
64873    ```javascript
64874    var promises = {
64875      myPromise: RSVP.resolve(1),
64876      yourPromise: RSVP.resolve(2),
64877      theirPromise: RSVP.resolve(3),
64878      notAPromise: 4
64879    };
64880  
64881    RSVP.hash(promises).then(function(hash){
64882      // hash here is an object that looks like:
64883      // {
64884      //   myPromise: 1,
64885      //   yourPromise: 2,
64886      //   theirPromise: 3,
64887      //   notAPromise: 4
64888      // }
64889    });
64890    ````
64891  
64892    If any of the `promises` given to `RSVP.hash` are rejected, the first promise
64893    that is rejected will be given as the reason to the rejection handler.
64894  
64895    Example:
64896  
64897    ```javascript
64898    var promises = {
64899      myPromise: RSVP.resolve(1),
64900      rejectedPromise: RSVP.reject(new Error('rejectedPromise')),
64901      anotherRejectedPromise: RSVP.reject(new Error('anotherRejectedPromise')),
64902    };
64903  
64904    RSVP.hash(promises).then(function(hash){
64905      // Code here never runs because there are rejected promises!
64906    }, function(reason) {
64907      // reason.message === 'rejectedPromise'
64908    });
64909    ```
64910  
64911    An important note: `RSVP.hash` is intended for plain JavaScript objects that
64912    are just a set of keys and values. `RSVP.hash` will NOT preserve prototype
64913    chains.
64914  
64915    Example:
64916  
64917    ```javascript
64918    function MyConstructor(){
64919      this.example = RSVP.resolve('Example');
64920    }
64921  
64922    MyConstructor.prototype = {
64923      protoProperty: RSVP.resolve('Proto Property')
64924    };
64925  
64926    var myObject = new MyConstructor();
64927  
64928    RSVP.hash(myObject).then(function(hash){
64929      // protoProperty will not be present, instead you will just have an
64930      // object that looks like:
64931      // {
64932      //   example: 'Example'
64933      // }
64934      //
64935      // hash.hasOwnProperty('protoProperty'); // false
64936      // 'undefined' === typeof hash.protoProperty
64937    });
64938    ```
64939  
64940    @method hash
64941    @static
64942    @for RSVP
64943    @param {Object} object
64944    @param {String} label optional string that describes the promise.
64945    Useful for tooling.
64946    @return {Promise} promise that is fulfilled when all properties of `promises`
64947    have been fulfilled, or rejected if any of them become rejected.
64948  */
64949
64950  function hash(object, label) {
64951    return new _rsvpPromiseHash.default(_rsvpPromise.default, object, label).promise;
64952  }
64953});
64954enifed('rsvp/instrument', ['exports', 'rsvp/config', 'rsvp/utils'], function (exports, _rsvpConfig, _rsvpUtils) {
64955  'use strict';
64956
64957  exports.default = instrument;
64958
64959  var queue = [];
64960
64961  function scheduleFlush() {
64962    setTimeout(function () {
64963      var entry;
64964      for (var i = 0; i < queue.length; i++) {
64965        entry = queue[i];
64966
64967        var payload = entry.payload;
64968
64969        payload.guid = payload.key + payload.id;
64970        payload.childGuid = payload.key + payload.childId;
64971        if (payload.error) {
64972          payload.stack = payload.error.stack;
64973        }
64974
64975        _rsvpConfig.config['trigger'](entry.name, entry.payload);
64976      }
64977      queue.length = 0;
64978    }, 50);
64979  }
64980
64981  function instrument(eventName, promise, child) {
64982    if (1 === queue.push({
64983      name: eventName,
64984      payload: {
64985        key: promise._guidKey,
64986        id: promise._id,
64987        eventName: eventName,
64988        detail: promise._result,
64989        childId: child && child._id,
64990        label: promise._label,
64991        timeStamp: _rsvpUtils.now(),
64992        error: _rsvpConfig.config["instrument-with-stack"] ? new Error(promise._label) : null
64993      } })) {
64994      scheduleFlush();
64995    }
64996  }
64997});
64998enifed('rsvp/map', ['exports', 'rsvp/promise', 'rsvp/utils'], function (exports, _rsvpPromise, _rsvpUtils) {
64999  'use strict';
65000
65001  exports.default = map;
65002
65003  /**
65004   `RSVP.map` is similar to JavaScript's native `map` method, except that it
65005    waits for all promises to become fulfilled before running the `mapFn` on
65006    each item in given to `promises`. `RSVP.map` returns a promise that will
65007    become fulfilled with the result of running `mapFn` on the values the promises
65008    become fulfilled with.
65009  
65010    For example:
65011  
65012    ```javascript
65013  
65014    var promise1 = RSVP.resolve(1);
65015    var promise2 = RSVP.resolve(2);
65016    var promise3 = RSVP.resolve(3);
65017    var promises = [ promise1, promise2, promise3 ];
65018  
65019    var mapFn = function(item){
65020      return item + 1;
65021    };
65022  
65023    RSVP.map(promises, mapFn).then(function(result){
65024      // result is [ 2, 3, 4 ]
65025    });
65026    ```
65027  
65028    If any of the `promises` given to `RSVP.map` are rejected, the first promise
65029    that is rejected will be given as an argument to the returned promise's
65030    rejection handler. For example:
65031  
65032    ```javascript
65033    var promise1 = RSVP.resolve(1);
65034    var promise2 = RSVP.reject(new Error('2'));
65035    var promise3 = RSVP.reject(new Error('3'));
65036    var promises = [ promise1, promise2, promise3 ];
65037  
65038    var mapFn = function(item){
65039      return item + 1;
65040    };
65041  
65042    RSVP.map(promises, mapFn).then(function(array){
65043      // Code here never runs because there are rejected promises!
65044    }, function(reason) {
65045      // reason.message === '2'
65046    });
65047    ```
65048  
65049    `RSVP.map` will also wait if a promise is returned from `mapFn`. For example,
65050    say you want to get all comments from a set of blog posts, but you need
65051    the blog posts first because they contain a url to those comments.
65052  
65053    ```javscript
65054  
65055    var mapFn = function(blogPost){
65056      // getComments does some ajax and returns an RSVP.Promise that is fulfilled
65057      // with some comments data
65058      return getComments(blogPost.comments_url);
65059    };
65060  
65061    // getBlogPosts does some ajax and returns an RSVP.Promise that is fulfilled
65062    // with some blog post data
65063    RSVP.map(getBlogPosts(), mapFn).then(function(comments){
65064      // comments is the result of asking the server for the comments
65065      // of all blog posts returned from getBlogPosts()
65066    });
65067    ```
65068  
65069    @method map
65070    @static
65071    @for RSVP
65072    @param {Array} promises
65073    @param {Function} mapFn function to be called on each fulfilled promise.
65074    @param {String} label optional string for labeling the promise.
65075    Useful for tooling.
65076    @return {Promise} promise that is fulfilled with the result of calling
65077    `mapFn` on each fulfilled promise or value when they become fulfilled.
65078     The promise will be rejected if any of the given `promises` become rejected.
65079    @static
65080  */
65081
65082  function map(promises, mapFn, label) {
65083    return _rsvpPromise.default.all(promises, label).then(function (values) {
65084      if (!_rsvpUtils.isFunction(mapFn)) {
65085        throw new TypeError("You must pass a function as map's second argument.");
65086      }
65087
65088      var length = values.length;
65089      var results = new Array(length);
65090
65091      for (var i = 0; i < length; i++) {
65092        results[i] = mapFn(values[i]);
65093      }
65094
65095      return _rsvpPromise.default.all(results, label);
65096    });
65097  }
65098});
65099enifed('rsvp/node', ['exports', 'rsvp/promise', 'rsvp/-internal', 'rsvp/utils'], function (exports, _rsvpPromise, _rsvpInternal, _rsvpUtils) {
65100  'use strict';
65101
65102  exports.default = denodeify;
65103
65104  function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Ob
65104ject.defineProperty(obj, key, value); } } return obj; }
65105
65106  function Result() {
65107    this.value = undefined;
65108  }
65109
65110  var ERROR = new Result();
65111  var GET_THEN_ERROR = new Result();
65112
65113  function getThen(obj) {
65114    try {
65115      return obj.then;
65116    } catch (error) {
65117      ERROR.value = error;
65118      return ERROR;
65119    }
65120  }
65121
65122  function tryApply(f, s, a) {
65123    try {
65124      f.apply(s, a);
65125    } catch (error) {
65126      ERROR.value = error;
65127      return ERROR;
65128    }
65129  }
65130
65131  function makeObject(_, argumentNames) {
65132    var obj = {};
65133    var name;
65134    var i;
65135    var length = _.length;
65136    var args = new Array(length);
65137
65138    for (var x = 0; x < length; x++) {
65139      args[x] = _[x];
65140    }
65141
65142    for (i = 0; i < argumentNames.length; i++) {
65143      name = argumentNames[i];
65144      obj[name] = args[i + 1];
65145    }
65146
65147    return obj;
65148  }
65149
65150  function arrayResult(_) {
65151    var length = _.length;
65152    var args = new Array(length - 1);
65153
65154    for (var i = 1; i < length; i++) {
65155      args[i - 1] = _[i];
65156    }
65157
65158    return args;
65159  }
65160
65161  function wrapThenable(then, promise) {
65162    return {
65163      then: function (onFulFillment, onRejection) {
65164        return then.call(promise, onFulFillment, onRejection);
65165      }
65166    };
65167  }
65168
65169  /**
65170    `RSVP.denodeify` takes a 'node-style' function and returns a function that
65171    will return an `RSVP.Promise`. You can use `denodeify` in Node.js or the
65172    browser when you'd prefer to use promises over using callbacks. For example,
65173    `denodeify` transforms the following:
65174  
65175    ```javascript
65176    var fs = require('fs');
65177  
65178    fs.readFile('myfile.txt', function(err, data){
65179      if (err) return handleError(err);
65180      handleData(data);
65181    });
65182    ```
65183  
65184    into:
65185  
65186    ```javascript
65187    var fs = require('fs');
65188    var readFile = RSVP.denodeify(fs.readFile);
65189  
65190    readFile('myfile.txt').then(handleData, handleError);
65191    ```
65192  
65193    If the node function has multiple success parameters, then `denodeify`
65194    just returns the first one:
65195  
65196    ```javascript
65197    var request = RSVP.denodeify(require('request'));
65198  
65199    request('http://example.com').then(function(res) {
65200      // ...
65201    });
65202    ```
65203  
65204    However, if you need all success parameters, setting `denodeify`'s
65205    second parameter to `true` causes it to return all success parameters
65206    as an array:
65207  
65208    ```javascript
65209    var request = RSVP.denodeify(require('request'), true);
65210  
65211    request('http://example.com').then(function(result) {
65212      // result[0] -> res
65213      // result[1] -> body
65214    });
65215    ```
65216  
65217    Or if you pass it an array with names it returns the parameters as a hash:
65218  
65219    ```javascript
65220    var request = RSVP.denodeify(require('request'), ['res', 'body']);
65221  
65222    request('http://example.com').then(function(result) {
65223      // result.res
65224      // result.body
65225    });
65226    ```
65227  
65228    Sometimes you need to retain the `this`:
65229  
65230    ```javascript
65231    var app = require('express')();
65232    var render = RSVP.denodeify(app.render.bind(app));
65233    ```
65234  
65235    The denodified function inherits from the original function. It works in all
65236    environments, except IE 10 and below. Consequently all properties of the original
65237    function are available to you. However, any properties you change on the
65238    denodeified function won't be changed on the original function. Example:
65239  
65240    ```javascript
65241    var request = RSVP.denodeify(require('request')),
65242        cookieJar = request.jar(); // <- Inheritance is used here
65243  
65244    request('http://example.com', {jar: cookieJar}).then(function(res) {
65245      // cookieJar.cookies holds now the cookies returned by example.com
65246    });
65247    ```
65248  
65249    Using `denodeify` makes it easier to compose asynchronous operations instead
65250    of using callbacks. For example, instead of:
65251  
65252    ```javascript
65253    var fs = require('fs');
65254  
65255    fs.readFile('myfile.txt', function(err, data){
65256      if (err) { ... } // Handle error
65257      fs.writeFile('myfile2.txt', data, function(err){
65258        if (err) { ... } // Handle error
65259        console.log('done')
65260      });
65261    });
65262    ```
65263  
65264    you can chain the operations together using `then` from the returned promise:
65265  
65266    ```javascript
65267    var fs = require('fs');
65268    var readFile = RSVP.denodeify(fs.readFile);
65269    var writeFile = RSVP.denodeify(fs.writeFile);
65270  
65271    readFile('myfile.txt').then(function(data){
65272      return writeFile('myfile2.txt', data);
65273    }).then(function(){
65274      console.log('done')
65275    }).catch(function(error){
65276      // Handle error
65277    });
65278    ```
65279  
65280    @method denodeify
65281    @static
65282    @for RSVP
65283    @param {Function} nodeFunc a 'node-style' function that takes a callback as
65284    its last argument. The callback expects an error to be passed as its first
65285    argument (if an error occurred, otherwise null), and the value from the
65286    operation as its second argument ('function(err, value){ }').
65287    @param {Boolean|Array} [options] An optional paramter that if set
65288    to `true` causes the promise to fulfill with the callback's success arguments
65289    as an array. This is useful if the node function has multiple success
65290    paramters. If you set this paramter to an array with names, the promise will
65291    fulfill with a hash with these names as keys and the success parameters as
65292    values.
65293    @return {Function} a function that wraps `nodeFunc` to return an
65294    `RSVP.Promise`
65295    @static
65296  */
65297
65298  function denodeify(nodeFunc, options) {
65299    var fn = function () {
65300      var self = this;
65301      var l = arguments.length;
65302      var args = new Array(l + 1);
65303      var arg;
65304      var promiseInput = false;
65305
65306      for (var i = 0; i < l; ++i) {
65307        arg = arguments[i];
65308
65309        if (!promiseInput) {
65310          // TODO: clean this up
65311          promiseInput = needsPromiseInput(arg);
65312          if (promiseInput === GET_THEN_ERROR) {
65313            var p = new _rsvpPromise.default(_rsvpInternal.noop);
65314            _rsvpInternal.reject(p, GET_THEN_ERROR.value);
65315            return p;
65316          } else if (promiseInput && promiseInput !== true) {
65317            arg = wrapThenable(promiseInput, arg);
65318          }
65319        }
65320        args[i] = arg;
65321      }
65322
65323      var promise = new _rsvpPromise.default(_rsvpInternal.noop);
65324
65325      args[l] = function (err, val) {
65326        if (err) _rsvpInternal.reject(promise, err);else if (options === undefined) _rsvpInternal.resolve(promise, val);else if (options === true) _rsvpInternal.resolve(promise, arrayResult(arguments));else if (_rsvpUtils.isArray(options)) _rsvpInternal.resolve(promise, makeObject(arguments, options));else _rsvpInternal.resolve(promise, val);
65327      };
65328
65329      if (promiseInput) {
65330        return handlePromiseInput(promise, args, nodeFunc, self);
65331      } else {
65332        return handleValueInput(promise, args, nodeFunc, self);
65333      }
65334    };
65335
65336    _defaults(fn, nodeFunc);
65337
65338    return fn;
65339  }
65340
65341  function handleValueInput(promise, args, nodeFunc, self) {
65342    var result = tryApply(nodeFunc, self, args);
65343    if (result === ERROR) {
65344      _rsvpInternal.reject(promise, result.value);
65345    }
65346    return promise;
65347  }
65348
65349  function handlePromiseInput(promise, args, nodeFunc, self) {
65350    return _rsvpPromise.default.all(args).then(function (args) {
65351      var result = tryApply(nodeFunc, self, args);
65352      if (result === ERROR) {
65353        _rsvpInternal.reject(promise, result.value);
65354      }
65355      return promise;
65356    });
65357  }
65358
65359  function needsPromiseInput(arg) {
65360    if (arg && typeof arg === 'object') {
65361      if (arg.constructor === _rsvpPromise.default) {
65362        return true;
65363      } else {
65364        return getThen(arg);
65365      }
65366    } else {
65367      return false;
65368    }
65369  }
65370});
65371enifed('rsvp/platform', ['exports'], function (exports) {
65372  'use strict';
65373
65374  var platform;
65375
65376  /* global self */
65377  if (typeof self === 'object') {
65378    platform = self;
65379
65380    /* global global */
65381  } else if (typeof global === 'object') {
65382      platform = global;
65383    } else {
65384      throw new Error('no global: `self` or `global` found');
65385    }
65386
65387  exports.default = platform;
65388});
65389enifed('rsvp/promise/all', ['exports', 'rsvp/enumerator'], function (exports, _rsvpEnumerator) {
65390  'use strict';
65391
65392  exports.default = all;
65393
65394  /**
65395    `RSVP.Promise.all` accepts an array of promises, and returns a new promise which
65396    is fulfilled with an array of fulfillment values for the passed promises, or
65397    rejected with the reason of the first passed promise to be rejected. It casts all
65398    elements of the passed iterable to promises as it runs this algorithm.
65399  
65400    Example:
65401  
65402    ```javascript
65403    var promise1 = RSVP.resolve(1);
65404    var promise2 = RSVP.resolve(2);
65405    var promise3 = RSVP.resolve(3);
65406    var promises = [ promise1, promise2, promise3 ];
65407  
65408    RSVP.Promise.all(promises).then(function(array){
65409      // The array here would be [ 1, 2, 3 ];
65410    });
65411    ```
65412  
65413    If any of the `promises` given to `RSVP.all` are rejected, the first promise
65414    that is rejected will be given as an argument to the returned promises's
65415    rejection handler. For example:
65416  
65417    Example:
65418  
65419    ```javascript
65420    var promise1 = RSVP.resolve(1);
65421    var promise2 = RSVP.reject(new Error("2"));
65422    var promise3 = RSVP.reject(new Error("3"));
65423    var promises = [ promise1, promise2, promise3 ];
65424  
65425    RSVP.Promise.all(promises).then(function(array){
65426      // Code here never runs because there are rejected promises!
65427    }, function(error) {
65428      // error.message === "2"
65429    });
65430    ```
65431  
65432    @method all
65433    @static
65434    @param {Array} entries array of promises
65435    @param {String} label optional string for labeling the promise.
65436    Useful for tooling.
65437    @return {Promise} promise that is fulfilled when all `promises` have been
65438    fulfilled, or rejected if any of them become rejected.
65439    @static
65440  */
65441
65442  function all(entries, label) {
65443    return new _rsvpEnumerator.default(this, entries, true, /* abort on reject */label).promise;
65444  }
65445});
65446enifed('rsvp/promise/race', ['exports', 'rsvp/utils', 'rsvp/-internal'], function (exports, _rsvpUtils, _rsvpInternal) {
65447  'use strict';
65448
65449  exports.default = race;
65450
65451  /**
65452    `RSVP.Promise.race` returns a new promise which is settled in the same way as the
65453    first passed promise to settle.
65454  
65455    Example:
65456  
65457    ```javascript
65458    var promise1 = new RSVP.Promise(function(resolve, reject){
65459      setTimeout(function(){
65460        resolve('promise 1');
65461      }, 200);
65462    });
65463  
65464    var promise2 = new RSVP.Promise(function(resolve, reject){
65465      setTimeout(function(){
65466        resolve('promise 2');
65467      }, 100);
65468    });
65469  
65470    RSVP.Promise.race([promise1, promise2]).then(function(result){
65471      // result === 'promise 2' because it was resolved before promise1
65472      // was resolved.
65473    });
65474    ```
65475  
65476    `RSVP.Promise.race` is deterministic in that only the state of the first
65477    settled promise matters. For example, even if other promises given to the
65478    `promises` array argument are resolved, but the first settled promise has
65479    become rejected before the other promises became fulfilled, the returned
65480    promise will become rejected:
65481  
65482    ```javascript
65483    var promise1 = new RSVP.Promise(function(resolve, reject){
65484      setTimeout(function(){
65485        resolve('promise 1');
65486      }, 200);
65487    });
65488  
65489    var promise2 = new RSVP.Promise(function(resolve, reject){
65490      setTimeout(function(){
65491        reject(new Error('promise 2'));
65492      }, 100);
65493    });
65494  
65495    RSVP.Promise.race([promise1, promise2]).then(function(result){
65496      // Code here never runs
65497    }, function(reason){
65498      // reason.message === 'promise 2' because promise 2 became rejected before
65499      // promise 1 became fulfilled
65500    });
65501    ```
65502  
65503    An example real-world use case is implementing timeouts:
65504  
65505    ```javascript
65506    RSVP.Promise.race([ajax('foo.json'), timeout(5000)])
65507    ```
65508  
65509    @method race
65510    @static
65511    @param {Array} entries array of promises to observe
65512    @param {String} label optional string for describing the promise returned.
65513    Useful for tooling.
65514    @return {Promise} a promise which settles in the same way as the first passed
65515    promise to settle.
65516  */
65517
65518  function race(entries, label) {
65519    /*jshint validthis:true */
65520    var Constructor = this;
65521
65522    var promise = new Constructor(_rsvpInternal.noop, label);
65523
65524    if (!_rsvpUtils.isArray(entries)) {
65525      _rsvpInternal.reject(promise, new TypeError('You must pass an array to race.'));
65526      return promise;
65527    }
65528
65529    var length = entries.length;
65530
65531    function onFulfillment(value) {
65532      _rsvpInternal.resolve(promise, value);
65533    }
65534
65535    function onRejection(reason) {
65536      _rsvpInternal.reject(promise, reason);
65537    }
65538
65539    for (var i = 0; promise._state === _rsvpInternal.PENDING && i < length; i++) {
65540      _rsvpInternal.subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
65541    }
65542
65543    return promise;
65544  }
65545});
65546enifed('rsvp/promise/reject', ['exports', 'rsvp/-internal'], function (exports, _rsvpInternal) {
65547  'use strict';
65548
65549  exports.default = reject;
65550
65551  /**
65552    `RSVP.Promise.reject` returns a promise rejected with the passed `reason`.
65553    It is shorthand for the following:
65554  
65555    ```javascript
65556    var promise = new RSVP.Promise(function(resolve, reject){
65557      reject(new Error('WHOOPS'));
65558    });
65559  
65560    promise.then(function(value){
65561      // Code here doesn't run because the promise is rejected!
65562    }, function(reason){
65563      // reason.message === 'WHOOPS'
65564    });
65565    ```
65566  
65567    Instead of writing the above, your code now simply becomes the following:
65568  
65569    ```javascript
65570    var promise = RSVP.Promise.reject(new Error('WHOOPS'));
65571  
65572    promise.then(function(value){
65573      // Code here doesn't run because the promise is rejected!
65574    }, function(reason){
65575      // reason.message === 'WHOOPS'
65576    });
65577    ```
65578  
65579    @method reject
65580    @static
65581    @param {*} reason value that the returned promise will be rejected with.
65582    @param {String} label optional string for identifying the returned promise.
65583    Useful for tooling.
65584    @return {Promise} a promise rejected with the given `reason`.
65585  */
65586
65587  function reject(reason, label) {
65588    /*jshint validthis:true */
65589    var Constructor = this;
65590    var promise = new Constructor(_rsvpInternal.noop, label);
65591    _rsvpInternal.reject(promise, reason);
65592    return promise;
65593  }
65594});
65595enifed('rsvp/promise/resolve', ['exports', 'rsvp/-internal'], function (exports, _rsvpInternal) {
65596  'use strict';
65597
65598  exports.default = resolve;
65599
65600  /**
65601    `RSVP.Promise.resolve` returns a promise that will become resolved with the
65602    passed `value`. It is shorthand for the following:
65603  
65604    ```javascript
65605    var promise = new RSVP.Promise(function(resolve, reject){
65606      resolve(1);
65607    });
65608  
65609    promise.then(function(value){
65610      // value === 1
65611    });
65612    ```
65613  
65614    Instead of writing the above, your code now simply becomes the following:
65615  
65616    ```javascript
65617    var promise = RSVP.Promise.resolve(1);
65618  
65619    promise.then(function(value){
65620      // value === 1
65621    });
65622    ```
65623  
65624    @method resolve
65625    @static
65626    @param {*} object value that the returned promise will be resolved with
65627    @param {String} label optional string for identifying the returned promise.
65628    Useful for tooling.
65629    @return {Promise} a promise that will become fulfilled with the given
65630    `value`
65631  */
65632
65633  function resolve(object, label) {
65634    /*jshint validthis:true */
65635    var Constructor = this;
65636
65637    if (object && typeof object === 'object' && object.constructor === Constructor) {
65638      return object;
65639    }
65640
65641    var promise = new Constructor(_rsvpInternal.noop, label);
65642    _rsvpInternal.resolve(promise, object);
65643    return promise;
65644  }
65645});
65646enifed('rsvp/promise-hash', ['exports', 'rsvp/enumerator', 'rsvp/-internal', 'rsvp/utils'], function (exports, _rsvpEnumerator, _rsvpInternal, _rsvpUtils) {
65647  'use strict';
65648
65649  function PromiseHash(Constructor, object, label) {
65650    this._superConstructor(Constructor, object, true, label);
65651  }
65652
65653  exports.default = PromiseHash;
65654
65655  PromiseHash.prototype = _rsvpUtils.o_create(_rsvpEnumerator.default.prototype);
65656  PromiseHash.prototype._superConstructor = _rsvpEnumerator.default;
65657  PromiseHash.prototype._init = function () {
65658    this._result = {};
65659  };
65660
65661  PromiseHash.prototype._validateInput = function (input) {
65662    return input && typeof input === 'object';
65663  };
65664
65665  PromiseHash.prototype._validationError = function () {
65666    return new Error('Promise.hash must be called with an object');
65667  };
65668
65669  PromiseHash.prototype._enumerate = function () {
65670    var enumerator = this;
65671    var promise = enumerator.promise;
65672    var input = enumerator._input;
65673    var results = [];
65674
65675    for (var key in input) {
65676      if (promise._state === _rsvpInternal.PENDING && Object.prototype.hasOwnProperty.call(input, key)) {
65677        results.push({
65678          position: key,
65679          entry: input[key]
65680        });
65681      }
65682    }
65683
65684    var length = results.length;
65685    enumerator._remaining = length;
65686    var result;
65687
65688    for (var i = 0; promise._state === _rsvpInternal.PENDING && i < length; i++) {
65689      result = results[i];
65690      enumerator._eachEntry(result.entry, result.position);
65691    }
65692  };
65693});
65694enifed('rsvp/promise', ['exports', 'rsvp/config', 'rsvp/instrument', 'rsvp/utils', 'rsvp/-internal', 'rsvp/promise/all', 'rsvp/promise/race', 'rsvp/promise/resolve', 'rsvp/promise/reject'], function (exports, _rsvpConfig, _r
65694svpInstrument, _rsvpUtils, _rsvpInternal, _rsvpPromiseAll, _rsvpPromiseRace, _rsvpPromiseResolve, _rsvpPromiseReject) {
65695  'use strict';
65696
65697  exports.default = Promise;
65698
65699  var guidKey = 'rsvp_' + _rsvpUtils.now() + '-';
65700  var counter = 0;
65701
65702  function needsResolver() {
65703    throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
65704  }
65705
65706  function needsNew() {
65707    throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
65708  }
65709
65710  /**
65711    Promise objects represent the eventual result of an asynchronous operation. The
65712    primary way of interacting with a promise is through its `then` method, which
65713    registers callbacks to receive either a promise’s eventual value or the reason
65714    why the promise cannot be fulfilled.
65715  
65716    Terminology
65717    -----------
65718  
65719    - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
65720    - `thenable` is an object or function that defines a `then` method.
65721    - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
65722    - `exception` is a value that is thrown using the throw statement.
65723    - `reason` is a value that indicates why a promise was rejected.
65724    - `settled` the final resting state of a promise, fulfilled or rejected.
65725  
65726    A promise can be in one of three states: pending, fulfilled, or rejected.
65727  
65728    Promises that are fulfilled have a fulfillment value and are in the fulfilled
65729    state.  Promises that are rejected have a rejection reason and are in the
65730    rejected state.  A fulfillment value is never a thenable.
65731  
65732    Promises can also be said to *resolve* a value.  If this value is also a
65733    promise, then the original promise's settled state will match the value's
65734    settled state.  So a promise that *resolves* a promise that rejects will
65735    itself reject, and a promise that *resolves* a promise that fulfills will
65736    itself fulfill.
65737  
65738  
65739    Basic Usage:
65740    ------------
65741  
65742    ```js
65743    var promise = new Promise(function(resolve, reject) {
65744      // on success
65745      resolve(value);
65746  
65747      // on failure
65748      reject(reason);
65749    });
65750  
65751    promise.then(function(value) {
65752      // on fulfillment
65753    }, function(reason) {
65754      // on rejection
65755    });
65756    ```
65757  
65758    Advanced Usage:
65759    ---------------
65760  
65761    Promises shine when abstracting away asynchronous interactions such as
65762    `XMLHttpRequest`s.
65763  
65764    ```js
65765    function getJSON(url) {
65766      return new Promise(function(resolve, reject){
65767        var xhr = new XMLHttpRequest();
65768  
65769        xhr.open('GET', url);
65770        xhr.onreadystatechange = handler;
65771        xhr.responseType = 'json';
65772        xhr.setRequestHeader('Accept', 'application/json');
65773        xhr.send();
65774  
65775        function handler() {
65776          if (this.readyState === this.DONE) {
65777            if (this.status === 200) {
65778              resolve(this.response);
65779            } else {
65780              reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
65781            }
65782          }
65783        };
65784      });
65785    }
65786  
65787    getJSON('/posts.json').then(function(json) {
65788      // on fulfillment
65789    }, function(reason) {
65790      // on rejection
65791    });
65792    ```
65793  
65794    Unlike callbacks, promises are great composable primitives.
65795  
65796    ```js
65797    Promise.all([
65798      getJSON('/posts'),
65799      getJSON('/comments')
65800    ]).then(function(values){
65801      values[0] // => postsJSON
65802      values[1] // => commentsJSON
65803  
65804      return values;
65805    });
65806    ```
65807  
65808    @class RSVP.Promise
65809    @param {function} resolver
65810    @param {String} label optional string for labeling the promise.
65811    Useful for tooling.
65812    @constructor
65813  */
65814
65815  function Promise(resolver, label) {
65816    var promise = this;
65817
65818    promise._id = counter++;
65819    promise._label = label;
65820    promise._state = undefined;
65821    promise._result = undefined;
65822    promise._subscribers = [];
65823
65824    if (_rsvpConfig.config.instrument) {
65825      _rsvpInstrument.default('created', promise);
65826    }
65827
65828    if (_rsvpInternal.noop !== resolver) {
65829      if (!_rsvpUtils.isFunction(resolver)) {
65830        needsResolver();
65831      }
65832
65833      if (!(promise instanceof Promise)) {
65834        needsNew();
65835      }
65836
65837      _rsvpInternal.initializePromise(promise, resolver);
65838    }
65839  }
65840
65841  Promise.cast = _rsvpPromiseResolve.default; // deprecated
65842  Promise.all = _rsvpPromiseAll.default;
65843  Promise.race = _rsvpPromiseRace.default;
65844  Promise.resolve = _rsvpPromiseResolve.default;
65845  Promise.reject = _rsvpPromiseReject.default;
65846
65847  Promise.prototype = {
65848    constructor: Promise,
65849
65850    _guidKey: guidKey,
65851
65852    _onError: function (reason) {
65853      var promise = this;
65854      _rsvpConfig.config.after(function () {
65855        if (promise._onError) {
65856          _rsvpConfig.config['trigger']('error', reason);
65857        }
65858      });
65859    },
65860
65861    /**
65862      The primary way of interacting with a promise is through its `then` method,
65863      which registers callbacks to receive either a promise's eventual value or the
65864      reason why the promise cannot be fulfilled.
65865    
65866      ```js
65867      findUser().then(function(user){
65868        // user is available
65869      }, function(reason){
65870        // user is unavailable, and you are given the reason why
65871      });
65872      ```
65873    
65874      Chaining
65875      --------
65876    
65877      The return value of `then` is itself a promise.  This second, 'downstream'
65878      promise is resolved with the return value of the first promise's fulfillment
65879      or rejection handler, or rejected if the handler throws an exception.
65880    
65881      ```js
65882      findUser().then(function (user) {
65883        return user.name;
65884      }, function (reason) {
65885        return 'default name';
65886      }).then(function (userName) {
65887        // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
65888        // will be `'default name'`
65889      });
65890    
65891      findUser().then(function (user) {
65892        throw new Error('Found user, but still unhappy');
65893      }, function (reason) {
65894        throw new Error('`findUser` rejected and we're unhappy');
65895      }).then(function (value) {
65896        // never reached
65897      }, function (reason) {
65898        // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
65899        // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
65900      });
65901      ```
65902      If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
65903    
65904      ```js
65905      findUser().then(function (user) {
65906        throw new PedagogicalException('Upstream error');
65907      }).then(function (value) {
65908        // never reached
65909      }).then(function (value) {
65910        // never reached
65911      }, function (reason) {
65912        // The `PedgagocialException` is propagated all the way down to here
65913      });
65914      ```
65915    
65916      Assimilation
65917      ------------
65918    
65919      Sometimes the value you want to propagate to a downstream promise can only be
65920      retrieved asynchronously. This can be achieved by returning a promise in the
65921      fulfillment or rejection handler. The downstream promise will then be pending
65922      until the returned promise is settled. This is called *assimilation*.
65923    
65924      ```js
65925      findUser().then(function (user) {
65926        return findCommentsByAuthor(user);
65927      }).then(function (comments) {
65928        // The user's comments are now available
65929      });
65930      ```
65931    
65932      If the assimliated promise rejects, then the downstream promise will also reject.
65933    
65934      ```js
65935      findUser().then(function (user) {
65936        return findCommentsByAuthor(user);
65937      }).then(function (comments) {
65938        // If `findCommentsByAuthor` fulfills, we'll have the value here
65939      }, function (reason) {
65940        // If `findCommentsByAuthor` rejects, we'll have the reason here
65941      });
65942      ```
65943    
65944      Simple Example
65945      --------------
65946    
65947      Synchronous Example
65948    
65949      ```javascript
65950      var result;
65951    
65952      try {
65953        result = findResult();
65954        // success
65955      } catch(reason) {
65956        // failure
65957      }
65958      ```
65959    
65960      Errback Example
65961    
65962      ```js
65963      findResult(function(result, err){
65964        if (err) {
65965          // failure
65966        } else {
65967          // success
65968        }
65969      });
65970      ```
65971    
65972      Promise Example;
65973    
65974      ```javascript
65975      findResult().then(function(result){
65976        // success
65977      }, function(reason){
65978        // failure
65979      });
65980      ```
65981    
65982      Advanced Example
65983      --------------
65984    
65985      Synchronous Example
65986    
65987      ```javascript
65988      var author, books;
65989    
65990      try {
65991        author = findAuthor();
65992        books  = findBooksByAuthor(author);
65993        // success
65994      } catch(reason) {
65995        // failure
65996      }
65997      ```
65998    
65999      Errback Example
66000    
66001      ```js
66002    
66003      function foundBooks(books) {
66004    
66005      }
66006    
66007      function failure(reason) {
66008    
66009      }
66010    
66011      findAuthor(function(author, err){
66012        if (err) {
66013          failure(err);
66014          // failure
66015        } else {
66016          try {
66017            findBoooksByAuthor(author, function(books, err) {
66018              if (err) {
66019                failure(err);
66020              } else {
66021                try {
66022                  foundBooks(books);
66023                } catch(reason) {
66024                  failure(reason);
66025                }
66026              }
66027            });
66028          } catch(error) {
66029            failure(err);
66030          }
66031          // success
66032        }
66033      });
66034      ```
66035    
66036      Promise Example;
66037    
66038      ```javascript
66039      findAuthor().
66040        then(findBooksByAuthor).
66041        then(function(books){
66042          // found books
66043      }).catch(function(reason){
66044        // something went wrong
66045      });
66046      ```
66047    
66048      @method then
66049      @param {Function} onFulfillment
66050      @param {Function} onRejection
66051      @param {String} label optional string for labeling the promise.
66052      Useful for tooling.
66053      @return {Promise}
66054    */
66055    then: function (onFulfillment, onRejection, label) {
66056      var parent = this;
66057      var state = parent._state;
66058
66059      if (state === _rsvpInternal.FULFILLED && !onFulfillment || state === _rsvpInternal.REJECTED && !onRejection) {
66060        if (_rsvpConfig.config.instrument) {
66061          _rsvpInstrument.default('chained', parent, parent);
66062        }
66063        return parent;
66064      }
66065
66066      parent._onError = null;
66067
66068      var child = new parent.constructor(_rsvpInternal.noop, label);
66069      var result = parent._result;
66070
66071      if (_rsvpConfig.config.instrument) {
66072        _rsvpInstrument.default('chained', parent, child);
66073      }
66074
66075      if (state) {
66076        var callback = arguments[state - 1];
66077        _rsvpConfig.config.async(function () {
66078          _rsvpInternal.invokeCallback(state, child, callback, result);
66079        });
66080      } else {
66081        _rsvpInternal.subscribe(parent, child, onFulfillment, onRejection);
66082      }
66083
66084      return child;
66085    },
66086
66087    /**
66088      `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
66089      as the catch block of a try/catch statement.
66090    
66091      ```js
66092      function findAuthor(){
66093        throw new Error('couldn't find that author');
66094      }
66095    
66096      // synchronous
66097      try {
66098        findAuthor();
66099      } catch(reason) {
66100        // something went wrong
66101      }
66102    
66103      // async with promises
66104      findAuthor().catch(function(reason){
66105        // something went wrong
66106      });
66107      ```
66108    
66109      @method catch
66110      @param {Function} onRejection
66111      @param {String} label optional string for labeling the promise.
66112      Useful for tooling.
66113      @return {Promise}
66114    */
66115    'catch': function (onRejection, label) {
66116      return this.then(undefined, onRejection, label);
66117    },
66118
66119    /**
66120      `finally` will be invoked regardless of the promise's fate just as native
66121      try/catch/finally behaves
66122    
66123      Synchronous example:
66124    
66125      ```js
66126      findAuthor() {
66127        if (Math.random() > 0.5) {
66128          throw new Error();
66129        }
66130        return new Author();
66131      }
66132    
66133      try {
66134        return findAuthor(); // succeed or fail
66135      } catch(error) {
66136        return findOtherAuther();
66137      } finally {
66138        // always runs
66139        // doesn't affect the return value
66140      }
66141      ```
66142    
66143      Asynchronous example:
66144    
66145      ```js
66146      findAuthor().catch(function(reason){
66147        return findOtherAuther();
66148      }).finally(function(){
66149        // author was either found, or not
66150      });
66151      ```
66152    
66153      @method finally
66154      @param {Function} callback
66155      @param {String} label optional string for labeling the promise.
66156      Useful for tooling.
66157      @return {Promise}
66158    */
66159    'finally': function (callback, label) {
66160      var promise = this;
66161      var constructor = promise.constructor;
66162
66163      return promise.then(function (value) {
66164        return constructor.resolve(callback()).then(function () {
66165          return value;
66166        });
66167      }, function (reason) {
66168        return constructor.resolve(callback()).then(function () {
66169          throw reason;
66170        });
66171      }, label);
66172    }
66173  };
66174});
66175enifed('rsvp/race', ['exports', 'rsvp/promise'], function (exports, _rsvpPromise) {
66176  'use strict';
66177
66178  exports.default = race;
66179
66180  /**
66181    This is a convenient alias for `RSVP.Promise.race`.
66182  
66183    @method race
66184    @static
66185    @for RSVP
66186    @param {Array} array Array of promises.
66187    @param {String} label An optional label. This is useful
66188    for tooling.
66189   */
66190
66191  function race(array, label) {
66192    return _rsvpPromise.default.race(array, label);
66193  }
66194});
66195enifed('rsvp/reject', ['exports', 'rsvp/promise'], function (exports, _rsvpPromise) {
66196  'use strict';
66197
66198  exports.default = reject;
66199
66200  /**
66201    This is a convenient alias for `RSVP.Promise.reject`.
66202  
66203    @method reject
66204    @static
66205    @for RSVP
66206    @param {*} reason value that the returned promise will be rejected with.
66207    @param {String} label optional string for identifying the returned promise.
66208    Useful for tooling.
66209    @return {Promise} a promise rejected with the given `reason`.
66210  */
66211
66212  function reject(reason, label) {
66213    return _rsvpPromise.default.reject(reason, label);
66214  }
66215});
66216enifed('rsvp/resolve', ['exports', 'rsvp/promise'], function (exports, _rsvpPromise) {
66217  'use strict';
66218
66219  exports.default = resolve;
66220
66221  /**
66222    This is a convenient alias for `RSVP.Promise.resolve`.
66223  
66224    @method resolve
66225    @static
66226    @for RSVP
66227    @param {*} value value that the returned promise will be resolved with
66228    @param {String} label optional string for identifying the returned promise.
66229    Useful for tooling.
66230    @return {Promise} a promise that will become fulfilled with the given
66231    `value`
66232  */
66233
66234  function resolve(value, label) {
66235    return _rsvpPromise.default.resolve(value, label);
66236  }
66237});
66238enifed("rsvp/rethrow", ["exports"], function (exports) {
66239  /**
66240    `RSVP.rethrow` will rethrow an error on the next turn of the JavaScript event
66241    loop in order to aid debugging.
66242  
66243    Promises A+ specifies that any exceptions that occur with a promise must be
66244    caught by the promises implementation and bubbled to the last handler. For
66245    this reason, it is recommended that you always specify a second rejection
66246    handler function to `then`. However, `RSVP.rethrow` will throw the exception
66247    outside of the promise, so it bubbles up to your console if in the browser,
66248    or domain/cause uncaught exception in Node. `rethrow` will also throw the
66249    error again so the error can be handled by the promise per the spec.
66250  
66251    ```javascript
66252    function throws(){
66253      throw new Error('Whoops!');
66254    }
66255  
66256    var promise = new RSVP.Promise(function(resolve, reject){
66257      throws();
66258    });
66259  
66260    promise.catch(RSVP.rethrow).then(function(){
66261      // Code here doesn't run because the promise became rejected due to an
66262      // error!
66263    }, function (err){
66264      // handle the error here
66265    });
66266    ```
66267  
66268    The 'Whoops' error will be thrown on the next turn of the event loop
66269    and you can watch for it in your console. You can also handle it using a
66270    rejection handler given to `.then` or `.catch` on the returned promise.
66271  
66272    @method rethrow
66273    @static
66274    @for RSVP
66275    @param {Error} reason reason the promise became rejected.
66276    @throws Error
66277    @static
66278  */
66279  "use strict";
66280
66281  exports.default = rethrow;
66282
66283  function rethrow(reason) {
66284    setTimeout(function () {
66285      throw reason;
66286    });
66287    throw reason;
66288  }
66289});
66290enifed('rsvp/utils', ['exports'], function (exports) {
66291  'use strict';
66292
66293  exports.objectOrFunction = objectOrFunction;
66294  exports.isFunction = isFunction;
66295  exports.isMaybeThenable = isMaybeThenable;
66296
66297  function objectOrFunction(x) {
66298    return typeof x === 'function' || typeof x === 'object' && x !== null;
66299  }
66300
66301  function isFunction(x) {
66302    return typeof x === 'function';
66303  }
66304
66305  function isMaybeThenable(x) {
66306    return typeof x === 'object' && x !== null;
66307  }
66308
66309  var _isArray;
66310  if (!Array.isArray) {
66311    _isArray = function (x) {
66312      return Object.prototype.toString.call(x) === '[object Array]';
66313    };
66314  } else {
66315    _isArray = Array.isArray;
66316  }
66317
66318  var isArray = _isArray;
66319
66320  exports.isArray = isArray;
66321  // Date.now is not available in browsers < IE9
66322  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
66323  var now = Date.now || function () {
66324    return new Date().getTime();
66325  };
66326
66327  exports.now = now;
66328  function F() {}
66329
66330  var o_create = Object.create || function (o) {
66331    if (arguments.length > 1) {
66332      throw new Error('Second argument not supported');
66333    }
66334    if (typeof o !== 'object') {
66335      throw new TypeError('Argument must be an object');
66336    }
66337    F.prototype = o;
66338    return new F();
66339  };
66340  exports.o_create = o_create;
66341});
66342enifed('rsvp', ['exports', 'rsvp/promise', 'rsvp/events', 'rsvp/node', 'rsvp/all', 'rsvp/all-settled', 'rsvp/race', 'rsvp/hash', 'rsvp/hash-settled', 'rsvp/rethrow', 'rsvp/defer', 'rsvp/config', 'rsvp/map', 'rsvp/resolve', 'rsvp/reject', 'rsvp/filter', 'rsvp/asap'], function (exports, _rsvpPromise, _rsvpEvents, _rsvpNode, _rsvpAll, _rsvpAllSettled, _rsvpRace, _rsvpHash, _rsvpHashSettled, _rsvpRethrow, _rsvpDefer, _rsvpConfig, _r
66342svpMap, _rsvpResolve, _rsvpReject, _rsvpFilter, _rsvpAsap) {
66343  'use strict';
66344
66345  // defaults
66346  _rsvpConfig.config.async = _rsvpAsap.default;
66347  _rsvpConfig.config.after = function (cb) {
66348    setTimeout(cb, 0);
66349  };
66350  var cast = _rsvpResolve.default;
66351  function async(callback, arg) {
66352    _rsvpConfig.config.async(callback, arg);
66353  }
66354
66355  function on() {
66356    _rsvpConfig.config['on'].apply(_rsvpConfig.config, arguments);
66357  }
66358
66359  function off() {
66360    _rsvpConfig.config['off'].apply(_rsvpConfig.config, arguments);
66361  }
66362
66363  // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
66364  if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {
66365    var callbacks = window['__PROMISE_INSTRUMENTATION__'];
66366    _rsvpConfig.configure('instrument', true);
66367    for (var eventName in callbacks) {
66368      if (callbacks.hasOwnProperty(eventName)) {
66369        on(eventName, callbacks[eventName]);
66370      }
66371    }
66372  }
66373
66374  exports.cast = cast;
66375  exports.Promise = _rsvpPromise.default;
66376  exports.EventTarget = _rsvpEvents.default;
66377  exports.all = _rsvpAll.default;
66378  exports.allSettled = _rsvpAllSettled.default;
66379  exports.race = _rsvpRace.default;
66380  exports.hash = _rsvpHash.default;
66381  exports.hashSettled = _rsvpHashSettled.default;
66382  exports.rethrow = _rsvpRethrow.default;
66383  exports.defer = _rsvpDefer.default;
66384  exports.denodeify = _rsvpNode.default;
66385  exports.configure = _rsvpConfig.configure;
66386  exports.on = on;
66387  exports.off = off;
66388  exports.resolve = _rsvpResolve.default;
66389  exports.reject = _rsvpReject.default;
66390  exports.async = async;
66391  exports.map = _rsvpMap.default;
66392  exports.filter = _rsvpFilter.default;
66393});
66394enifed('rsvp.umd', ['exports', 'rsvp/platform', 'rsvp'], function (exports, _rsvpPlatform, _rsvp) {
66395  'use strict';
66396
66397  var RSVP = {
66398    'race': _rsvp.race,
66399    'Promise': _rsvp.Promise,
66400    'allSettled': _rsvp.allSettled,
66401    'hash': _rsvp.hash,
66402    'hashSettled': _rsvp.hashSettled,
66403    'denodeify': _rsvp.denodeify,
66404    'on': _rsvp.on,
66405    'off': _rsvp.off,
66406    'map': _rsvp.map,
66407    'filter': _rsvp.filter,
66408    'resolve': _rsvp.resolve,
66409    'reject': _rsvp.reject,
66410    'all': _rsvp.all,
66411    'rethrow': _rsvp.rethrow,
66412    'defer': _rsvp.defer,
66413    'EventTarget': _rsvp.EventTarget,
66414    'configure': _rsvp.configure,
66415    'async': _rsvp.async
66416  };
66417
66418  /* global define:true module:true window: true */
66419  if (typeof define === 'function' && define['amd']) {
66420    define(function () {
66421      return RSVP;
66422    });
66423  } else if (typeof module !== 'undefined' && module['exports']) {
66424    module['exports'] = RSVP;
66425  } else if (typeof _rsvpPlatform.default !== 'undefined') {
66426    _rsvpPlatform.default['RSVP'] = RSVP;
66427  }
66428});
66429enifed("vertex", ["exports"], function (exports) {
66430  /**
66431   * DAG Vertex
66432   *
66433   * @class Vertex
66434   * @constructor
66435   */
66436
66437  "use strict";
66438
66439  exports.default = Vertex;
66440
66441  function Vertex(name) {
66442    this.name = name;
66443    this.incoming = {};
66444    this.incomingNames = [];
66445    this.hasOutgoing = false;
66446    this.value = null;
66447  }
66448});
66449enifed("visit", ["exports"], function (exports) {
66450  "use strict";
66451
66452  exports.default = visit;
66453
66454  function visit(vertex, fn, visited, path) {
66455    var name = vertex.name;
66456    var vertices = vertex.incoming;
66457    var names = vertex.incomingNames;
66458    var len = names.length;
66459    var i;
66460
66461    if (!visited) {
66462      visited = {};
66463    }
66464    if (!path) {
66465      path = [];
66466    }
66467    if (visited.hasOwnProperty(name)) {
66468      return;
66469    }
66470    path.push(name);
66471    visited[name] = true;
66472    for (i = 0; i < len; i++) {
66473      visit(vertices[names[i]], fn, visited, path);
66474    }
66475    fn(vertex, path);
66476    path.pop();
66477  }
66478});
66479requireModule("ember");
66480
66481}());
66482
66483;(function() {
66484/* globals define, Ember, jQuery */
66485
66486  function processEmberShims() {
66487    var shims = {
66488      'ember': {
66489        'default': Ember
66490      },
66491      'ember-application': {
66492        'default': Ember.Application
66493      },
66494      'ember-array': {
66495        'default': Ember.Array
66496      },
66497      'ember-array/mutable': {
66498        'default': Ember.MutableArray
66499      },
66500      'ember-array/utils': {
66501        'A':            Ember.A,
66502        'isEmberArray': Ember.isArray,
66503        'wrap':         Ember.makeArray
66504      },
66505      'ember-component': {
66506        'default': Ember.Component
66507      },
66508      'ember-components/checkbox': {
66509        'default': Ember.Checkbox
66510      },
66511      'ember-components/text-area': {
66512        'default': Ember.TextArea
66513      },
66514      'ember-components/text-field': {
66515        'default': Ember.TextField
66516      },
66517      'ember-controller': {
66518        'default': Ember.Controller
66519      },
66520      'ember-controller/inject': {
66521        'default': Ember.inject.controller
66522      },
66523      'ember-controller/proxy': {
66524        'default': Ember.ArrayProxy
66525      },
66526      'ember-controllers/sortable': {
66527        'default': Ember.SortableMixin
66528      },
66529      'ember-debug': {
66530        'log':      Ember.debug,
66531        'inspect':  Ember.inspect,
66532        'run':      Ember.runInDebug,
66533        'warn':     Ember.warn
66534      },
66535      'ember-debug/container-debug-adapter': {
66536        'default': Ember.ContainerDebugAdapter
66537      },
66538      'ember-debug/data-adapter': {
66539        'default': Ember.DataAdapter
66540      },
66541      'ember-deprecations': {
66542        'deprecate':      Ember.deprecate,
66543        'deprecateFunc':  Ember.deprecateFunc
66544      },
66545      'ember-enumerable': {
66546        'default': Ember.Enumerable
66547      },
66548      'ember-evented': {
66549        'default': Ember.Evented
66550      },
66551      'ember-evented/on': {
66552        'default': Ember.on
66553      },
66554      'ember-globals-resolver': {
66555        'default': Ember.DefaultResolver
66556      },
66557      'ember-helper': {
66558        'default':  Ember.Helper,
66559        'helper':   Ember.Helper && Ember.Helper.helper
66560      },
66561      'ember-instrumentation': {
66562        'instrument':   Ember.Instrumentation.instrument,
66563        'reset':        Ember.Instrumentation.reset,
66564        'subscribe':    Ember.Instrumentation.subscribe,
66565        'unsubscribe':  Ember.Instrumentation.unsubscribe
66566      },
66567      'ember-locations/hash': {
66568        'default': Ember.HashLocation
66569      },
66570      'ember-locations/history': {
66571        'default': Ember.HistoryLocation
66572      },
66573      'ember-locations/none': {
66574        'default': Ember.NoneLocation
66575      },
66576      'ember-map': {
66577        'default':      Ember.Map,
66578        'withDefault':  Ember.MapWithDefault
66579      },
66580      'ember-metal/destroy': {
66581        'default': Ember.destroy
66582      },
66583      'ember-metal/events': {
66584        'addListener':    Ember.addListener,
66585        'removeListener': Ember.removeListener,
66586        'send':           Ember.sendEvent
66587      },
66588      'ember-metal/get': {
66589        'default': Ember.get,
66590        'getProperties': Ember.getProperties
66591      },
66592      'ember-metal/mixin': {
66593        'default': Ember.Mixin
66594      },
66595      'ember-metal/observer': {
66596        'default':        Ember.observer,
66597        'addObserver':    Ember.addObserver,
66598        'removeObserver': Ember.removeObserver
66599      },
66600      'ember-metal/on-load': {
66601        'default':  Ember.onLoad,
66602        'run':      Ember.runLoadHooks
66603      },
66604      'ember-metal/set': {
66605        'default':        Ember.set,
66606        'setProperties':  Ember.setProperties,
66607        'trySet':         Ember.trySet
66608      },
66609      'ember-metal/utils': {
66610        'aliasMethod':  Ember.aliasMethod,
66611        'assert':       Ember.assert,
66612        'cacheFor':     Ember.cacheFor,
66613        'copy':         Ember.copy,
66614        'guidFor':      Ember.guidFor
66615      },
66616      'ember-object': {
66617        'default': Ember.Object
66618      },
66619      'ember-platform': {
66620        'assign':         Ember.merge,
66621        'create':         Ember.create,
66622        'defineProperty': Ember.platform.defineProperty,
66623        'hasAccessors':   Ember.platform.hasPropertyAccessors,
66624        'keys':           Ember.keys
66625      },
66626      'ember-route': {
66627        'default': Ember.Route
66628      },
66629      'ember-router': {
66630        'default': Ember.Router
66631      },
66632      'ember-runloop': {
66633        'default':      Ember.run,
66634        'begin':        Ember.run.begin,
66635        'bind':         Ember.run.bind,
66636        'cancel':       Ember.run.cancel,
66637        'debounce':     Ember.run.debounce,
66638        'end':          Ember.run.end,
66639        'join':         Ember.run.join,
66640        'later':        Ember.run.later,
66641        'next':         Ember.run.next,
66642        'once':         Ember.run.once,
66643        'schedule':     Ember.run.schedule,
66644        'scheduleOnce': Ember.run.scheduleOnce,
66645        'throttle':     Ember.run.throttle
66646      },
66647      'ember-service': {
66648        'default': Ember.Service
66649      },
66650      'ember-service/inject': {
66651        'default': Ember.inject.service
66652      },
66653      'ember-set/ordered': {
66654        'default': Ember.OrderedSet
66655      },
66656      'ember-string': {
66657        'camelize':     Ember.String.camelize,
66658        'capitalize':   Ember.String.capitalize,
66659        'classify':     Ember.String.classify,
66660        'dasherize':    Ember.String.dasherize,
66661        'decamelize':   Ember.String.decamelize,
66662        'fmt':          Ember.String.fmt,
66663        'htmlSafe':     Ember.String.htmlSafe,
66664        'loc':          Ember.String.loc,
66665        'underscore':   Ember.String.underscore,
66666        'w':            Ember.String.w
66667      },
66668      'ember-utils': {
66669        'isBlank':    Ember.isBlank,
66670        'isEmpty':    Ember.isEmpty,
66671        'isNone':     Ember.isNone,
66672        'isPresent':  Ember.isPresent,
66673        'tryInvoke':  Ember.tryInvoke,
66674        'typeOf':     Ember.typeOf
66675      }
66676    };
66677
66678    // populate `ember/computed` named exports
66679    shims['ember-computed'] = {
66680      'default': Ember.computed
66681    };
66682    var computedMacros = [
66683      "empty","notEmpty", "none", "not", "bool", "match",
66684      "equal", "gt", "gte", "lt", "lte", "alias", "oneWay",
66685      "reads", "readOnly", "deprecatingAlias",
66686      "and", "or", "collect", "sum", "min", "max",
66687      "map", "sort", "setDiff", "mapBy", "mapProperty",
66688      "filter", "filterBy", "filterProperty", "uniq",
66689      "union", "intersect"
66690    ];
66691    for (var i = 0, l = computedMacros.length; i < l; i++) {
66692      var key = computedMacros[i];
66693      shims['ember-computed'][key] = Ember.computed[key];
66694    }
66695
66696    for (var moduleName in shims) {
66697      generateModule(moduleName, shims[moduleName]);
66698    }
66699  }
66700
66701  function processTestShims() {
66702    if (Ember.Test) {
66703      var testShims = {
66704        'ember-test': {
66705          'default': Ember.Test
66706        },
66707        'ember-test/adapter': {
66708          'default': Ember.Test.Adapter
66709        },
66710        'ember-test/qunit-adapter': {
66711          'default': Ember.Test.QUnitAdapter
66712        }
66713      };
66714
66715      for (var moduleName in testShims) {
66716        generateModule(moduleName, testShims[moduleName]);
66717      }
66718    }
66719  }
66720
66721  function generateModule(name, values) {
66722    define(name, [], function() {
66723      'use strict';
66724
66725      return values;
66726    });
66727  }
66728
66729  processEmberShims();
66730  processTestShims();
66731  generateModule('jquery', { 'default': self.jQuery });
66732  generateModule('rsvp', { 'default': Ember.RSVP });
66733})();
66734
66735;/* globals define */
66736define('ember/load-initializers', ['exports', 'ember-load-initializers', 'ember'], function(exports, loadInitializer
66736s, Ember) {
66737  Ember['default'].deprecate(
66738    'Usage of `' + 'ember/load-initializers' + '` module is deprecated, please update to `ember-load-initializers`.',
66739    false,
66740    { id: 'ember-load-initializers.legacy-shims', until: '3.0.0' }
66741  );
66742
66743  exports['default'] = loadInitializers['default'];
66744});
66745
66746;/* globals define */
66747
66748function createDeprecatedModule(moduleId) {
66749  define(moduleId, ['exports', 'ember-resolver/resolver', 'ember'], function(exports, Resolver, Ember) {
66750    Ember['default'].deprecate(
66751      'Usage of `' + moduleId + '` module is deprecated, please update to `ember-resolver`.',
66752      false,
66753      { id: 'ember-resolver.legacy-shims', until: '3.0.0' }
66754    );
66755
66756    exports['default'] = Resolver['default'];
66757  });
66758}
66759
66760createDeprecatedModule('ember/resolver');
66761createDeprecatedModule('resolver');
66762
66763;define('ember-ajax/errors', ['exports', 'ember'], function (exports, _ember) {
66764  'use strict';
66765
66766  exports.AjaxError = AjaxError;
66767  exports.InvalidError = InvalidError;
66768  exports.UnauthorizedError = UnauthorizedError;
66769  exports.ForbiddenError = ForbiddenError;
66770
66771  var EmberError = _ember['default'].Error;
66772
66773  /**
66774    @class AjaxError
66775    @namespace DS
66776  */
66777
66778  function AjaxError(errors) {
66779    var message = arguments.length <= 1 || arguments[1] === undefined ? 'Ajax operation failed' : arguments[1];
66780
66781    EmberError.call(this, message);
66782
66783    this.errors = errors || [{
66784      title: 'Ajax Error',
66785      detail: message
66786    }];
66787  }
66788
66789  AjaxError.prototype = Object.create(EmberError.prototype);
66790
66791  function InvalidError(errors) {
66792    AjaxError.call(this, errors, 'Request was rejected because it was invali
66792d');
66793  }
66794
66795  InvalidError.prototype = Object.create(AjaxError.prototype);
66796
66797  function UnauthorizedError(errors) {
66798    AjaxError.call(this, errors, 'Ajax authorization failed');
66799  }
66800
66801  UnauthorizedError.prototype = Object.create(AjaxError.prototype);
66802
66803  function ForbiddenError(errors) {
66804    AjaxError.call(this, errors, 'Request was rejected because user is not permitted to perform this operation.');
66805  }
66806
66807  ForbiddenError.prototype = Object.create(AjaxError.prototype);
66808});
66809define('ember-ajax/index', ['exports', 'ember-ajax/request'], function (exports, _emberAjaxRequest) {
66810  'use strict';
66811
66812  Object.defineProperty(exports, 'default', {
66813    enumerable: true,
66814    get: function get() {
66815      return _emberAjaxRequest['default'];
66816    }
66817  });
66818});
66819define('ember-ajax/make-promise', ['exports', 'ember'], function (exports, _ember) {
66820  'use strict';
66821
66822  exports['default'] = makePromise;
66823
66824  var run = _ember['default'].run;
66825  var RSVP = _ember['default'].RSVP;
66826
66827  function makePromise(settings) {
66828    var type = settings.type || 'GET';
66829    return new RSVP.Promise(function (resolve, reject) {
66830      settings.success = makeSuccess(resolve);
66831      settings.error = makeError(reject);
66832      _ember['default'].$.ajax(settings);
66833    }, 'ember-ajax: ' + type + ' to ' + settings.url);
66834  }
66835
66836  function makeSuccess(resolve) {
66837    return function success(response, textStatus, jqXHR) {
66838      run(null, resolve, {
66839        response: response,
66840        textStatus: textStatus,
66841        jqXHR: jqXHR
66842      });
66843    };
66844  }
66845
66846  function makeError(reject) {
66847    return function error(jqXHR, textStatus, errorThrown) {
66848      run(null, reject, {
66849        jqXHR: jqXHR,
66850        textStatus: textStatus,
66851        errorThrown: errorThrown
66852      });
66853    };
66854  }
66855});
66856define('ember-ajax/raw', ['exports', 'ember-ajax/make-promise', 'ember-ajax/utils/parse-args', 'ember'], function (exports, _emberAjaxMakePromise, _emberAjaxUtilsParseArgs, _ember) {
66857  'use strict';
66858
66859  var _slicedToArray = (function () {
66860    function sliceIterator(arr, i) {
66861      var _arr = [];var _n = true;var _d = false;var _e = undefined;try {
66862        for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
66863          _arr.push(_s.value);if (i && _arr.length === i) break;
66864        }
66865      } catch (err) {
66866        _d = true;_e = err;
66867      } finally {
66868        try {
66869          if (!_n && _i['return']) _i['return']();
66870        } finally {
66871          if (_d) throw _e;
66872        }
66873      }return _arr;
66874    }return function (arr, i) {
66875      if (Array.isArray(arr)) {
66876        return arr;
66877      } else if (Symbol.iterator in Object(arr)) {
66878        return sliceIterator(arr, i);
66879      } else {
66880        throw new TypeError('Invalid attempt to destructure non-iterable instance');
66881      }
66882    };
66883  })();
66884
66885  exports['default'] = raw;
66886
66887  var deprecate = _ember['default'].deprecate;
66888
66889  /*
66890   * Same as `request` except it resolves an object with `{response, textStatus,
66891   * jqXHR}`, useful if you need access to the jqXHR object for headers, etc.
66892   */
66893  function raw() {
66894    deprecate('ember-ajax/raw is deprecated and will be removed in [email protected]', false, { id: 'ember-ajax.raw' });
66895
66896    var _parseArgs$apply = _emberAjaxUtilsParseArgs['default'].apply(null, arguments);
66897
66898    var _parseArgs$apply2 = _slicedToArray(_parseArgs$apply, 3);
66899
66900    var url = _parseArgs$apply2[0];
66901    var type = _parseArgs$apply2[1];
66902    var settings = _parseArgs$apply2[2];
66903
66904    if (!settings) {
66905      settings = {};
66906    }
66907    settings.url = url;
66908    settings.type = type;
66909    return (0, _emberAjaxMakePromise['default'])(settings);
66910  }
66911});
66912define('ember-ajax/request', ['exports', 'ember-ajax/raw', 'ember'], function (exports, _emberAjaxRaw, _ember) {
66913  'use strict';
66914
66915  exports['default'] = request;
66916
66917  var deprecate = _ember['default'].deprecate;
66918
66919  /*
66920   * jQuery.ajax wrapper, supports the same signature except providing
66921   * `success` and `error` handlers will throw an error (use promises instead)
66922   * and it resolves only the response (no access to jqXHR or textStatus).
66923   */
66924  function request() {
66925    deprecate('ember-ajax/request is deprecated and will be removed in ember-
66925[email protected]', false, { id: 'ember-ajax.raw' });
66926    return _emberAjaxRaw['default'].apply(undefined, arguments).then(function (result) {
66927      return result.response;
66928    }, null, 'ember-ajax: unwrap raw ajax response');
66929  }
66930});
66931define('ember-ajax/services/ajax', ['exports', 'ember', 'ember-ajax/errors', 'ember-ajax/utils/parse-response-headers'], function (exports, _ember, _emberAjaxErrors, _emberAjaxUtilsParseResponseHeaders) {
66932  'use strict';
66933
66934  var deprecate = _ember['default'].deprecate;
66935  var get = _ember['default'].get;
66936  var isBlank = _ember['default'].isBlank;
66937
66938  /**
66939    ### Headers customization
66940  
66941    Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary
66942    headers can be set as key/value pairs on the `RESTAdapter`'s `headers`
66943    object and Ember Data will send them along with each ajax request.
66944  
66945    ```app/services/ajax
66946    import AjaxService from 'ember-ajax/services/ajax';
66947  
66948    export default AjaxService.extend({
66949      headers: {
66950        "API_KEY": "secret key",
66951        "ANOTHER_HEADER": "Some header value"
66952      }
66953    });
66954    ```
66955  
66956    `headers` can also be used as a computed property to support dynamic
66957    headers.
66958  
66959    ```app/services/ajax.js
66960    import Ember from 'ember';
66961    import AjaxService from 'ember-ajax/services/ajax';
66962  
66963    export default AjaxService.extend({
66964      session: Ember.inject.service(),
66965      headers: Ember.computed("session.authToken", function() {
66966        return {
66967          "API_KEY": this.get("session.authToken"),
66968          "ANOTHER_HEADER": "Some header value"
66969        };
66970      })
66971    });
66972    ```
66973  
66974    In some cases, your dynamic headers may require data from some
66975    object outside of Ember's observer system (for example
66976    `document.cookie`). You can use the
66977    [volatile](/api/classes/Ember.ComputedProperty.html#method_volatile)
66978    function to set the property into a non-cached mode causing the headers to
66979    be recomputed with every request.
66980  
66981    ```app/services/ajax.js
66982    import Ember from 'ember';
66983    import AjaxService from 'ember-ajax/services/ajax';
66984  
66985    export default AjaxService.extend({
66986      session: Ember.inject.service(),
66987      headers: Ember.computed("session.authToken", function() {
66988        return {
66989          "API_KEY": Ember.get(document.cookie.match(/apiKey\=([^;]*)/), "1"),
66990          "ANOTHER_HEADER": "Some header value"
66991        };
66992      }).volatile()
66993    });
66994    ```
66995  
66996  **/
66997  exports['default'] = _ember['default'].Service.extend({
66998
66999    request: function request(url, options) {
67000      var _this = this;
67001
67002      var opts;
67003
67004      if (arguments.length > 2 || typeof options === 'string') {
67005        deprecate('ember-ajax/ajax#request calling request with `type` is deprecated and will be removed in [email protected]. If you want to specify a type pass an object like {type: \'DELETE\'}', false, { id: 'ember-ajax.service.request' });
67006
67007        if (arguments.length > 2) {
67008          opts = arguments[2];
67009          opts.type = options;
67010        } else {
67011          opts = { type: options };
67012        }
67013      } else {
67014        opts = options;
67015      }
67016
67017      var hash = this.options(url, opts);
67018
67019      return new _ember['default'].RSVP.Promise(function (resolve, reject) {
67020
67021        hash.success = function (payload, textStatus, jqXHR) {
67022          var response = _this.handleResponse(jqXHR.status, (0, _emberAjaxUtilsParseResponseHeaders['default'])(jqXHR.getAllResponseHeaders()), payload);
67023
67024          if (response instanceof _emberAjaxErrors.AjaxError) {
67025            reject(response);
67026          } else {
67027            resolve(response);
67028          }
67029        };
67030
67031        hash.error = function (jqXHR, textStatus, errorThrown) {
67032          var error = undefined;
67033
67034          if (!(error instanceof Error)) {
67035            if (errorThrown instanceof Error) {
67036              error = errorThrown;
67037            } else {
67038              error = _this.handleResponse(jqXHR.status, (0, _emberAjaxUtilsParseResponseHeaders['default'])(jqXHR.getAllResponseHeaders()), _this.parseErrorResponse(jqXHR.responseText) || errorThrown);
67039            }
67040          }
67041          reject(error);
67042        };
67043
67044        _ember['default'].$.ajax(hash);
67045      }, 'ember-ajax: ' + hash.type + ' to ' + url);
67046    },
67047
67048    // calls `request()` but forces `options.type` to `POST`
67049    post: function post(url, options) {
67050      return this.request(url, this._addTypeToOptionsFor(options, 'POST'));
67051    },
67052
67053    // calls `request()` but forces `options.type` to `PUT`
67054    put: function put(url, options) {
67055      return this.request(url, this._addTypeToOptionsFor(options, 'PUT'));
67056    },
67057
67058    // calls `request()` but forces `options.type` to `PATCH`
67059    patch: function patch(url, options) {
67060      return this.request(url, this._addTypeToOptionsFor(options, 'PATCH'));
67061    },
67062
67063    // calls `request()` but forces `options.type` to `DELETE`
67064    del: function del(url, options) {
67065      return this.request(url, this._addTypeToOptionsFor(options, 'DELETE'));
67066    },
67067
67068    // forcibly manipulates the options hash to include the HTTP method on the type key
67069    _addTypeToOptionsFor: function _addTypeToOptionsFor(options, method) {
67070      options = options || {};
67071      options.type = method;
67072      return options;
67073    },
67074
67075    /**
67076      @method options
67077      @private
67078      @param {String} url
67079      @param {Object} options
67080      @return {Object}
67081    */
67082    options: function options(url, _options) {
67083      var hash = _options || {};
67084      hash.url = this._buildURL(url);
67085      hash.type = hash.type || 'GET';
67086      hash.dataType = hash.dataType || 'json';
67087      hash.context = this;
67088
67089      var headers = get(this, 'headers');
67090      if (headers !== undefined) {
67091        hash.beforeSend = function (xhr) {
67092          Object.keys(headers).forEach(function (key) {
67093            return xhr.setRequestHeader(key, headers[key]);
67094          });
67095        };
67096      }
67097
67098      return hash;
67099    },
67100
67101    _buildURL: function _buildURL(url) {
67102      var host = get(this, 'host');
67103      if (isBlank(host)) {
67104        return url;
67105      }
67106      var startsWith = String.prototype.startsWith || function (searchString, position) {
67107        position = position || 0;
67108        return this.indexOf(searchString, position) === position;
67109      };
67110      if (startsWith.call(url, '/')) {
67111        return '' + host + url;
67112      } else {
67113        return host + '/' + url;
67114      }
67115    },
67116
67117    /**
67118     Takes an ajax response, and returns the json payload or an error.
67119      By default this hook just returns the json payload passed to it.
67120     You might want to override it in two cases:
67121      1. Your API might return useful results in the response headers.
67122     Response headers are passed in as the second argument.
67123      2. Your API might return errors as successful responses with status code
67124     200 and an Errors text or object.
67125     @method handleResponse
67126     @param  {Number} status
67127     @param  {Object} headers
67128     @param  {Object} payload
67129     @return {Object | DS.AdapterError} response
67130    */
67131    handleResponse: function handleResponse(status, headers, payload) {
67132      if (this.isSuccess(status, headers, payload)) {
67133        return payload;
67134      } else if (this.isUnauthorized(status, headers, payload)) {
67135        return new _emberAjaxErrors.UnauthorizedError(payload.errors);
67136      } else if (this.isForbidden(status, headers, payload)) {
67137        return new _emberAjaxErrors.ForbiddenError(payload.errors);
67138      } else if (this.isInvalid(status, headers, payload)) {
67139        return new _emberAjaxErrors.InvalidError(payload.errors);
67140      }
67141
67142      var errors = this.normalizeErrorResponse(status, headers, payload);
67143
67144      return new _emberAjaxErrors.AjaxError(errors);
67145    },
67146
67147    /**
67148     Default `handleResponse` implementation uses this hook to decide if the
67149     response is a an authorized error.
67150     @method isUnauthorized
67151     @param  {Number} status
67152     @param  {Object} headers
67153     @param  {Object} payload
67154     @return {Boolean}
67155    */
67156    isUnauthorized: function isUnauthorized(status /*, headers, payload */) {
67157      return status === 401;
67158    },
67159
67160    /**
67161       Default `handleResponse` implementation uses this hook to decide if the
67162       response is a forbidden error.
67163       @method isForbidden
67164       @param  {Number} status
67165       @param  {Object} headers
67166       @param  {Object} payload
67167       @return {Boolean}
67168     */
67169    isForbidden: function isForbidden(status /*, headers, payload */) {
67170      return status === 403;
67171    },
67172
67173    /**
67174      Default `handleResponse` implementation uses this hook to decide if the
67175      response is a an invalid error.
67176      @method isInvalid
67177      @param  {Number} status
67178      @param  {Object} headers
67179      @param  {Object} payload
67180      @return {Boolean}
67181    */
67182    isInvalid: function isInvalid(status /*, headers, payload */) {
67183      return status === 422;
67184    },
67185
67186    /**
67187     Default `handleResponse` implementation uses this hook to decide if the
67188     response is a success.
67189     @method isSuccess
67190     @param  {Number} status
67191     @param  {Object} headers
67192     @param  {Object} payload
67193     @return {Boolean}
67194    */
67195    isSuccess: function isSuccess(status /*, headers, payload */) {
67196      return status >= 200 && status < 300 || status === 304;
67197    },
67198
67199    /**
67200      @method parseErrorResponse
67201      @private
67202      @param {String} responseText
67203      @return {Object}
67204    */
67205    parseErrorResponse: function parseErrorResponse(responseText) {
67206      var json = responseText;
67207
67208      try {
67209        json = _ember['default'].$.parseJSON(responseText);
67210      } catch (e) {}
67211
67212      return json;
67213    },
67214
67215    /**
67216      @method normalizeErrorResponse
67217      @private
67218      @param  {Number} status
67219      @param  {Object} headers
67220      @param  {Object} payload
67221      @return {Object} errors payload
67222    */
67223    normalizeErrorResponse: function normalizeErrorResponse(status, headers, payload) {
67224      if (payload && typeof payload === 'object' && payload.errors) {
67225        return payload.errors;
67226      } else {
67227        return [{
67228          status: '' + status,
67229          title: "The backend responded with an error",
67230          detail: '' + payload
67231        }];
67232      }
67233    }
67234  });
67235});
67236define("ember-ajax/utils/parse-args", ["exports"], function (exports) {
67237  "use strict";
67238
67239  var _slicedToArray = (function () {
67240    function sliceIterator(arr, i) {
67241      var _arr = [];var _n = true;var _d = false;var _e = undefined;try {
67242        for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
67243          _arr.push(_s.value);if (i && _arr.length === i) break;
67244        }
67245      } catch (err) {
67246        _d = true;_e = err;
67247      } finally {
67248        try {
67249          if (!_n && _i["return"]) _i["return"]();
67250        } finally {
67251          if (_d) throw _e;
67252        }
67253      }return _arr;
67254    }return function (arr, i) {
67255      if (Array.isArray(arr)) {
67256        return arr;
67257      } else if (Symbol.iterator in Object(arr)) {
67258        return sliceIterator(arr, i);
67259      } else {
67260        throw new TypeError("Invalid attempt to destructure non-iterable instance");
67261      }
67262    };
67263  })();
67264
67265  exports["default"] = parseArgs;
67266
67267  function parseArgs() {
67268    var args = [].slice.apply(arguments);
67269    if (args.length === 1) {
67270      if (typeof args[0] === "string") {
67271        var _args = _slicedToArray(args, 1);
67272
67273        var url = _args[0];
67274
67275        return [url];
67276      } else {
67277        var _args2 = _slicedToArray(args, 1);
67278
67279        var options = _args2[0];
67280        var url = options.url;
67281
67282        delete options.url;
67283        var type = options.type || options.method;
67284        delete options.type;
67285        delete options.method;
67286        return [url, type, options];
67287      }
67288    }
67289    if (args.length === 2) {
67290      var _args3 = _slicedToArray(args, 1);
67291
67292      var url = _args3[0];
67293
67294      if (typeof args[1] === 'object') {
67295        var options = args[1];
67296        var type = options.type || options.method;
67297        delete options.type;
67298        delete options.method;
67299        return [url, type, options];
67300      } else {
67301        var type = args[1];
67302        return [url, type];
67303      }
67304    }
67305    return args;
67306  }
67307});
67308define('ember-ajax/utils/parse-response-headers', ['exports'], function (exports) {
67309  'use strict';
67310
67311  exports['default'] = parseResponseHeaders;
67312
67313  function parseResponseHeaders(headerStr) {
67314    var headers = Object.create(null);
67315    if (!headerStr) {
67316      return headers;
67317    }
67318
67319    var headerPairs = headerStr.split('\r\n');
67320    for (var i = 0; i < headerPairs.length; i++) {
67321      var headerPair = headerPairs[i];
67322      // Can't use split() here because it does the wrong thing
67323      // if the header value has the string ": " in it.
67324      var index = headerPair.indexOf(': ');
67325      if (index > 0) {
67326        var key = headerPair.substring(0, index);
67327        var val = headerPair.substring(index + 2);
67328        headers[key] = val;
67329      }
67330    }
67331
67332    return headers;
67333  }
67334});
67335define('ember-cli-app-version/initializer-factory', ['exports', 'ember'], function (exports, _ember) {
67336  'use strict';
67337
67338  exports['default'] = initializerFactory;
67339
67340  var classify = _ember['default'].String.classify;
67341  var libraries = _ember['default'].libraries;
67342
67343  function initializerFactory(name, version) {
67344    var registered = false;
67345
67346    return function () {
67347      if (!registered && name && version) {
67348        var appName = classify(name);
67349        libraries.register(appName, version);
67350        registered = true;
67351      }
67352    };
67353  }
67354});
67355define("ember-data/-private/adapters", ["exports", "ember-data/adapters/json-api", "ember-data/adapters/rest"], function (exports, _emberDataAdaptersJsonApi, _emberDataAdaptersRest) {
67356  /**
67357    @module ember-data
67358  */
67359
67360  "use strict";
67361
67362  exports.JSONAPIAdapter = _emberDataAdaptersJsonApi["default"];
67363  exports.RESTAdapter = _emberDataAdaptersRest["default"];
67364});
67365define('ember-data/-private/adapters/build-url-mixin', ['exports', 'ember'], function (exports, _ember) {
67366  'use strict';
67367
67368  var get = _ember['default'].get;
67369
67370  /**
67371  
67372    WARNING: This interface is likely to change in order to accomodate https://github.com/emberjs/rfcs/pull/4
67373  
67374    ## Using BuildURLMixin
67375  
67376    To use url building, include the mixin when extending an adapter, and call `buildURL` where needed.
67377    The default behaviour is designed for RESTAdapter.
67378  
67379    ### Example
67380  
67381    ```javascript
67382    export default DS.Adapter.extend(BuildURLMixin, {
67383      findRecord: function(store, type, id, snapshot) {
67384        var url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
67385        return this.ajax(url, 'GET');
67386      }
67387    });
67388    ```
67389  
67390    ### Attributes
67391  
67392    The `host` and `namespace` attributes will be used if defined, and are optional.
67393  
67394    @class BuildURLMixin
67395    @namespace DS
67396  */
67397  exports['default'] = _ember['default'].Mixin.create({
67398    /**
67399      Builds a URL for a given type and optional ID.
67400       By default, it pluralizes the type's name (for example, 'post'
67401      becomes 'posts' and 'person' becomes 'people'). To override the
67402      pluralization see [pathForType](#method_pathForType).
67403       If an ID is specified, it adds the ID to the path generated
67404      for the type, separated by a `/`.
67405       When called by RESTAdapter.findMany() the `id` and `snapshot` parameters
67406      will be arrays of ids and snapshots.
67407       @method buildURL
67408      @param {String} modelName
67409      @param {(String|Array|Object)} id single id or array of ids or query
67410      @param {(DS.Snapshot|Array)} snapshot single snapshot or array of snapshots
67411      @param {String} requestType
67412      @param {Object} query object of query parameters to send for query requests.
67413      @return {String} url
67414    */
67415    buildURL: function buildURL(modelName, id, snapshot, requestType, query) {
67416      switch (requestType) {
67417        case 'findRecord':
67418          return this.urlForFindRecord(id, modelName, snapshot);
67419        case 'findAll':
67420          return this.urlForFindAll(modelName, snapshot);
67421        case 'query':
67422          return this.urlForQuery(query, modelName);
67423        case 'queryRecord':
67424          return this.urlForQueryRecord(query, modelName);
67425        case 'findMany':
67426          return this.urlForFindMany(id, modelName, snapshot);
67427        case 'findHasMany':
67428          return this.urlForFindHasMany(id, modelName, snapshot);
67429        case 'findBelongsTo':
67430          return this.urlForFindBelongsTo(id, modelName, snapshot);
67431        case 'createRecord':
67432          return this.urlForCreateRecord(modelName, snapshot);
67433        case 'updateRecord':
67434          return this.urlForUpdateRecord(id, modelName, snapshot);
67435        case 'deleteRecord':
67436          return this.urlForDeleteRecord(id, modelName, snapshot);
67437        default:
67438          return this._buildURL(modelName, id);
67439      }
67440    },
67441
67442    /**
67443      @method _buildURL
67444      @private
67445      @param {String} modelName
67446      @param {String} id
67447      @return {String} url
67448    */
67449    _buildURL: function _buildURL(modelName, id) {
67450      var url = [];
67451      var host = get(this, 'host');
67452      var prefix = this.urlPrefix();
67453      var path;
67454
67455      if (modelName) {
67456        path = this.pathForType(modelName);
67457        if (path) {
67458          url.push(path);
67459        }
67460      }
67461
67462      if (id) {
67463        url.push(encodeURIComponent(id));
67464      }
67465      if (prefix) {
67466        url.unshift(prefix);
67467      }
67468
67469      url = url.join('/');
67470      if (!host && url && url.charAt(0) !== '/') {
67471        url = '/' + url;
67472      }
67473
67474      return url;
67475    },
67476
67477    /**
67478     * @method urlForFindRecord
67479     * @param {String} id
67480     * @param {String} modelName
67481     * @param {DS.Snapshot} snapshot
67482     * @return {String} url
67483     */
67484    urlForFindRecord: function urlForFindRecord(id, modelName, snapshot) {
67485      return this._buildURL(modelName, id);
67486    },
67487
67488    /**
67489     * @method urlForFindAll
67490     * @param {String} modelName
67491     * @param {DS.SnapshotRecordArray} snapshot
67492     * @return {String} url
67493     */
67494    urlForFindAll: function urlForFindAll(modelName, snapshot) {
67495      return this._buildURL(modelName);
67496    },
67497
67498    /**
67499     * @method urlForQuery
67500     * @param {Object} query
67501     * @param {String} modelName
67502     * @return {String} url
67503     */
67504    urlForQuery: function urlForQuery(query, modelName) {
67505      return this._buildURL(modelName);
67506    },
67507
67508    /**
67509     * @method urlForQueryRecord
67510     * @param {Object} query
67511     * @param {String} modelName
67512     * @return {String} url
67513     */
67514    urlForQueryRecord: function urlForQueryRecord(query, modelName) {
67515      return this._buildURL(modelName);
67516    },
67517
67518    /**
67519     * @method urlForFindMany
67520     * @param {Array} ids
67521     * @param {String} modelName
67522     * @param {Array} snapshots
67523     * @return {String} url
67524     */
67525    urlForFindMany: function urlForFindMany(ids, modelName, snapshots) {
67526      return this._buildURL(modelName);
67527    },
67528
67529    /**
67530     * @method urlForFindHasMany
67531     * @param {String} id
67532     * @param {String} modelName
67533     * @param {DS.Snapshot} snapshot
67534     * @return {String} url
67535     */
67536    urlForFindHasMany: function urlForFindHasMany(id, modelName, snapshot) {
67537      return this._buildURL(modelName, id);
67538    },
67539
67540    /**
67541     * @method urlForFindBelongsTo
67542     * @param {String} id
67543     * @param {String} modelName
67544     * @param {DS.Snapshot} snapshot
67545     * @return {String} url
67546     */
67547    urlForFindBelongsTo: function urlForFindBelongsTo(id, modelName, snapshot) {
67548      return this._buildURL(modelName, id);
67549    },
67550
67551    /**
67552     * @method urlForCreateRecord
67553     * @param {String} modelName
67554     * @param {DS.Snapshot} snapshot
67555     * @return {String} url
67556     */
67557    urlForCreateRecord: function urlForCreateRecord(modelName, snapshot) {
67558      return this._buildURL(modelName);
67559    },
67560
67561    /**
67562     * @method urlForUpdateRecord
67563     * @param {String} id
67564     * @param {String} modelName
67565     * @param {DS.Snapshot} snapshot
67566     * @return {String} url
67567     */
67568    urlForUpdateRecord: function urlForUpdateRecord(id, modelName, snapshot) {
67569      return this._buildURL(modelName, id);
67570    },
67571
67572    /**
67573     * @method urlForDeleteRecord
67574     * @param {String} id
67575     * @param {String} modelName
67576     * @param {DS.Snapshot} snapshot
67577     * @return {String} url
67578     */
67579    urlForDeleteRecord: function urlForDeleteRecord(id, modelName, snapshot) {
67580      return this._buildURL(modelName, id);
67581    },
67582
67583    /**
67584      @method urlPrefix
67585      @private
67586      @param {String} path
67587      @param {String} parentURL
67588      @return {String} urlPrefix
67589    */
67590    urlPrefix: function urlPrefix(path, parentURL) {
67591      var host = get(this, 'host');
67592      var namespace = get(this, 'namespace');
67593
67594      if (!host || host === '/') {
67595        host = '';
67596      }
67597
67598      if (path) {
67599        // Protocol relative url
67600        if (/^\/\//.test(path) || /http(s)?:\/\//.test(path)) {
67601          // Do nothing, the full host is already included.
67602          return path;
67603
67604          // Absolute path
67605        } else if (path.charAt(0) === '/') {
67606            return '' + host + path;
67607            // Relative path
67608          } else {
67609              return parentURL + '/' + path;
67610            }
67611      }
67612
67613      // No path provided
67614      var url = [];
67615      if (host) {
67616        url.push(host);
67617      }
67618      if (namespace) {
67619        url.push(namespace);
67620      }
67621      return url.join('/');
67622    },
67623
67624    /**
67625      Determines the pathname for a given type.
67626       By default, it pluralizes the type's name (for example,
67627      'post' becomes 'posts' and 'person' becomes 'people').
67628       ### Pathname customization
67629       For example if you have an object LineItem with an
67630      endpoint of "/line_items/".
67631       ```app/adapters/application.js
67632      import DS from 'ember-data';
67633       export default DS.RESTAdapter.extend({
67634        pathForType: function(modelName) {
67635          var decamelized = Ember.String.decamelize(modelName);
67636          return Ember.String.pluralize(decamelized);
67637        }
67638      });
67639      ```
67640       @method pathForType
67641      @param {String} modelName
67642      @return {String} path
67643    **/
67644    pathForType: function pathForType(modelName) {
67645      var camelized = _ember['default'].String.camelize(modelName);
67646      return _ember['default'].String.pluralize(camelized);
67647    }
67648  });
67649});
67650define('ember-data/-private/core', ['exports', 'ember', 'ember-data/version'], function (exports, _ember, _emberDataVersion) {
67651  'use strict';
67652
67653  /**
67654    @module ember-data
67655  */
67656
67657  /**
67658    All Ember Data methods and functions are defined inside of this namespace.
67659  
67660    @class DS
67661    @static
67662  */
67663
67664  /**
67665    @property VERSION
67666    @type String
67667    @static
67668  */
67669  var DS = _ember['default'].Namespace.create({
67670    VERSION: _emberDataVersion['default'],
67671    name: "DS"
67672  });
67673
67674  if (_ember['default'].libraries) {
67675    _ember['default'].libraries.registerCoreLibrary('Ember Data', DS.VERSION);
67676  }
67677
67678  exports['default'] = DS;
67679});
67680define('ember-data/-private/debug', ['exports', 'ember'], function (exports, _ember) {
67681  'use strict';
67682
67683  exports.assert = assert;
67684  exports.debug = debug;
67685  exports.deprecate = deprecate;
67686  exports.info = info;
67687  exports.runInDebug = runInDebug;
67688  exports.warn = warn;
67689  exports.debugSeal = debugSeal;
67690  exports.assertPolymorphicType = assertPolymorphicType;
67691
67692  function assert() {
67693    return _ember['default'].assert.apply(_ember['default'], arguments);
67694  }
67695
67696  function debug() {
67697    return _ember['default'].debug.apply(_ember['default'], arguments);
67698  }
67699
67700  function deprecate() {
67701    return _ember['default'].deprecate.apply(_ember['default'], arguments);
67702  }
67703
67704  function info() {
67705    return _ember['default'].info.apply(_ember['default'], arguments);
67706  }
67707
67708  function runInDebug() {
67709    return _ember['default'].runInDebug.apply(_ember['default'], arguments);
67710  }
67711
67712  function warn() {
67713    return _ember['default'].warn.apply(_ember['default'], arguments);
67714  }
67715
67716  function debugSeal() {
67717    return _ember['default'].debugSeal.apply(_ember['default'], arguments);
67718  }
67719
67720  function checkPolymorphic(typeClass, addedRecord) {
67721    if (typeClass.__isMixin) {
67722      //TODO Need to do this in order to support mixins, should convert to public api
67723      //once it exists in Ember
67724      return typeClass.__mixin.detect(addedRecord.type.PrototypeMixin);
67725    }
67726    if (_ember['default'].MODEL_FACTORY_INJECTIONS) {
67727      typeClass = typeClass.superclass;
67728    }
67729    return typeClass.detect(addedRecord.type);
67730  }
67731
67732  /**
67733    Assert that `addedRecord` has a valid type so it can be added to the
67734    relationship of the `record`.
67735  
67736    The assert basically checks if the `addedRecord` can be added to the
67737    relationship (specified via `relationshipMeta`) of the `record`.
67738  
67739    This utility should only be used internally, as both record parameters must
67740    be an InternalModel and the `relationshipMeta` needs to be the meta
67741    information about the relationship, retrieved via
67742    `record.relationshipFor(key)`.
67743  
67744    @method assertPolymorphicType
67745    @param {InternalModel} record
67746    @param {RelationshipMeta} relationshipMeta retrieved via
67747           `record.relationshipFor(key)`
67748    @param {InternalModel} addedRecord record which
67749           should be added/set for the relationship
67750  */
67751
67752  function assertPolymorphicType(record, relationshipMeta, addedRecord) {
67753    var addedType = addedRecord.type.modelName;
67754    var recordType = record.type.modelName;
67755    var key = relationshipMeta.key;
67756    var typeClass = record.store.modelFor(relationshipMeta.type);
67757
67758    var assertionMessage = 'You cannot add a record of type \'' + addedType + '\' to the \'' + recordType + '.' + key + '\' relationship (only \'' + typeClass.modelName + '\' allowed)';
67759
67760    assert(assertionMessage, checkPolymorphic(typeClass, addedRecord));
67761  }
67762});
67763define('ember-data/-private/ext/date', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
67764  /**
67765    @module ember-data
67766  */
67767
67768  'use strict';
67769
67770  _ember['default'].Date = _ember['default'].Date || {};
67771
67772  var origParse = Date.parse;
67773  var numericKeys = [1, 4, 5, 6, 7, 10, 11];
67774
67775  var parseDate = function parseDate(date) {
67776    var timestamp, struct;
67777    var minutesOffset = 0;
67778
67779    // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
67780    // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
67781    // implementations could be faster
67782    //              1 YYYY                2 MM       3 DD           4 HH    5 mm       6 ss        7 msec        8 Z 9 ±    10 tzHH    11 tzmm
67783    if (struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?:(\d{2}))?)?)?$/.exec(date)) {
67784      // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
67785      for (var i = 0, k; k = numericKeys[i]; ++i) {
67786        struct[k] = +struct[k] || 0;
67787      }
67788
67789      // allow undefined days and months
67790      struct[2] = (+struct[2] || 1) - 1;
67791      struct[3] = +struct[3] || 1;
67792
67793      if (struct[8] !== 'Z' && struct[9] !== undefined) {
67794        minutesOffset = struct[10] * 60 + struct[11];
67795
67796        if (struct[9] === '+') {
67797          minutesOffset = 0 - minutesOffset;
67798        }
67799      }
67800
67801      timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
67802    } else {
67803      timestamp = origParse ? origParse(date) : NaN;
67804    }
67805
67806    return timestamp;
67807  };
67808
67809  exports.parseDate = parseDate;
67810
67811  _ember['default'].Date.parse = function (date) {
67812    // throw deprecation
67813    (0, _emberDataPrivateDebug.deprecate)('Ember.Date.parse is deprecated because Safari 5-, IE8-, and\n      Firefox 3.6- are no longer supported (see\n      https://github.com/csnover/js-iso8601 for the history of this issue).\n      Please use Date.parse instead', false, {
67814      id: 'ds.ember.date.parse-deprecate',
67815      until: '3.0.0'
67816    });
67817
67818    return parseDate(date);
67819  };
67820
67821  if (_ember['default'].EXTEND_PROTOTYPES === true || _ember['default'].EXTEND_PROTOTYPES.Date) {
67822    (0, _emberDataPrivateDebug.deprecate)('Overriding Date.parse with Ember.Date.parse is deprecated. Please set ENV.EmberENV.EXTEND_PROTOTYPES.Date to false in config/environment.js\n\n\n// config/environment.js\nENV = {\n  EmberENV: {\n    EXTEND_PROTOTYPES: {\n      Date: false,\n    }\n  }\n}\n', false, {
67823      id: 'ds.date.parse-deprecate',
67824      until: '3.0.0'
67825    });
67826    Date.parse = parseDate;
67827  }
67828});
67829define('ember-data/-private/features', ['exports', 'ember'], function (exports, _ember) {
67830  'use strict';
67831
67832  exports['default'] = isEnabled;
67833
67834  function isEnabled() {
67835    var _Ember$FEATURES;
67836
67837    return (_Ember$FEATURES = _ember['default'].FEATURES).isEnabled.apply(_Ember$FEATURES, arguments);
67838  }
67839});
67840define('ember-data/-private/global', ['exports'], function (exports) {
67841  /* globals global, window, self */
67842
67843  // originally from https://github.com/emberjs/ember.js/blob/c0bd26639f50efd6a03ee5b87035fd200e313b8e/packages/ember-environment/lib/global.js
67844
67845  // from lodash to catch fake globals
67846  'use strict';
67847
67848  function checkGlobal(value) {
67849    return value && value.Object === Object ? value : undefined;
67850  }
67851
67852  // element ids can ruin global miss checks
67853  function checkElementIdShadowing(value) {
67854    return value && value.nodeType === undefined ? value : undefined;
67855  }
67856
67857  // export real global
67858  exports['default'] = checkGlobal(checkElementIdShadowing(typeof global === 'object' && global)) || checkGlobal(typeof self === 'object' && self) || checkGlobal(typeof window === 'object' && window) || new Function('return this')();
67859  // eval outside of strict mode
67860});
67861define("ember-data/-private/initializers/data-adapter", ["exports", "ember-data/-private/system/debug/debug-adapter"], function (exports, _emberDataPrivateSystemDebugDebugAdapter) {
67862  "use strict";
67863
67864  exports["default"] = initializeDebugAdapter;
67865
67866  /**
67867    Configures a registry with injections on Ember applications
67868    for the Ember-Data store. Accepts an optional namespace argument.
67869  
67870    @method initializeStoreInjections
67871    @param {Ember.Registry} registry
67872  */
67873  function initializeDebugAdapter(registry) {
67874    registry.register('data-adapter:main', _emberDataPrivateSystemDebugDebugAdapter["default"]);
67875  }
67876});
67877define('ember-data/-private/initializers/store-injections', ['exports'], function (exports) {
67878  'use strict';
67879
67880  exports['default'] = initializeStoreInjections;
67881
67882  /**
67883    Configures a registry with injections on Ember applications
67884    for the Ember-Data store. Accepts an optional namespace argument.
67885  
67886    @method initializeStoreInjections
67887    @param {Ember.Registry} registry
67888  */
67889  function initializeStoreInjections(registry) {
67890    // registry.injection for Ember < 2.1.0
67891    // application.inject for Ember 2.1.0+
67892    var inject = registry.inject || registry.injection;
67893    inject.call(registry, 'controller', 'store', 'service:store');
67894    inject.call(registry, 'route', 'store', 'service:store');
67895    inject.call(registry, 'data-adapter', 'store', 'service:store');
67896  }
67897});
67898define("ember-data/-private/initializers/store", ["exports", "ember-data/-private/system/store", "ember-data/-private/serializers", "ember-data/-private/adapters"], function (exports, _emberDataPrivateSystemStore, _emberDataPrivateSerializers, _emberDataPrivateAdapters) {
67899  "use strict";
67900
67901  exports["default"] = initializeStore;
67902
67903  function has(applicationOrRegistry, fullName) {
67904    if (applicationOrRegistry.has) {
67905      // < 2.1.0
67906      return applicationOrRegistry.has(fullName);
67907    } else {
67908      // 2.1.0+
67909      return applicationOrRegistry.hasRegistration(fullName);
67910    }
67911  }
67912
67913  /**
67914    Configures a registry for use with an Ember-Data
67915    store. Accepts an optional namespace argument.
67916  
67917    @method initializeStore
67918    @param {Ember.Registry} registry
67919  */
67920  function initializeStore(registry) {
67921    // registry.optionsForType for Ember < 2.1.0
67922    // application.registerOptionsForType for Ember 2.1.0+
67923    var registerOptionsForType = registry.registerOptionsForType || registry.optionsForType;
67924    registerOptionsForType.call(registry, 'serializer', { singleton: false });
67925    registerOptionsForType.call(registry, 'adapter', { singleton: false });
67926
67927    registry.register('serializer:-default', _emberDataPrivateSerializers.JSONSerializer);
67928    registry.register('serializer:-rest', _emberDataPrivateSerializers.RESTSerializer);
67929    registry.register('adapter:-rest', _emberDataPrivateAdapters.RESTAdapter);
67930
67931    registry.register('adapter:-json-api', _emberDataPrivateAdapters.JSONAPIAdapter);
67932    registry.register('serializer:-json-api', _emberDataPrivateSerializers.JSONAPISerializer);
67933
67934    if (!has(registry, 'service:store')) {
67935      registry.register('service:store', _emberDataPrivateSystemStore["default"]);
67936    }
67937  }
67938});
67939define('ember-data/-private/initializers/transforms', ['exports', 'ember-data/-private/transforms'], function (exports, _emberDataPrivateTransforms) {
67940  'use strict';
67941
67942  exports['default'] = initializeTransforms;
67943
67944  /**
67945    Configures a registry for use with Ember-Data
67946    transforms.
67947  
67948    @method initializeTransforms
67949    @param {Ember.Registry} registry
67950  */
67951  function initializeTransforms(registry) {
67952    registry.register('transform:boolean', _emberDataPrivateTransforms.BooleanTransform);
67953    registry.register('transform:date', _emberDataPrivateTransforms.DateTransform);
67954    registry.register('transform:number', _emberDataPrivateTransforms.NumberTransform);
67955    registry.register('transform:string', _emberDataPrivateTransforms.StringTransform);
67956  }
67957});
67958define('ember-data/-private/instance-initializers/initialize-store-service', ['exports'], function (exports) {
67959  'use strict';
67960
67961  exports['default'] = initializeStoreService;
67962
67963  /**
67964   Configures a registry for use with an Ember-Data
67965   store.
67966  
67967   @method initializeStore
67968   @param {Ember.ApplicationInstance} applicationOrRegistry
67969   */
67970  function initializeStoreService(application) {
67971    var container = application.lookup ? application : application.container;
67972    // Eagerly generate the store so defaultStore is populated.
67973    container.lookup('service:store');
67974  }
67975});
67976define("ember-data/-private/serializers", ["exports", "ember-data/serializers/json-api", "ember-data/serializers/json", "ember-data/serializers/rest"], function (exports, _emberDataSerializersJsonApi, _emberDataSerializersJson, _emberDataSerializersRest) {
67977  /**
67978    @module ember-data
67979  */
67980
67981  "use strict";
67982
67983  exports.JSONAPISerializer = _emberDataSerializersJsonApi["default"];
67984  exports.JSONSerializer = _emberDataSerializersJson["default"];
67985  exports.RESTSerializer = _emberDataSerializersRest["default"];
67986});
67987define("ember-data/-private/system/clone-null", ["exports", "ember-data/-private/system/empty-object"], function (exports, _emberDataPrivateSystemEmptyObject) {
67988  "use strict";
67989
67990  exports["default"] = cloneNull;
67991
67992  function cloneNull(source) {
67993    var clone = new _emberDataPrivateSystemEmptyObject["default"]();
67994    for (var key in source) {
67995      clone[key] = source[key];
67996    }
67997    return clone;
67998  }
67999});
68000define('ember-data/-private/system/coerce-id', ['exports'], function (exports) {
68001  'use strict';
68002
68003  exports['default'] = coerceId;
68004
68005  // Used by the store to normalize IDs entering the store.  Despite the fact
68006  // that developers may provide IDs as numbers (e.g., `store.findRecord('person', 1)`),
68007  // it is important that internally we use strings, since IDs may be serialized
68008  // and lose type information.  For example, Ember's router may put a record's
68009  // ID into the URL, and if we later try to deserialize that URL and find the
68010  // corresponding record, we will not know if it is a string or a number.
68011
68012  function coerceId(id) {
68013    return id === null || id === undefined || id === '' ? null : id + '';
68014  }
68015});
68016define('ember-data/-private/system/container-proxy', ['exports', 'ember-data/-private/debug'], function (exports, _emberDataPrivateDebug) {
68017  'use strict';
68018
68019  exports['default'] = ContainerProxy;
68020
68021  /*
68022    This is used internally to enable deprecation of container paths and provide
68023    a decent message to the user indicating how to fix the issue.
68024  
68025    @class ContainerProxy
68026    @namespace DS
68027    @private
68028  */
68029  function ContainerProxy(container) {
68030    this.container = container;
68031  }
68032
68033  ContainerProxy.prototype.aliasedFactory = function (path, preLookup) {
68034    var _this = this;
68035
68036    return {
68037      create: function create() {
68038        if (preLookup) {
68039          preLookup();
68040        }
68041
68042        return _this.container.lookup(path);
68043      }
68044    };
68045  };
68046
68047  ContainerProxy.prototype.registerAlias = function (source, dest, preLookup) {
68048    var factory = this.aliasedFactory(dest, preLookup);
68049
68050    return this.container.register(source, factory);
68051  };
68052
68053  ContainerProxy.prototype.registerDeprecation = function (deprecated, val
68053id) {
68054    var preLookupCallback = function preLookupCallback() {
68055      (0, _emberDataPrivateDebug.deprecate)('You tried to look up \'' + deprecated + '\', but this has been deprecated in favor of \'' + valid + '\'.', false, {
68056        id: 'ds.store.deprecated-lookup',
68057        until: '2.0.0'
68058      });
68059    };
68060
68061    return this.registerAlias(deprecated, valid, preLookupCallback);
68062  };
68063
68064  ContainerProxy.prototype.registerDeprecations = function (proxyPairs) {
68065    var i, proxyPair, deprecated, valid;
68066
68067    for (i = proxyPairs.length; i > 0; i--) {
68068      proxyPair = proxyPairs[i - 1];
68069      deprecated = proxyPair['deprecated'];
68070      valid = proxyPair['valid'];
68071
68072      this.registerDeprecation(deprecated, valid);
68073    }
68074  };
68075});
68076define("ember-data/-private/system/debug", ["exports", "ember-data/-private/system/debug/debug-adapter"], function (exports, _emberDataPrivateSystemDebugDebugAdapter) {
68077  /**
68078    @module ember-data
68079  */
68080
68081  "use strict";
68082
68083  exports["default"] = _emberDataPrivateSystemDebugDebugAdapter["default"];
68084});
68085define('ember-data/-private/system/debug/debug-adapter', ['exports', 'ember', 'ember-data/model'], function (exports, _ember, _emberDataModel) {
68086  /**
68087    @module ember-data
68088  */
68089  'use strict';
68090
68091  var get = _ember['default'].get;
68092  var capitalize = _ember['default'].String.capitalize;
68093  var underscore = _ember['default'].String.underscore;
68094  var assert = _ember['default'].assert;
68095
68096  /*
68097    Extend `Ember.DataAdapter` with ED specific code.
68098  
68099    @class DebugAdapter
68100    @namespace DS
68101    @extends Ember.DataAdapter
68102    @private
68103  */
68104  exports['default'] = _ember['default'].DataAdapter.extend({
68105    getFilters: function getFilters() {
68106      return [{ name: 'isNew', desc: 'New' }, { name: 'isModified', desc: 'Modified' }, { name: 'isClean', desc: 'Clean' }];
68107    },
68108
68109    detect: function detect(typeClass) {
68110      return typeClass !== _emberDataModel['default'] && _emberDataModel['default'].detect(typeClass);
68111    },
68112
68113    columnsForType: function columnsForType(typeClass) {
68114      var columns = [{
68115        name: 'id',
68116        desc: 'Id'
68117      }];
68118      var count = 0;
68119      var self = this;
68120      get(typeClass, 'attributes').forEach(function (meta, name) {
68121        if (count++ > self.attributeLimit) {
68122          return false;
68123        }
68124        var desc = capitalize(underscore(name).replace('_', ' '));
68125        columns.push({ name: name, desc: desc });
68126      });
68127      return columns;
68128    },
68129
68130    getRecords: function getRecords(modelClass, modelName) {
68131      if (arguments.length < 2) {
68132        // Legacy Ember.js < 1.13 support
68133        var containerKey = modelClass._debugContainerKey;
68134        if (containerKey) {
68135          var match = containerKey.match(/model:(.*)/);
68136          if (match) {
68137            modelName = match[1];
68138          }
68139        }
68140      }
68141      assert("Cannot find model name. Please upgrade to Ember.js >= 1.13 for Ember Inspector support", !!modelName);
68142      return this.get('store').peekAll(modelName);
68143    },
68144
68145    getRecordColumnValues: function getRecordColumnValues(record) {
68146      var _this = this;
68147
68148      var count = 0;
68149      var columnValues = { id: get(record, 'id') };
68150
68151      record.eachAttribute(function (key) {
68152        if (count++ > _this.attributeLimit) {
68153          return false;
68154        }
68155        var value = get(record, key);
68156        columnValues[key] = value;
68157      });
68158      return columnValues;
68159    },
68160
68161    getRecordKeywords: function getRecordKeywords(record) {
68162      var keywords = [];
68163      var keys = _ember['default'].A(['id']);
68164      record.eachAttribute(function (key) {
68165        return keys.push(key);
68166      });
68167      keys.forEach(function (key) {
68168        return keywords.push(get(record, key));
68169      });
68170      return keywords;
68171    },
68172
68173    getRecordFilterValues: function getRecordFilterValues(record) {
68174      return {
68175        isNew: record.get('isNew'),
68176        isModified: record.get('hasDirtyAttributes') && !record.get('isNew'),
68177        isClean: !record.get('hasDirtyAttributes')
68178      };
68179    },
68180
68181    getRecordColor: function getRecordColor(record) {
68182      var color = 'black';
68183      if (record.get('isNew')) {
68184        color = 'green';
68185      } else if (record.get('hasDirtyAttributes')) {
68186        color = 'blue';
68187      }
68188      return color;
68189    },
68190
68191    observeRecord: function observeRecord(record, recordUpdated) {
68192      var releaseMethods = _ember['default'].A();
68193      var keysToObserve = _ember['default'].A(['id', 'isNew', 'hasDirtyAttributes']);
68194
68195      record.eachAttribute(function (key) {
68196        return keysToObserve.push(key);
68197      });
68198      var adapter = this;
68199
68200      keysToObserve.forEach(function (key) {
68201        var handler = function handler() {
68202          recordUpdated(adapter.wrapRecord(record));
68203        };
68204        _ember['default'].addObserver(record, key, handler);
68205        releaseMethods.push(function () {
68206          _ember['default'].removeObserver(record, key, handler);
68207        });
68208      });
68209
68210      var release = function release() {
68211        releaseMethods.forEach(function (fn) {
68212          return fn();
68213        });
68214      };
68215
68216      return release;
68217    }
68218  });
68219});
68220define('ember-data/-private/system/debug/debug-info', ['exports', 'ember'], function (exports, _ember) {
68221  'use strict';
68222
68223  exports['default'] = _ember['default'].Mixin.create({
68224
68225    /**
68226      Provides info about the model for debugging purposes
68227      by grouping the properties into more semantic groups.
68228       Meant to be used by debugging tools such as the Chrome Ember Extension.
68229       - Groups all attributes in "Attributes" group.
68230      - Groups all belongsTo relationships in "Belongs To" group.
68231      - Groups all hasMany relationships in "Has Many" group.
68232      - Groups all flags in "Flags" group.
68233      - Flags relationship CPs as expensive properties.
68234       @method _debugInfo
68235      @for DS.Model
68236      @private
68237    */
68238    _debugInfo: function _debugInfo() {
68239      var attributes = ['id'];
68240      var relationships = { belongsTo: [], hasMany: [] };
68241      var expensiveProperties = [];
68242
68243      this.eachAttribute(function (name, meta) {
68244        return attributes.push(name);
68245      });
68246
68247      this.eachRelationship(function (name, relationship) {
68248        relationships[relationship.kind].push(name);
68249        expensiveProperties.push(name);
68250      });
68251
68252      var groups = [{
68253        name: 'Attributes',
68254        properties: attributes,
68255        expand: true
68256      }, {
68257        name: 'Belongs To',
68258        properties: relationships.belongsTo,
68259        expand: true
68260      }, {
68261        name: 'Has Many',
68262        properties: relationships.hasMany,
68263        expand: true
68264      }, {
68265        name: 'Flags',
68266        properties: ['isLoaded', 'hasDirtyAttributes', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
68267      }];
68268
68269      return {
68270        propertyInfo: {
68271          // include all other mixins / properties (not just the grouped ones)
68272          includeOtherProperties: true,
68273          groups: groups,
68274          // don't pre-calculate unless cached
68275          expensiveProperties: expensiveProperties
68276        }
68277      };
68278    }
68279  });
68280});
68281define("ember-data/-private/system/empty-object", ["exports"], function (exports) {
68282  "use strict";
68283
68284  exports["default"] = EmptyObject;
68285
68286  // This exists because `Object.create(null)` is absurdly slow compared
68287  // to `new EmptyObject()`. In either case, you want a null prototype
68288  // when you're treating the object instances as arbitrary dictionaries
68289  // and don't want your keys colliding with build-in methods on the
68290  // default object prototype.
68291  var proto = Object.create(null, {
68292    // without this, we will always still end up with (new
68293    // EmptyObject()).constructor === Object
68294    constructor: {
68295      value: undefined,
68296      enumerable: false,
68297      writable: true
68298    }
68299  });
68300  function EmptyObject() {}
68301
68302  EmptyObject.prototype = proto;
68303});
68304define('ember-data/-private/system/is-array-like', ['exports', 'ember'], function (exports, _ember) {
68305  'use strict';
68306
68307  exports['default'] = isArrayLike;
68308
68309  /*
68310    We're using this to detect arrays and "array-like" objects.
68311  
68312    This is a copy of the `isArray` method found in `ember-runtime/utils` as we're
68313    currently unable to import non-exposed modules.
68314  
68315    This method was previously exposed as `Ember.isArray` but since
68316    https://github.com/emberjs/ember.js/pull/11463 `Ember.isArray` is an alias of
68317    `Array.isArray` hence removing the "array-like" part.
68318   */
68319  function isArrayLike(obj) {
68320    if (!obj || obj.setInterval) {
68321      return false;
68322    }
68323    if (Array.isArray(obj)) {
68324      return true;
68325    }
68326    if (_ember['default'].Array.detect(obj)) {
68327      return true;
68328    }
68329
68330    var type = _ember['default'].typeOf(obj);
68331    if ('array' === type) {
68332      return true;
68333    }
68334    if (obj.length !== undefined && 'object' === type) {
68335      return true;
68336    }
68337    return false;
68338  }
68339});
68340define("ember-data/-private/system/many-array", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/store/common"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemStoreCommon) {
68341  /**
68342    @module ember-data
68343  */
68344  "use strict";
68345
68346  var get = _ember["default"].get;
68347  var set = _ember["default"].set;
68348
68349  /**
68350    A `ManyArray` is a `MutableArray` that represents the contents of a has-many
68351    relationship.
68352  
68353    The `ManyArray` is instantiated lazily the first time the relationship is
68354    requested.
68355  
68356    ### Inverses
68357  
68358    Often, the relationships in Ember Data applications will have
68359    an inverse. For example, imagine the following models are
68360    defined:
68361  
68362    ```app/models/post.js
68363    import DS from 'ember-data';
68364  
68365    export default DS.Model.extend({
68366      comments: DS.hasMany('comment')
68367    });
68368    ```
68369  
68370    ```app/models/comment.js
68371    import DS from 'ember-data';
68372  
68373    export default DS.Model.extend({
68374      post: DS.belongsTo('post')
68375    });
68376    ```
68377  
68378    If you created a new instance of `App.Post` and added
68379    a `App.Comment` record to its `comments` has-many
68380    relationship, you would expect the comment's `post`
68381    property to be set to the post that contained
68382    the has-many.
68383  
68384    We call the record to which a relationship belongs the
68385    relationship's _owner_.
68386  
68387    @class ManyArray
68388    @namespace DS
68389    @extends Ember.Object
68390    @uses Ember.MutableArray, Ember.Evented
68391  */
68392  exports["default"] = _ember["default"].Object.extend(_ember["default"].MutableArray, _ember["default"].Evented, {
68393    init: function init() {
68394      this._super.apply(this, arguments);
68395      this.currentState = _ember["default"].A([]);
68396    },
68397
68398    record: null,
68399
68400    canonicalState: null,
68401    currentState: null,
68402
68403    length: 0,
68404
68405    objectAt: function objectAt(index) {
68406      //Ember observers such as 'firstObject', 'lastObject' might do out of bounds accesses
68407      if (!this.currentState[index]) {
68408        return undefined;
68409      }
68410      return this.currentState[index].getRecord();
68411    },
68412
68413    flushCanonical: function flushCanonical() {
68414      //TODO make this smarter, currently its plenty stupid
68415      var toSet = this.canonicalState.filter(function (internalModel) {
68416        return !internalModel.isDeleted();
68417      });
68418
68419      //a hack for not removing new records
68420      //TODO remove once we have proper diffing
68421      var newRecords = this.currentState.filter(
68422      // only add new records which are not yet in the canonical state of this
68423      // relationship (a new record can be in the canonical state if it has
68424      function (internalModel) {
68425        return internalModel.isNew() && toSet.indexOf(internalModel) === -1;
68426      });
68427      toSet = toSet.concat(newRecords);
68428      var oldLength = this.length;
68429      this.arrayContentWillChange(0, this.length, toSet.length);
68430      // It’s possible the parent side of the relationship may have been unloaded by this point
68431      if ((0, _emberDataPrivateSystemStoreCommon._objectIsAlive)(this)) {
68432        this.set('length', toSet.length);
68433      }
68434      this.currentState = toSet;
68435      this.arrayContentDidChange(0, oldLength, this.length);
68436      //TODO Figure out to notify only on additions and maybe only if unloaded
68437      this.relationship.notifyHasManyChanged();
68438      this.record.updateRecordArrays();
68439    },
68440    /**
68441      `true` if the relationship is polymorphic, `false` otherwise.
68442       @property {Boolean} isPolymorphic
68443      @private
68444    */
68445    isPolymorphic: false,
68446
68447    /**
68448      The loading state of this array
68449       @property {Boolean} isLoaded
68450    */
68451    isLoaded: false,
68452
68453    /**
68454      The relationship which manages this array.
68455       @property {ManyRelationship} relationship
68456      @private
68457    */
68458    relationship: null,
68459
68460    /**
68461      Metadata associated with the request for async hasMany relationships.
68462       Example
68463       Given that the server returns the following JSON payload when fetching a
68464      hasMany relationship:
68465       ```js
68466      {
68467        "comments": [{
68468          "id": 1,
68469          "comment": "This is the first comment",
68470        }, {
68471          // ...
68472        }],
68473         "meta": {
68474          "page": 1,
68475          "total": 5
68476        }
68477      }
68478      ```
68479       You can then access the metadata via the `meta` property:
68480       ```js
68481      post.get('comments').then(function(comments) {
68482        var meta = comments.get('meta');
68483         // meta.page => 1
68484        // meta.total => 5
68485      });
68486      ```
68487       @property {Object} meta
68488      @public
68489    */
68490    meta: null,
68491
68492    internalReplace: function internalReplace(idx, amt, objects) {
68493      if (!objects) {
68494        objects = [];
68495      }
68496      this.arrayContentWillChange(idx, amt, objects.length);
68497      this.currentState.splice.apply(this.currentState, [idx, amt].concat(objects));
68498      this.set('length', this.currentState.length);
68499      this.arrayContentDidChange(idx, amt, objects.length);
68500      if (objects) {
68501        //TODO(Igor) probably needed only for unloaded records
68502        this.relationship.notifyHasManyChanged();
68503      }
68504      this.record.updateRecordArrays();
68505    },
68506
68507    //TODO(Igor) optimize
68508    internalRemoveRecords: function internalRemoveRecords(records) {
68509      var index;
68510      for (var i = 0; i < records.length; i++) {
68511        index = this.currentState.indexOf(records[i]);
68512        this.internalReplace(index, 1);
68513      }
68514    },
68515
68516    //TODO(Igor) optimize
68517    internalAddRecords: function internalAddRecords(records, idx) {
68518      if (idx === undefined) {
68519        idx = this.currentState.length;
68520      }
68521      this.internalReplace(idx, 0, records);
68522    },
68523
68524    replace: function replace(idx, amt, objects) {
68525      var records;
68526      if (amt > 0) {
68527        records = this.currentState.slice(idx, idx + amt);
68528        this.get('relationship').removeRecords(records);
68529      }
68530      if (objects) {
68531        this.get('relationship').addRecords(objects.map(function (obj) {
68532          return obj._internalModel;
68533        }), idx);
68534      }
68535    },
68536    /**
68537      Used for async `hasMany` arrays
68538      to keep track of when they will resolve.
68539       @property {Ember.RSVP.Promise} promise
68540      @private
68541    */
68542    promise: null,
68543
68544    /**
68545      @method loadingRecordsCount
68546      @param {Number} count
68547      @private
68548    */
68549    loadingRecordsCount: function loadingRecordsCount(count) {
68550      this.loadingRecordsCount = count;
68551    },
68552
68553    /**
68554      @method loadedRecord
68555      @private
68556    */
68557    loadedRecord: function loadedRecord() {
68558      this.loadingRecordsCount--;
68559      if (this.loadingRecordsCount === 0) {
68560        set(this, 'isLoaded', true);
68561        this.trigger('didLoad');
68562      }
68563    },
68564
68565    /**
68566      @method reload
68567      @public
68568    */
68569    reload: function reload() {
68570      return this.relationship.reload();
68571    },
68572
68573    /**
68574      Saves all of the records in the `ManyArray`.
68575       Example
68576       ```javascript
68577      store.findRecord('inbox', 1).then(function(inbox) {
68578        inbox.get('messages').then(function(messages) {
68579          messages.forEach(function(message) {
68580            message.set('isRead', true);
68581          });
68582          messages.save()
68583        });
68584      });
68585      ```
68586       @method save
68587      @return {DS.PromiseArray} promise
68588    */
68589    save: function save() {
68590      var manyArray = this;
68591      var promiseLabel = "DS: ManyArray#save " + get(this, 'type');
68592      var promise = _ember["default"].RSVP.all(this.invoke("save"), promiseLabel).then(function (array) {
68593        return manyArray;
68594      }, null, "DS: ManyArray#save return ManyArray");
68595
68596      return _emberDataPrivateSystemPromiseProxies.PromiseArray.create({ promise: promise });
68597    },
68598
68599    /**
68600      Create a child record within the owner
68601       @method createRecord
68602      @private
68603      @param {Object} hash
68604      @return {DS.Model} record
68605    */
68606    createRecord: function createRecord(hash) {
68607      var store = get(this, 'store');
68608      var type = get(this, 'type');
68609      var record;
68610
68611      (0, _emberDataPrivateDebug.assert)("You cannot add '" + type.modelName + "' records to this polymorphic relationship.", !get(this, 'isPolymorphic'));
68612      record = store.createRecord(type.modelName, hash);
68613      this.pushObject(record);
68614
68615      return record;
68616    }
68617  });
68618});
68619// been 'acknowleged' to be in the relationship via a store.push)
68620define("ember-data/-private/system/model", ["exports", "ember-data/-private/system/model/model", "ember-data/attr", "ember-data/-private/system/model/states", "ember-data/-private/system/model/errors"], function (exports, _emberDataPrivateSystemModelModel, _emberDataAttr, _emberDataPrivateSystemModelStates, _emberDataPrivateSystemModelErrors) {
68621  /**
68622    @module ember-data
68623  */
68624
68625  "use strict";
68626
68627  exports.RootState = _emberDataPrivateSystemModelStates["default"];
68628  exports.attr = _emberDataAttr["default"];
68629  exports.Errors = _emberDataPrivateSystemModelErrors["default"];
68630  exports["default"] = _emberDataPrivateSystemModelModel["default"];
68631});
68632define("ember-data/-private/system/model/attr", ["exports", "ember", "ember-data/-private/debug"], function (exports, _ember, _emberDataPrivateDebug) {
68633  "use strict";
68634
68635  var get = _ember["default"].get;
68636  var Map = _ember["default"].Map;
68637
68638  /**
68639    @module ember-data
68640  */
68641
68642  /**
68643    @class Model
68644    @namespace DS
68645  */
68646
68647  var AttrClassMethodsMixin = _ember["default"].Mixin.create({
68648    /**
68649      A map whose keys are the attributes of the model (properties
68650      described by DS.attr) and whose values are the meta object for the
68651      property.
68652       Example
68653       ```app/models/person.js
68654      import DS from 'ember-data';
68655       export default DS.Model.extend({
68656        firstName: attr('string'),
68657        lastName: attr('string'),
68658        birthday: attr('date')
68659      });
68660      ```
68661       ```javascript
68662      import Ember from 'ember';
68663      import Person from 'app/models/person';
68664       var attributes = Ember.get(Person, 'attributes')
68665       attributes.forEach(function(meta, name) {
68666        console.log(name, meta);
68667      });
68668       // prints:
68669      // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
68670      // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
68671      // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
68672      ```
68673       @property attributes
68674      @static
68675      @type {Ember.Map}
68676      @readOnly
68677    */
68678    attributes: _ember["default"].computed(function () {
68679      var _this = this;
68680
68681      var map = Map.create();
68682
68683      this.eachComputedProperty(function (name, meta) {
68684        if (meta.isAttribute) {
68685          (0, _emberDataPrivateDebug.assert)("You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('<type>')` from " + _this.toString(), name !== 'id');
68686
68687          meta.name = name;
68688          map.set(name, meta);
68689        }
68690      });
68691
68692      return map;
68693    }).readOnly(),
68694
68695    /**
68696      A map whose keys are the attributes of the model (properties
68697      described by DS.attr) and whose values are type of transformation
68698      applied to each attribute. This map does not include any
68699      attributes that do not have an transformation type.
68700       Example
68701       ```app/models/person.js
68702      import DS from 'ember-data';
68703       export default DS.Model.extend({
68704        firstName: attr(),
68705        lastName: attr('string'),
68706        birthday: attr('date')
68707      });
68708      ```
68709       ```javascript
68710      import Ember from 'ember';
68711      import Person from 'app/models/person';
68712       var transformedAttributes = Ember.get(Person, 'transformedAttributes')
68713       transformedAttributes.forEach(function(field, type) {
68714        console.log(field, type);
68715      });
68716       // prints:
68717      // lastName string
68718      // birthday date
68719      ```
68720       @property transformedAttributes
68721      @static
68722      @type {Ember.Map}
68723      @readOnly
68724    */
68725    transformedAttributes: _ember["default"].computed(function () {
68726      var map = Map.create();
68727
68728      this.eachAttribute(function (key, meta) {
68729        if (meta.type) {
68730          map.set(key, meta.type);
68731        }
68732      });
68733
68734      return map;
68735    }).readOnly(),
68736
68737    /**
68738      Iterates through the attributes of the model, calling the passed function on each
68739      attribute.
68740       The callback method you provide should have the following signature (all
68741      parameters are optional):
68742       ```javascript
68743      function(name, meta);
68744      ```
68745       - `name` the name of the current property in the iteration
68746      - `meta` the meta object for the attribute property in the iteration
68747       Note that in addition to a callback, you can also pass an optional target
68748      object that will be set as `this` on the context.
68749       Example
68750       ```javascript
68751      import DS from 'ember-data';
68752       var Person = DS.Model.extend({
68753        firstName: attr('string'),
68754        lastName: attr('string'),
68755        birthday: attr('date')
68756      });
68757       Person.eachAttribute(function(name, meta) {
68758        console.log(name, meta);
68759      });
68760       // prints:
68761      // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
68762      // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
68763      // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
68764     ```
68765       @method eachAttribute
68766      @param {Function} callback The callback to execute
68767      @param {Object} [binding] the value to which the callback's `this` should be bound
68768      @static
68769    */
68770    eachAttribute: function eachAttribute(callback, binding) {
68771      get(this, 'attributes').forEach(function (meta, name) {
68772        callback.call(binding, name, meta);
68773      });
68774    },
68775
68776    /**
68777      Iterates through the transformedAttributes of the model, calling
68778      the passed function on each attribute. Note the callback will not be
68779      called for any attributes that do not have an transformation type.
68780       The callback method you provide should have the following signature (all
68781      parameters are optional):
68782       ```javascript
68783      function(name, type);
68784      ```
68785       - `name` the name of the current property in the iteration
68786      - `type` a string containing the name of the type of transformed
68787        applied to the attribute
68788       Note that in addition to a callback, you can also pass an optional target
68789      object that will be set as `this` on the context.
68790       Example
68791       ```javascript
68792      import DS from 'ember-data';
68793       var Person = DS.Model.extend({
68794        firstName: attr(),
68795        lastName: attr('string'),
68796        birthday: attr('date')
68797      });
68798       Person.eachTransformedAttribute(function(name, type) {
68799        console.log(name, type);
68800      });
68801       // prints:
68802      // lastName string
68803      // birthday date
68804     ```
68805       @method eachTransformedAttribute
68806      @param {Function} callback The callback to execute
68807      @param {Object} [binding] the value to which the callback's `this` should be bound
68808      @static
68809    */
68810    eachTransformedAttribute: function eachTransformedAttribute(callback, binding) {
68811      get(this, 'transformedAttributes').forEach(function (type, name) {
68812        callback.call(binding, name, type);
68813      });
68814    }
68815  });
68816
68817  exports.AttrClassMethodsMixin = AttrClassMethodsMixin;
68818
68819  var AttrInstanceMethodsMixin = _ember["default"].Mixin.create({
68820    eachAttribute: function eachAttribute(callback, binding) {
68821      this.constructor.eachAttribute(callback, binding);
68822    }
68823  });
68824  exports.AttrInstanceMethodsMixin = AttrInstanceMethodsMixin;
68825});
68826define('ember-data/-private/system/model/errors', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
68827  'use strict';
68828
68829  var get = _ember['default'].get;
68830  var set = _ember['default'].set;
68831  var isEmpty = _ember['default'].isEmpty;
68832  var makeArray = _ember['default'].makeArray;
68833
68834  var MapWithDefault = _ember['default'].MapWithDefault;
68835
68836  /**
68837  @module ember-data
68838  */
68839
68840  /**
68841    Holds validation errors for a given record, organized by attribute names.
68842  
68843    Every `DS.Model` has an `errors` property that is an instance of
68844    `DS.Errors`. This can be used to display validation error
68845    messages returned from the server when a `record.save()` rejects.
68846  
68847    For Example, if you had a `User` model that looked like this:
68848  
68849    ```app/models/user.js
68850    import DS from 'ember-data';
68851  
68852    export default DS.Model.extend({
68853      username: attr('string'),
68854      email: attr('string')
68855    });
68856    ```
68857    And you attempted to save a record that did not validate on the backend:
68858  
68859    ```javascript
68860    var user = store.createRecord('user', {
68861      username: 'tomster',
68862      email: 'invalidEmail'
68863    });
68864    user.save();
68865    ```
68866  
68867    Your backend would be expected to return an error response that described
68868    the problem, so that error messages can be generated on the app.
68869  
68870    API responses will be translated into instances of `DS.Errors` differently,
68871    depending on the specific combination of adapter and serializer used. You
68872    may want to check the documentation or the source code of the libraries
68873    that you are using, to know how they expect errors to be communicated.
68874  
68875    Errors can be displayed to the user by accessing their property name
68876    to get an array of all the error objects for that property. Each
68877    error object is a JavaScript object with two keys:
68878  
68879    - `message` A string containing the error message from the backend
68880    - `attribute` The name of the property associated with this error message
68881  
68882    ```handlebars
68883    <label>Username: {{input value=username}} </label>
68884    {{#each model.errors.username as |error|}}
68885      <div class="error">
68886        {{error.message}}
68887      </div>
68888    {{/each}}
68889  
68890    <label>Email: {{input value=email}} </label>
68891    {{#each model.errors.email as |error|}}
68892      <div class="error">
68893        {{error.message}}
68894      </div>
68895    {{/each}}
68896    ```
68897  
68898    You can also access the special `messages` property on the error
68899    object to get an array of all the error strings.
68900  
68901    ```handlebars
68902    {{#each model.errors.messages as |message|}}
68903      <div class="error">
68904        {{message}}
68905      </div>
68906    {{/each}}
68907    ```
68908  
68909    @class Errors
68910    @namespace DS
68911    @extends Ember.Object
68912    @uses Ember.Enumerable
68913    @uses Ember.Evented
68914   */
68915  exports['default'] = _ember['default'].ArrayProxy.extend(_ember['default'].Evented, {
68916    /**
68917      Register with target handler
68918       @method registerHandlers
68919      @param {Object} target
68920      @param {Function} becameInvalid
68921      @param {Function} becameValid
68922      @deprecated
68923    */
68924    registerHandlers: function registerHandlers(target, becameInvalid, becameValid) {
68925      (0, _emberDataPrivateDebug.deprecate)('Record errors will no longer be evented.', false, {
68926        id: 'ds.errors.registerHandlers',
68927        until: '3.0.0'
68928      });
68929
68930      this._registerHandlers(target, becameInvalid, becameValid);
68931    },
68932
68933    /**
68934      Register with target handler
68935       @method _registerHandlers
68936      @private
68937    */
68938    _registerHandlers: function _registerHandlers(target, becameInvalid, becameValid) {
68939      this.on('becameInvalid', target, becameInvalid);
68940      this.on('becameValid', target, becameValid);
68941    },
68942
68943    /**
68944      @property errorsByAttributeName
68945      @type {Ember.MapWithDefault}
68946      @private
68947    */
68948    errorsByAttributeName: _ember['default'].computed(function () {
68949      return MapWithDefault.create({
68950        defaultValue: function defaultValue() {
68951          return _ember['default'].A();
68952        }
68953      });
68954    }),
68955
68956    /**
68957      Returns errors for a given attribute
68958       ```javascript
68959      var user = store.createRecord('user', {
68960        username: 'tomster',
68961        email: 'invalidEmail'
68962      });
68963      user.save().catch(function(){
68964        user.get('errors').errorsFor('email'); // returns:
68965        // [{attribute: "email", message: "Doesn't look like a valid email."}]
68966      });
68967      ```
68968       @method errorsFor
68969      @param {String} attribute
68970      @return {Array}
68971    */
68972    errorsFor: function errorsFor(attribute) {
68973      return get(this, 'errorsByAttributeName').get(attribute);
68974    },
68975
68976    /**
68977      An array containing all of the error messages for this
68978      record. This is useful for displaying all errors to the user.
68979       ```handlebars
68980      {{#each model.errors.messages as |message|}}
68981        <div class="error">
68982          {{message}}
68983        </div>
68984      {{/each}}
68985      ```
68986       @property messages
68987      @type {Array}
68988    */
68989    messages: _ember['default'].computed.mapBy('content', 'message'),
68990
68991    /**
68992      @property content
68993      @type {Array}
68994      @private
68995    */
68996    content: _ember['default'].computed(function () {
68997      return _ember['default'].A();
68998    }),
68999
69000    /**
69001      @method unknownProperty
69002      @private
69003    */
69004    unknownProperty: function unknownProperty(attribute) {
69005      var errors = this.errorsFor(attribute);
69006      if (isEmpty(errors)) {
69007        return null;
69008      }
69009      return errors;
69010    },
69011
69012    /**
69013      Total number of errors.
69014       @property length
69015      @type {Number}
69016      @readOnly
69017    */
69018
69019    /**
69020      @property isEmpty
69021      @type {Boolean}
69022      @readOnly
69023    */
69024    isEmpty: _ember['default'].computed.not('length').readOnly(),
69025
69026    /**
69027      Adds error messages to a given attribute and sends
69028      `becameInvalid` event to the record.
69029       Example:
69030       ```javascript
69031      if (!user.get('username') {
69032        user.get('errors').add('username', 'This field is required');
69033      }
69034      ```
69035       @method add
69036      @param {String} attribute
69037      @param {(Array|String)} messages
69038      @deprecated
69039    */
69040    add: function add(attribute, messages) {
69041      (0, _emberDataPrivateDebug.warn)('Interacting with a record errors object will no longer change the record state.', false, {
69042        id: 'ds.errors.add'
69043      });
69044
69045      var wasEmpty = get(this, 'isEmpty');
69046
69047      this._add(attribute, messages);
69048
69049      if (wasEmpty && !get(this, 'isEmpty')) {
69050        this.trigger('becameInvalid');
69051      }
69052    },
69053
69054    /**
69055      Adds error messages to a given attribute without sending event.
69056       @method _add
69057      @private
69058    */
69059    _add: function _add(attribute, messages) {
69060      messages = this._findOrCreateMessages(attribute, messages);
69061      this.addObjects(messages);
69062      get(this, 'errorsByAttributeName').get(attribute).addObjects(messages);
69063
69064      this.notifyPropertyChange(attribute);
69065    },
69066
69067    /**
69068      @method _findOrCreateMessages
69069      @private
69070    */
69071    _findOrCreateMessages: function _findOrCreateMessages(attribute, messages) {
69072      var errors = this.errorsFor(attribute);
69073      var messagesArray = makeArray(messages);
69074      var _messages = new Array(messagesArray.length);
69075
69076      for (var i = 0; i < messagesArray.length; i++) {
69077        var message = messagesArray[i];
69078        var err = errors.findBy('message', message);
69079        if (err) {
69080          _messages[i] = err;
69081        } else {
69082          _messages[i] = {
69083            attribute: attribute,
69084            message: message
69085          };
69086        }
69087      }
69088
69089      return _messages;
69090    },
69091
69092    /**
69093      Removes all error messages from the given attribute and sends
69094      `becameValid` event to the record if there no more errors left.
69095       Example:
69096       ```app/models/user.js
69097      import DS from 'ember-data';
69098       export default DS.Model.extend({
69099        email: DS.attr('string'),
69100        twoFactorAuth: DS.attr('boolean'),
69101        phone: DS.attr('string')
69102      });
69103      ```
69104       ```app/routes/user/edit.js
69105      import Ember from 'ember';
69106       export default Ember.Route.extend({
69107        actions: {
69108          save: function(user) {
69109             if (!user.get('twoFactorAuth')) {
69110               user.get('errors').remove('phone');
69111             }
69112             user.save();
69113           }
69114        }
69115      });
69116      ```
69117       @method remove
69118      @param {String} attribute
69119      @deprecated
69120    */
69121    remove: function remove(attribute) {
69122      (0, _emberDataPrivateDebug.warn)('Interacting with a record errors object will no longer change the record state.', false, {
69123        id: 'ds.errors.remove'
69124      });
69125
69126      if (get(this, 'isEmpty')) {
69127        return;
69128      }
69129
69130      this._remove(attribute);
69131
69132      if (get(this, 'isEmpty')) {
69133        this.trigger('becameValid');
69134      }
69135    },
69136
69137    /**
69138      Removes all error messages from the given attribute without sending event.
69139       @method _remove
69140      @private
69141    */
69142    _remove: function _remove(attribute) {
69143      if (get(this, 'isEmpty')) {
69144        return;
69145      }
69146
69147      var content = this.rejectBy('attribute', attribute);
69148      set(this, 'content', content);
69149      get(this, 'errorsByAttributeName')['delete'](attribute);
69150
69151      this.notifyPropertyChange(attribute);
69152    },
69153
69154    /**
69155      Removes all error messages and sends `becameValid` event
69156      to the record.
69157       Example:
69158       ```app/routes/user/edit.js
69159      import Ember from 'ember';
69160       export default Ember.Route.extend({
69161        actions: {
69162          retrySave: function(user) {
69163             user.get('errors').clear();
69164             user.save();
69165           }
69166        }
69167      });
69168      ```
69169       @method clear
69170      @deprecated
69171    */
69172    clear: function clear() {
69173      (0, _emberDataPrivateDebug.warn)('Interacting with a record errors object will no longer change the record state.', false, {
69174        id: 'ds.errors.clear'
69175      });
69176
69177      if (get(this, 'isEmpty')) {
69178        return;
69179      }
69180
69181      this._clear();
69182      this.trigger('becameValid');
69183    },
69184
69185    /**
69186      Removes all error messages.
69187      to the record.
69188       @method _clear
69189      @private
69190    */
69191    _clear: function _clear() {
69192      if (get(this, 'isEmpty')) {
69193        return;
69194      }
69195
69196      var errorsByAttributeName = get(this, 'errorsByAttributeName');
69197      var attributes = _ember['default'].A();
69198
69199      errorsByAttributeName.forEach(function (_, attribute) {
69200        attributes.push(attribute);
69201      });
69202
69203      errorsByAttributeName.clear();
69204      attributes.forEach(function (attribute) {
69205        this.notifyPropertyChange(attribute);
69206      }, this);
69207
69208      _ember['default'].ArrayProxy.prototype.clear.call(this);
69209    },
69210
69211    /**
69212      Checks if there is error messages for the given attribute.
69213       ```app/routes/user/edit.js
69214      import Ember from 'ember';
69215       export default Ember.Route.extend({
69216        actions: {
69217          save: function(user) {
69218             if (user.get('errors').has('email')) {
69219               return alert('Please update your email before attempting to save.');
69220             }
69221             user.save();
69222           }
69223        }
69224      });
69225      ```
69226       @method has
69227      @param {String} attribute
69228      @return {Boolean} true if there some errors on given attribute
69229    */
69230    has: function has(attribute) {
69231      return !isEmpty(this.errorsFor(attribute));
69232    }
69233  });
69234});
69235define("ember-data/-private/system/model/internal-model", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/model/states", "ember-data/-private/system/relationships/state/create", "ember-data/-private/system/snapshot", "ember-data/-private/system/empty-object", "ember-data/-private/utils", "ember-data/-private/system/references"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemModelStates, _emberDataPrivateSystemRelationshipsStateCreate, _emberDataPrivateSystemSnapshot, _emberDataPrivateSystemEmptyObject, _emberDataPrivateUtils, _emberDataPrivateSystemReferences) {
69236  "use strict";
69237
69238  var _slicedToArray = (function () {
69239    function sliceIterator(arr, i) {
69240      var _arr = [];var _n = true;var _d = false;var _e = undefined;try {
69241        for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
69242          _arr.push(_s.value);if (i && _arr.length === i) break;
69243        }
69244      } catch (err) {
69245        _d = true;_e = err;
69246      } finally {
69247        try {
69248          if (!_n && _i["return"]) _i["return"]();
69249        } finally {
69250          if (_d) throw _e;
69251        }
69252      }return _arr;
69253    }return function (arr, i) {
69254      if (Array.isArray(arr)) {
69255        return arr;
69256      } else if (Symbol.iterator in Object(arr)) {
69257        return sliceIterator(arr, i);
69258      } else {
69259        throw new TypeError("Invalid attempt to destructure non-iterable instance");
69260      }
69261    };
69262  })();
69263
69264  exports["default"] = InternalModel;
69265
69266  var Promise = _ember["default"].RSVP.Promise;
69267  var get = _ember["default"].get;
69268  var set = _ember["default"].set;
69269  var copy = _ember["default"].copy;
69270  var assign = _ember["default"].assign || _ember["default"].merge;
69271
69272  var _extractPivotNameCache = new _emberDataPrivateSystemEmptyObject["default"]();
69273  var _splitOnDotCache = new _emberDataPrivateSystemEmptyObject["default"]();
69274
69275  function splitOnDot(name) {
69276    return _splitOnDotCache[name] || (_splitOnDotCache[name] = name.split('.'));
69277  }
69278
69279  function extractPivotName(name) {
69280    return _extractPivotNameCache[name] || (_extractPivotNameCache[name] = splitOnDot(name)[0]);
69281  }
69282
69283  function retrieveFromCurrentState(key) {
69284    return function () {
69285      return get(this.currentState, key);
69286    };
69287  }
69288
69289  var guid = 0;
69290  /*
69291    `InternalModel` is the Model class that we use internally inside Ember Data to represent models.
69292    Internal ED methods should only deal with `InternalModel` objects. It is a fast, plain Javascript class.
69293  
69294    We expose `DS.Model` to application code, by materializing a `DS.Model` from `InternalModel` lazily, as
69295    a performance optimization.
69296  
69297    `InternalModel` should never be exposed to application code. At the boundaries of the system, in places
69298    like `find`, `push`, etc. we convert between Models and InternalModels.
69299  
69300    We need to make sure that the properties from `InternalModel` are correctly exposed/proxied on `Model`
69301    if they are needed.
69302  
69303    @private
69304    @class InternalModel
69305  */
69306  function InternalModel(type, id, store, _, data) {
69307    this.type = type;
69308    this.id = id;
69309    this.store = store;
69310    this._data = data || new _emberDataPrivateSystemEmptyObject["default"]();
69311    this.modelName = type.modelName;
69312    this.dataHasInitialized = false;
69313    //Look into making this lazy
69314    this._deferredTriggers = [];
69315    this._attributes = new _emberDataPrivateSystemEmptyObject["default"]();
69316    this._inFlightAttributes = new _emberDataPrivateSystemEmptyObject["default"]();
69317    this._relationships = new _emberDataPrivateSystemRelationshipsStateCreate["default"](this);
69318    this._recordArrays = undefined;
69319    this.currentState = _emberDataPrivateSystemModelStates["default"].empty;
69320    this.recordReference = new _emberDataPrivateSystemReferences.RecordReference(store, this);
69321    this.references = {};
69322    this.isReloading = false;
69323    this.isError = false;
69324    this.error = null;
69325    this.__ember_meta__ = null;
69326    this[_ember["default"].GUID_KEY] = guid++ + 'internal-model';
69327    /*
69328      implicit relationships are relationship which have not been declared but the inverse side exists on
69329      another record somewhere
69330      For example if there was
69331       ```app/models/comment.js
69332      import DS from 'ember-data';
69333       export default DS.Model.extend({
69334        name: DS.attr()
69335      })
69336      ```
69337       but there is also
69338       ```app/models/post.js
69339      import DS from 'ember-data';
69340       export default DS.Model.extend({
69341        name: DS.attr(),
69342        comments: DS.hasMany('comment')
69343      })
69344      ```
69345       would have a implicit post relationship in order to be do things like remove ourselves from the post
69346      when we are deleted
69347    */
69348    this._implicitRelationships = new _emberDataPrivateSystemEmptyObject["default"]();
69349  }
69350
69351  InternalModel.prototype = {
69352    isEmpty: retrieveFromCurrentState('isEmpty'),
69353    isLoading: retrieveFromCurrentState('isLoading'),
69354    isLoaded: retrieveFromCurrentState('isLoaded'),
69355    hasDirtyAttributes: retrieveFromCurrentState('hasDirtyAttributes'),
69356    isSaving: retrieveFromCurrentState('isSaving'),
69357    isDeleted: retrieveFromCurrentState('isDeleted'),
69358    isNew: retrieveFromCurrentState('isNew'),
69359    isValid: retrieveFromCurrentState('isValid'),
69360    dirtyType: retrieveFromCurrentState('dirtyType'),
69361
69362    constructor: InternalModel,
69363    materializeRecord: function materializeRecord() {
69364      (0, _emberDataPrivateDebug.assert)("Materialized " + this.modelName + " record with id:" + this.id + "more than once", this.record === null || this.record === undefined);
69365
69366      // lookupFactory should really return an object that creates
69367      // instances with the injections applied
69368      var createOptions = {
69369        store: this.store,
69370        _internalModel: this,
69371        id: this.id,
69372        currentState: get(this, 'currentState'),
69373        isError: this.isError,
69374        adapterError: this.error
69375      };
69376
69377      if (_ember["default"].setOwner) {
69378        // ensure that `Ember.getOwner(this)` works inside a model instance
69379        _ember["default"].setOwner(createOptions, (0, _emberDataPrivateUtils.getOwner)(this.store));
69380      } else {
69381        createOptions.container = this.store.container;
69382      }
69383
69384      this.record = this.type._create(createOptions);
69385
69386      this._triggerDeferredTriggers();
69387    },
69388
69389    recordObjectWillDestroy: function recordObjectWillDestroy() {
69390      this.record = null;
69391    },
69392
69393    deleteRecord: function deleteRecord() {
69394      this.send('deleteRecord');
69395    },
69396
69397    save: function save(options) {
69398      var promiseLabel = "DS: Model#save " + this;
69399      var resolver = _ember["default"].RSVP.defer(promiseLabel);
69400
69401      this.store.scheduleSave(this, resolver, options);
69402      return resolver.promise;
69403    },
69404
69405    startedReloading: function startedReloading() {
69406      this.isReloading = true;
69407      if (this.record) {
69408        set(this.record, 'isReloading', true);
69409      }
69410    },
69411
69412    finishedReloading: function finishedReloading() {
69413      this.isReloading = false;
69414      if (this.record) {
69415        set(this.record, 'isReloading', false);
69416      }
69417    },
69418
69419    reload: function reload() {
69420      this.startedReloading();
69421      var record = this;
69422      var promiseLabel = "DS: Model#reload of " + this;
69423      return new Promise(function (resolve) {
69424        record.send('reloadRecord', resolve);
69425      }, promiseLabel).then(function () {
69426        record.didCleanError();
69427        return record;
69428      }, function (error) {
69429        record.didError(error);
69430        throw error;
69431      }, "DS: Model#reload complete, update flags")["finally"](function () {
69432        record.finishedReloading();
69433        record.updateRecordArrays();
69434      });
69435    },
69436
69437    getRecord: function getRecord() {
69438      if (!this.record) {
69439        this.materializeRecord();
69440      }
69441      return this.record;
69442    },
69443
69444    unloadRecord: function unloadRecord() {
69445      this.send('unloadRecord');
69446    },
69447
69448    eachRelationship: function eachRelationship(callback, binding) {
69449      return this.type.eachRelationship(callback, binding);
69450    },
69451
69452    eachAttribute: function eachAttribute(callback, binding) {
69453      return this.type.eachAttribute(callback, binding);
69454    },
69455
69456    inverseFor: function inverseFor(key) {
69457      return this.type.inverseFor(key);
69458    },
69459
69460    setupData: function setupData(data) {
69461      var changedKeys = this._changedKeys(data.attributes);
69462      assign(this._data, data.attributes);
69463      this.pushedData();
69464      if (this.record) {
69465        this.record._notifyProperties(changedKeys);
69466      }
69467      this.didInitalizeData();
69468    },
69469
69470    becameReady: function becameReady() {
69471      _ember["default"].run.schedule('actions', this.store.recordArrayManager, this.store.recordArrayManager.recordWasLoaded, this);
69472    },
69473
69474    didInitalizeData: function didInitalizeData() {
69475      if (!this.dataHasInitialized) {
69476        this.becameReady();
69477        this.dataHasInitialized = true;
69478      }
69479    },
69480
69481    destroy: function destroy() {
69482      if (this.record) {
69483        return this.record.destroy();
69484      }
69485    },
69486
69487    /*
69488      @method createSnapshot
69489      @private
69490    */
69491    createSnapshot: function createSnapshot(options) {
69492      return new _emberDataPrivateSystemSnapshot["default"](this, options);
69493    },
69494
69495    /*
69496      @method loadingData
69497      @private
69498      @param {Promise} promise
69499    */
69500    loadingData: function loadingData(promise) {
69501      this.send('loadingData', promise);
69502    },
69503
69504    /*
69505      @method loadedData
69506      @private
69507    */
69508    loadedData: function loadedData() {
69509      this.send('loadedData');
69510      this.didInitalizeData();
69511    },
69512
69513    /*
69514      @method notFound
69515      @private
69516    */
69517    notFound: function notFound() {
69518      this.send('notFound');
69519    },
69520
69521    /*
69522      @method pushedData
69523      @private
69524    */
69525    pushedData: function pushedData() {
69526      this.send('pushedData');
69527    },
69528
69529    flushChangedAttributes: function flushChangedAttributes() {
69530      this._inFlightAttributes = this._attributes;
69531      this._attributes = new _emberDataPrivateSystemEmptyObject["default"]();
69532    },
69533
69534    hasChangedAttributes: function hasChangedAttributes() {
69535      return Object.keys(this._attributes).length > 0;
69536    },
69537
69538    /*
69539      Checks if the attributes which are considered as changed are still
69540      different to the state which is acknowledged by the server.
69541       This method is needed when data for the internal model is pushed and the
69542      pushed data might acknowledge dirty attributes as confirmed.
69543       @method updateChangedAttributes
69544      @private
69545     */
69546    updateChangedAttributes: function updateChangedAttributes() {
69547      var changedAttributes = this.changedAttributes();
69548      var changedAttributeNames = Object.keys(changedAttributes);
69549
69550      for (var i = 0, _length = changedAttributeNames.length; i < _length; i++) {
69551        var attribute = changedAttributeNames[i];
69552
69553        var _changedAttributes$attribute = _slicedToArray(changedAttributes[attribute], 2);
69554
69555        var oldData = _changedAttributes$attribute[0];
69556        var newData = _changedAttributes$attribute[1];
69557
69558        if (oldData === newData) {
69559          delete this._attributes[attribute];
69560        }
69561      }
69562    },
69563
69564    /*
69565      Returns an object, whose keys are changed properties, and value is an
69566      [oldProp, newProp] array.
69567       @method changedAttributes
69568      @private
69569    */
69570    changedAttributes: function changedAttributes() {
69571      var oldData = this._data;
69572      var currentData = this._attributes;
69573      var inFlightData = this._inFlightAttributes;
69574      var newData = assign(copy(inFlightData), currentData);
69575      var diffData = new _emberDataPrivateSystemEmptyObject["default"]();
69576
69577      var newDataKeys = Object.keys(newData);
69578
69579      for (var i = 0, _length2 = newDataKeys.length; i < _length2; i++) {
69580        var key = newDataKeys[i];
69581        diffData[key] = [oldData[key], newData[key]];
69582      }
69583
69584      return diffData;
69585    },
69586
69587    /*
69588      @method adapterWillCommit
69589      @private
69590    */
69591    adapterWillCommit: function adapterWillCommit() {
69592      this.send('willCommit');
69593    },
69594
69595    /*
69596      @method adapterDidDirty
69597      @private
69598    */
69599    adapterDidDirty: function adapterDidDirty() {
69600      this.send('becomeDirty');
69601      this.updateRecordArraysLater();
69602    },
69603
69604    /*
69605      @method send
69606      @private
69607      @param {String} name
69608      @param {Object} context
69609    */
69610    send: function send(name, context) {
69611      var currentState = get(this, 'currentState');
69612
69613      if (!currentState[name]) {
69614        this._unhandledEvent(currentState, name, context);
69615      }
69616
69617      return currentState[name](this, context);
69618    },
69619
69620    notifyHasManyAdded: function notifyHasManyAdded(key, record, idx) {
69621      if (this.record) {
69622        this.record.notifyHasManyAdded(key, record, idx);
69623      }
69624    },
69625
69626    notifyHasManyRemoved: function notifyHasManyRemoved(key, record, idx) {
69627      if (this.record) {
69628        this.record.notifyHasManyRemoved(key, record, idx);
69629      }
69630    },
69631
69632    notifyBelongsToChanged: function notifyBelongsToChanged(key, record) {
69633      if (this.record) {
69634        this.record.notifyBelongsToChanged(key, record);
69635      }
69636    },
69637
69638    notifyPropertyChange: function notifyPropertyChange(key) {
69639      if (this.record) {
69640        this.record.notifyPropertyChange(key);
69641      }
69642    },
69643
69644    rollbackAttributes: function rollbackAttributes() {
69645      var dirtyKeys = Object.keys(this._attributes);
69646
69647      this._attributes = new _emberDataPrivateSystemEmptyObject["default"]();
69648
69649      if (get(this, 'isError')) {
69650        this._inFlightAttributes = new _emberDataPrivateSystemEmptyObject["default"]();
69651        this.didCleanError();
69652      }
69653
69654      //Eventually rollback will always work for relationships
69655      //For now we support it only out of deleted state, because we
69656      //have an explicit way of knowing when the server acked the relationship change
69657      if (this.isDeleted()) {
69658        //TODO: Should probably move this to the state machine somehow
69659        this.becameReady();
69660      }
69661
69662      if (this.isNew()) {
69663        this.clearRelationships();
69664      }
69665
69666      if (this.isValid()) {
69667        this._inFlightAttributes = new _emberDataPrivateSystemEmptyObject["default"]();
69668      }
69669
69670      this.send('rolledBack');
69671
69672      this.record._notifyProperties(dirtyKeys);
69673    },
69674    /*
69675      @method transitionTo
69676      @private
69677      @param {String} name
69678    */
69679    transitionTo: function transitionTo(name) {
69680      // POSSIBLE TODO: Remove this code and replace with
69681      // always having direct reference to state objects
69682
69683      var pivotName = extractPivotName(name);
69684      var currentState = get(this, 'currentState');
69685      var state = currentState;
69686
69687      do {
69688        if (state.exit) {
69689          state.exit(this);
69690        }
69691        state = state.parentState;
69692      } while (!state.hasOwnProperty(pivotName));
69693
69694      var path = splitOnDot(name);
69695      var setups = [];
69696      var enters = [];
69697      var i, l;
69698
69699      for (i = 0, l = path.length; i < l; i++) {
69700        state = state[path[i]];
69701
69702        if (state.enter) {
69703          enters.push(state);
69704        }
69705        if (state.setup) {
69706          setups.push(state);
69707        }
69708      }
69709
69710      for (i = 0, l = enters.length; i < l; i++) {
69711        enters[i].enter(this);
69712      }
69713
69714      set(this, 'currentState', state);
69715      //TODO Consider whether this is the best approach for keeping these two in sync
69716      if (this.record) {
69717        set(this.record, 'currentState', state);
69718      }
69719
69720      for (i = 0, l = setups.length; i < l; i++) {
69721        setups[i].setup(this);
69722      }
69723
69724      this.updateRecordArraysLater();
69725    },
69726
69727    _unhandledEvent: function _unhandledEvent(state, name, context) {
69728      var errorMessage = "Attempted to handle event `" + name + "` ";
69729      errorMessage += "on " + String(this) + " while in state ";
69730      errorMessage += state.stateName + ". ";
69731
69732      if (context !== undefined) {
69733        errorMessage += "Called with " + _ember["default"].inspect(context) + ".";
69734      }
69735
69736      throw new _ember["default"].Error(errorMessage);
69737    },
69738
69739    triggerLater: function triggerLater() {
69740      var length = arguments.length;
69741      var args = new Array(length);
69742
69743      for (var i = 0; i < length; i++) {
69744        args[i] = arguments[i];
69745      }
69746
69747      if (this._deferredTriggers.push(args) !== 1) {
69748        return;
69749      }
69750      _ember["default"].run.scheduleOnce('actions', this, '_triggerDeferredTriggers');
69751    },
69752
69753    _triggerDeferredTriggers: function _triggerDeferredTriggers() {
69754      //TODO: Before 1.0 we want to remove all the events that happen on the pre materialized record,
69755      //but for now, we queue up all the events triggered before the record was materialized, and flush
69756      //them once we have the record
69757      if (!this.record) {
69758        return;
69759      }
69760      for (var i = 0, l = this._deferredTriggers.length; i < l; i++) {
69761        this.record.trigger.apply(this.record, this._deferredTriggers[i]);
69762      }
69763
69764      this._deferredTriggers.length = 0;
69765    },
69766    /*
69767      @method clearRelationships
69768      @private
69769    */
69770    clearRelationships: function clearRelationships() {
69771      var _this = this;
69772
69773      this.eachRelationship(function (name, relationship) {
69774        if (_this._relationships.has(name)) {
69775          var rel = _this._relationships.get(name);
69776          rel.clear();
69777          rel.destroy();
69778        }
69779      });
69780      Object.keys(this._implicitRelationships).forEach(function (key) {
69781        _this._implicitRelationships[key].clear();
69782        _this._implicitRelationships[key].destroy();
69783      });
69784    },
69785
69786    /*
69787      When a find request is triggered on the store, the user can optionally pass in
69788      attributes and relationships to be preloaded. These are meant to behave as if they
69789      came back from the server, except the user obtained them out of band and is informing
69790      the store of their existence. The most common use case is for supporting client side
69791      nested URLs, such as `/posts/1/comments/2` so the user can do
69792      `store.findRecord('comment', 2, { preload: { post: 1 } })` without having to fetch the post.
69793       Preloaded data can be attributes and relationships passed in either as IDs or as actual
69794      models.
69795       @method _preloadData
69796      @private
69797      @param {Object} preload
69798    */
69799    _preloadData: function _preloadData(preload) {
69800      var _this2 = this;
69801
69802      //TODO(Igor) consider the polymorphic case
69803      Object.keys(preload).forEach(function (key) {
69804        var preloadValue = get(preload, key);
69805        var relationshipMeta = _this2.type.metaForProperty(key);
69806        if (relationshipMeta.isRelationship) {
69807          _this2._preloadRelationship(key, preloadValue);
69808        } else {
69809          _this2._data[key] = preloadValue;
69810        }
69811      });
69812    },
69813
69814    _preloadRelationship: function _preloadRelationship(key, preloadValue) {
69815      var relationshipMeta = this.type.metaForProperty(key);
69816      var type = relationshipMeta.type;
69817      if (relationshipMeta.kind === 'hasMany') {
69818        this._preloadHasMany(key, preloadValue, type);
69819      } else {
69820        this._preloadBelongsTo(key, preloadValue, type);
69821      }
69822    },
69823
69824    _preloadHasMany: function _preloadHasMany(key, preloadValue, type) {
69825      (0, _emberDataPrivateDebug.assert)("You need to pass in an array to set a hasMany property on a record", Array.isArray(preloadValue));
69826      var recordsToSet = new Array(preloadValue.length);
69827
69828      for (var i = 0; i < preloadValue.length; i++) {
69829        var recordToPush = preloadValue[i];
69830        recordsToSet[i] = this._convertStringOrNumberIntoInternalModel(recordToPush, type);
69831      }
69832
69833      //We use the pathway of setting the hasMany as if it came from the adapter
69834      //because the user told us that they know this relationships exists already
69835      this._relationships.get(key).updateRecordsFromAdapter(recordsToSet);
69836    },
69837
69838    _preloadBelongsTo: function _preloadBelongsTo(key, preloadValue, type) {
69839      var recordToSet = this._convertStringOrNumberIntoInternalModel(preloadValue, type);
69840
69841      //We use the pathway of setting the hasMany as if it came from the adapter
69842      //because the user told us that they know this relationships exists already
69843      this._relationships.get(key).setRecord(recordToSet);
69844    },
69845
69846    _convertStringOrNumberIntoInternalModel: function _convertStringOrNumberIntoInternalModel(value, type) {
69847      if (typeof value === 'string' || typeof value === 'number') {
69848        return this.store._internalModelForId(type, value);
69849      }
69850      if (value._internalModel) {
69851        return value._internalModel;
69852      }
69853      return value;
69854    },
69855
69856    /*
69857      @method updateRecordArrays
69858      @private
69859    */
69860    updateRecordArrays: function updateRecordArrays() {
69861      this._updatingRecordArraysLater = false;
69862      this.store.dataWasUpdated(this.type, this);
69863    },
69864
69865    setId: function setId(id) {
69866      (0, _emberDataPrivateDebug.assert)('A record\'s id cannot be changed once it is in the loaded state', this.id === null || this.id === id || this.isNew());
69867      this.id = id;
69868      if (this.record.get('id') !== id) {
69869        this.record.set('id', id);
69870      }
69871    },
69872
69873    didError: function didError(error) {
69874      this.error = error;
69875      this.isError = true;
69876
69877      if (this.record) {
69878        this.record.setProperties({
69879          isError: true,
69880          adapterError: error
69881        });
69882      }
69883    },
69884
69885    didCleanError: function didCleanError() {
69886      this.error = null;
69887      this.isError = false;
69888
69889      if (this.record) {
69890        this.record.setProperties({
69891          isError: false,
69892          adapterError: null
69893        });
69894      }
69895    },
69896    /*
69897      If the adapter did not return a hash in response to a commit,
69898      merge the changed attributes and relationships into the existing
69899      saved data.
69900       @method adapterDidCommit
69901    */
69902    adapterDidCommit: function adapterDidCommit(data) {
69903      if (data) {
69904        data = data.attributes;
69905      }
69906
69907      this.didCleanError();
69908      var changedKeys = this._changedKeys(data);
69909
69910      assign(this._data, this._inFlightAttributes);
69911      if (data) {
69912        assign(this._data, data);
69913      }
69914
69915      this._inFlightAttributes = new _emberDataPrivateSystemEmptyObject["default"]();
69916
69917      this.send('didCommit');
69918      this.updateRecordArraysLater();
69919
69920      if (!data) {
69921        return;
69922      }
69923
69924      this.record._notifyProperties(changedKeys);
69925    },
69926
69927    /*
69928      @method updateRecordArraysLater
69929      @private
69930    */
69931    updateRecordArraysLater: function updateRecordArraysLater() {
69932      // quick hack (something like this could be pushed into run.once
69933      if (this._updatingRecordArraysLater) {
69934        return;
69935      }
69936      this._updatingRecordArraysLater = true;
69937      _ember["default"].run.schedule('actions', this, this.updateRecordArrays);
69938    },
69939
69940    addErrorMessageToAttribute: function addErrorMessageToAttribute(attribute, message) {
69941      var record = this.getRecord();
69942      get(record, 'errors')._add(attribute, message);
69943    },
69944
69945    removeErrorMessageFromAttribute: function removeErrorMessageFromAttribute(attribute) {
69946      var record = this.getRecord();
69947      get(record, 'errors')._remove(attribute);
69948    },
69949
69950    clearErrorMessages: function clearErrorMessages() {
69951      var record = this.getRecord();
69952      get(record, 'errors')._clear();
69953    },
69954
69955    hasErrors: function hasErrors() {
69956      var record = this.getRecord();
69957      var errors = get(record, 'errors');
69958
69959      return !_ember["default"].isEmpty(errors);
69960    },
69961
69962    // FOR USE DURING COMMIT PROCESS
69963
69964    /*
69965      @method adapterDidInvalidate
69966      @private
69967    */
69968    adapterDidInvalidate: function adapterDidInvalidate(errors) {
69969      var attribute;
69970
69971      for (attribute in errors) {
69972        if (errors.hasOwnProperty(attribute)) {
69973          this.addErrorMessageToAttribute(attribute, errors[attribute]);
69974        }
69975      }
69976
69977      this.send('becameInvalid');
69978
69979      this._saveWasRejected();
69980    },
69981
69982    /*
69983      @method adapterDidError
69984      @private
69985    */
69986    adapterDidError: function adapterDidError(error) {
69987      this.send('becameError');
69988      this.didError(error);
69989      this._saveWasRejected();
69990    },
69991
69992    _saveWasRejected: function _saveWasRejected() {
69993      var keys = Object.keys(this._inFlightAttributes);
69994      for (var i = 0; i < keys.length; i++) {
69995        if (this._attributes[keys[i]] === undefined) {
69996          this._attributes[keys[i]] = this._inFlightAttributes[keys[i]];
69997        }
69998      }
69999      this._inFlightAttributes = new _emberDataPrivateSystemEmptyObject["default"]();
70000    },
70001
70002    /*
70003      Ember Data has 3 buckets for storing the value of an attribute on an internalModel.
70004       `_data` holds all of the attributes that have been acknowledged by
70005      a backend via the adapter. When rollbackAttributes is called on a model all
70006      attributes will revert to the record's state in `_data`.
70007       `_attributes` holds any change the user has made to an attribute
70008      that has not been acknowledged by the adapter. Any values in
70009      `_attributes` are have priority over values in `_data`.
70010       `_inFlightAttributes`. When a record is being synced with the
70011      backend the values in `_attributes` are copied to
70012      `_inFlightAttributes`. This way if the backend acknowledges the
70013      save but does not return the new state Ember Data can copy the
70014      values from `_inFlightAttributes` to `_data`. Without having to
70015      worry about changes made to `_attributes` while the save was
70016      happenign.
70017        Changed keys builds a list of all of the values that may have been
70018      changed by the backend after a successful save.
70019       It does this by iterating over each key, value pair in the payload
70020      returned from the server after a save. If the `key` is found in
70021      `_attributes` then the user has a local changed to the attribute
70022      that has not been synced with the server and the key is not
70023      included in the list of changed keys.
70024    
70025      If the value, for a key differs from the value in what Ember Data
70026      believes to be the truth about the backend state (A merger of the
70027      `_data` and `_inFlightAttributes` objects where
70028      `_inFlightAttributes` has priority) then that means the backend
70029      has updated the value and the key is added to the list of changed
70030      keys.
70031       @method _changedKeys
70032      @private
70033    */
70034    _changedKeys: function _changedKeys(updates) {
70035      var changedKeys = [];
70036
70037      if (updates) {
70038        var original, i, value, key;
70039        var keys = Object.keys(updates);
70040        var length = keys.length;
70041
70042        original = assign(new _emberDataPrivateSystemEmptyObject["default"](), this._data);
70043        original = assign(original, this._inFlightAttributes);
70044
70045        for (i = 0; i < length; i++) {
70046          key = keys[i];
70047          value = updates[key];
70048
70049          // A value in _attributes means the user has a local change to
70050          // this attributes. We never override this value when merging
70051          // updates from the backend so we should not sent a change
70052          // notification if the server value differs from the original.
70053          if (this._attributes[key] !== undefined) {
70054            continue;
70055          }
70056
70057          if (!_ember["default"].isEqual(original[key], value)) {
70058            changedKeys.push(key);
70059          }
70060        }
70061      }
70062
70063      return changedKeys;
70064    },
70065
70066    toString: function toString() {
70067      if (this.record) {
70068        return this.record.toString();
70069      } else {
70070        return "<" + this.modelName + ":" + this.id + ">";
70071      }
70072    },
70073
70074    referenceFor: function referenceFor(type, name) {
70075      var reference = this.references[name];
70076
70077      if (!reference) {
70078        var relationship = this._relationships.get(name);
70079
70080        if (type === "belongsTo") {
70081          reference = new _emberDataPrivateSystemReferences.BelongsToReference(this.store, this, relationship);
70082        } else if (type === "hasMany") {
70083          reference = new _emberDataPrivateSystemReferences.HasManyReference(this.store, this, relationship);
70084        }
70085
70086        this.references[name] = reference;
70087      }
70088
70089      return reference;
70090    }
70091  };
70092});
70093define("ember-data/-private/system/model/model", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/model/errors", "ember-data/-private/system/debug/debug-info", "ember-data/-private/system/relationships/belongs-to", "ember-data/-private/system/relationships/has-many", "ember-data/-private/system/relationships/ext", "ember-data/-private/system/model/attr"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemModelErrors, _emberDataPrivateSystemDebugDebugInfo, _emberDataPrivateSystemRelationshipsBelongsTo, _emberDataPrivateSystemRelationshipsHasMany, _emberDataPrivateSystemRelationshipsExt, _emberDataPrivateSystemModelAttr) {
70094  "use strict";
70095
70096  /**
70097    @module ember-data
70098  */
70099
70100  var get = _ember["default"].get;
70101
70102  function intersection(array1, array2) {
70103    var result = [];
70104    array1.forEach(function (element) {
70105      if (array2.indexOf(element) >= 0) {
70106        result.push(element);
70107      }
70108    });
70109
70110    return result;
70111  }
70112
70113  var RESERVED_MODEL_PROPS = ['currentState', 'data', 'store'];
70114
70115  var retrieveFromCurrentState = _ember["default"].computed('currentState', function (key) {
70116    return get(this._internalModel.currentState, key);
70117  }).readOnly();
70118
70119  /**
70120  
70121    The model class that all Ember Data records descend from.
70122    This is the public API of Ember Data models. If you are using Ember Data
70123    in your application, this is the class you should use.
70124    If you are working on Ember Data internals, you most likely want to be dealing
70125    with `InternalModel`
70126  
70127    @class Model
70128    @namespace DS
70129    @extends Ember.Object
70130    @uses Ember.Evented
70131  */
70132  var Model = _ember["default"].Object.extend(_ember["default"].Evented, {
70133    _internalModel: null,
70134    store: null,
70135
70136    /**
70137      If this property is `true` the record is in the `empty`
70138      state. Empty is the first state all records enter after they have
70139      been created. Most records created by the store will quickly
70140      transition to the `loading` state if data needs to be fetched from
70141      the server or the `created` state if the record is created on the
70142      client. A record can also enter the empty state if the adapter is
70143      unable to locate the record.
70144       @property isEmpty
70145      @type {Boolean}
70146      @readOnly
70147    */
70148    isEmpty: retrieveFromCurrentState,
70149    /**
70150      If this property is `true` the record is in the `loading` state. A
70151      record enters this state when the store asks the adapter for its
70152      data. It remains in this state until the adapter provides the
70153      requested data.
70154       @property isLoading
70155      @type {Boolean}
70156      @readOnly
70157    */
70158    isLoading: retrieveFromCurrentState,
70159    /**
70160      If this property is `true` the record is in the `loaded` state. A
70161      record enters this state when its data is populated. Most of a
70162      record's lifecycle is spent inside substates of the `loaded`
70163      state.
70164       Example
70165       ```javascript
70166      var record = store.createRecord('model');
70167      record.get('isLoaded'); // true
70168       store.findRecord('model', 1).then(function(model) {
70169        model.get('isLoaded'); // true
70170      });
70171      ```
70172       @property isLoaded
70173      @type {Boolean}
70174      @readOnly
70175    */
70176    isLoaded: retrieveFromCurrentState,
70177    /**
70178      If this property is `true` the record is in the `dirty` state. The
70179      record has local changes that have not yet been saved by the
70180      adapter. This includes records that have been created (but not yet
70181      saved) or deleted.
70182       Example
70183       ```javascript
70184      var record = store.createRecord('model');
70185      record.get('hasDirtyAttributes'); // true
70186       store.findRecord('model', 1).then(function(model) {
70187        model.get('hasDirtyAttributes'); // false
70188        model.set('foo', 'some value');
70189        model.get('hasDirtyAttributes'); // true
70190      });
70191      ```
70192       @since 1.13.0
70193      @property hasDirtyAttributes
70194      @type {Boolean}
70195      @readOnly
70196    */
70197    hasDirtyAttributes: _ember["default"].computed('currentState.isDirty', function () {
70198      return this.get('currentState.isDirty');
70199    }),
70200    /**
70201      If this property is `true` the record is in the `saving` state. A
70202      record enters the saving state when `save` is called, but the
70203      adapter has not yet acknowledged that the changes have been
70204      persisted to the backend.
70205       Example
70206       ```javascript
70207      var record = store.createRecord('model');
70208      record.get('isSaving'); // false
70209      var promise = record.save();
70210      record.get('isSaving'); // true
70211      promise.then(function() {
70212        record.get('isSaving'); // false
70213      });
70214      ```
70215       @property isSaving
70216      @type {Boolean}
70217      @readOnly
70218    */
70219    isSaving: retrieveFromCurrentState,
70220    /**
70221      If this property is `true` the record is in the `deleted` state
70222      and has been marked for deletion. When `isDeleted` is true and
70223      `hasDirtyAttributes` is true, the record is deleted locally but the deletion
70224      was not yet persisted. When `isSaving` is true, the change is
70225      in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the
70226      change has persisted.
70227       Example
70228       ```javascript
70229      var record = store.createRecord('model');
70230      record.get('isDeleted');    // false
70231      record.deleteRecord();
70232       // Locally deleted
70233      record.get('isDeleted');           // true
70234      record.get('hasDirtyAttributes');  // true
70235      record.get('isSaving');            // false
70236       // Persisting the deletion
70237      var promise = record.save();
70238      record.get('isDeleted');    // true
70239      record.get('isSaving');     // true
70240       // Deletion Persisted
70241      promise.then(function() {
70242        record.get('isDeleted');          // true
70243        record.get('isSaving');           // false
70244        record.get('hasDirtyAttributes'); // false
70245      });
70246      ```
70247       @property isDeleted
70248      @type {Boolean}
70249      @readOnly
70250    */
70251    isDeleted: retrieveFromCurrentState,
70252    /**
70253      If this property is `true` the record is in the `new` state. A
70254      record will be in the `new` state when it has been created on the
70255      client and the adapter has not yet report that it was successfully
70256      saved.
70257       Example
70258       ```javascript
70259      var record = store.createRecord('model');
70260      record.get('isNew'); // true
70261       record.save().then(function(model) {
70262        model.get('isNew'); // false
70263      });
70264      ```
70265       @property isNew
70266      @type {Boolean}
70267      @readOnly
70268    */
70269    isNew: retrieveFromCurrentState,
70270    /**
70271      If this property is `true` the record is in the `valid` state.
70272       A record will be in the `valid` state when the adapter did not report any
70273      server-side validation failures.
70274       @property isValid
70275      @type {Boolean}
70276      @readOnly
70277    */
70278    isValid: retrieveFromCurrentState,
70279    /**
70280      If the record is in the dirty state this property will report what
70281      kind of change has caused it to move into the dirty
70282      state. Possible values are:
70283       - `created` The record has been created by the client and not yet saved to the adapter.
70284      - `updated` The record has been updated by the client and not yet saved to the adapter.
70285      - `deleted` The record has been deleted by the client and not yet saved to the adapter.
70286       Example
70287       ```javascript
70288      var record = store.createRecord('model');
70289      record.get('dirtyType'); // 'created'
70290      ```
70291       @property dirtyType
70292      @type {String}
70293      @readOnly
70294    */
70295    dirtyType: retrieveFromCurrentState,
70296
70297    /**
70298      If `true` the adapter reported that it was unable to save local
70299      changes to the backend for any reason other than a server-side
70300      validation error.
70301       Example
70302       ```javascript
70303      record.get('isError'); // false
70304      record.set('foo', 'valid value');
70305      record.save().then(null, function() {
70306        record.get('isError'); // true
70307      });
70308      ```
70309       @property isError
70310      @type {Boolean}
70311      @readOnly
70312    */
70313    isError: false,
70314
70315    /**
70316      If `true` the store is attempting to reload the record form the adapter.
70317       Example
70318       ```javascript
70319      record.get('isReloading'); // false
70320      record.reload();
70321      record.get('isReloading'); // true
70322      ```
70323       @property isReloading
70324      @type {Boolean}
70325      @readOnly
70326    */
70327    isReloading: false,
70328
70329    /**
70330      All ember models have an id property. This is an identifier
70331      managed by an external source. These are always coerced to be
70332      strings before being used internally. Note when declaring the
70333      attributes for a model it is an error to declare an id
70334      attribute.
70335       ```javascript
70336      var record = store.createRecord('model');
70337      record.get('id'); // null
70338       store.findRecord('model', 1).then(function(model) {
70339        model.get('id'); // '1'
70340      });
70341      ```
70342       @property id
70343      @type {String}
70344    */
70345    id: null,
70346
70347    /**
70348      @property currentState
70349      @private
70350      @type {Object}
70351    */
70352
70353    /**
70354      When the record is in the `invalid` state this object will contain
70355      any errors returned by the adapter. When present the errors hash
70356      contains keys corresponding to the invalid property names
70357      and values which are arrays of Javascript objects with two keys:
70358       - `message` A string containing the error message from the backend
70359      - `attribute` The name of the property associated with this error message
70360       ```javascript
70361      record.get('errors.length'); // 0
70362      record.set('foo', 'invalid value');
70363      record.save().catch(function() {
70364        record.get('errors').get('foo');
70365        // [{message: 'foo should be a number.', attribute: 'foo'}]
70366      });
70367      ```
70368       The `errors` property us useful for displaying error messages to
70369      the user.
70370       ```handlebars
70371      <label>Username: {{input value=username}} </label>
70372      {{#each model.errors.username as |error|}}
70373        <div class="error">
70374          {{error.message}}
70375        </div>
70376      {{/each}}
70377      <label>Email: {{input value=email}} </label>
70378      {{#each model.errors.email as |error|}}
70379        <div class="error">
70380          {{error.message}}
70381        </div>
70382      {{/each}}
70383      ```
70384        You can also access the special `messages` property on the error
70385      object to get an array of all the error strings.
70386       ```handlebars
70387      {{#each model.errors.messages as |message|}}
70388        <div class="error">
70389          {{message}}
70390        </div>
70391      {{/each}}
70392      ```
70393       @property errors
70394      @type {DS.Errors}
70395    */
70396    errors: _ember["default"].computed(function () {
70397      var errors = _emberDataPrivateSystemModelErrors["default"].create();
70398
70399      errors._registerHandlers(this._internalModel, function () {
70400        this.send('becameInvalid');
70401      }, function () {
70402        this.send('becameValid');
70403      });
70404      return errors;
70405    }).readOnly(),
70406
70407    /**
70408      This property holds the `DS.AdapterError` object with which
70409      last adapter operation was rejected.
70410       @property adapterError
70411      @type {DS.AdapterError}
70412    */
70413    adapterError: null,
70414
70415    /**
70416      Create a JSON representation of the record, using the serialization
70417      strategy of the store's adapter.
70418      `serialize` takes an optional hash as a parameter, currently
70419      supported options are:
70420      - `includeId`: `true` if the record's ID should be included in the
70421        JSON representation.
70422       @method serialize
70423      @param {Object} options
70424      @return {Object} an object whose values are primitive JSON values only
70425    */
70426    serialize: function serialize(options) {
70427      return this.store.serialize(this, options);
70428    },
70429
70430    /**
70431      Use [DS.JSONSerializer](DS.JSONSerializer.html) to
70432      get the JSON representation of a record.
70433       `toJSON` takes an optional hash as a parameter, currently
70434      supported options are:
70435       - `includeId`: `true` if the record's ID should be included in the
70436        JSON representation.
70437       @method toJSON
70438      @param {Object} options
70439      @return {Object} A JSON representation of the object.
70440    */
70441    toJSON: function toJSON(options) {
70442      // container is for lazy transform lookups
70443      var serializer = this.store.serializerFor('-default');
70444      var snapshot = this._internalModel.createSnapshot();
70445
70446      return serializer.serialize(snapshot, options);
70447    },
70448
70449    /**
70450      Fired when the record is ready to be interacted with,
70451      that is either loaded from the server or created locally.
70452       @event ready
70453    */
70454    ready: _ember["default"].K,
70455
70456    /**
70457      Fired when the record is loaded from the server.
70458       @event didLoad
70459    */
70460    didLoad: _ember["default"].K,
70461
70462    /**
70463      Fired when the record is updated.
70464       @event didUpdate
70465    */
70466    didUpdate: _ember["default"].K,
70467
70468    /**
70469      Fired when a new record is commited to the server.
70470       @event didCreate
70471    */
70472    didCreate: _ember["default"].K,
70473
70474    /**
70475      Fired when the record is deleted.
70476       @event didDelete
70477    */
70478    didDelete: _ember["default"].K,
70479
70480    /**
70481      Fired when the record becomes invalid.
70482       @event becameInvalid
70483    */
70484    becameInvalid: _ember["default"].K,
70485
70486    /**
70487      Fired when the record enters the error state.
70488       @event becameError
70489    */
70490    becameError: _ember["default"].K,
70491
70492    /**
70493      Fired when the record is rolled back.
70494       @event rolledBack
70495    */
70496    rolledBack: _ember["default"].K,
70497
70498    /**
70499      @property data
70500      @private
70501      @type {Object}
70502    */
70503    data: _ember["default"].computed.readOnly('_internalModel._data'),
70504
70505    //TODO Do we want to deprecate these?
70506    /**
70507      @method send
70508      @private
70509      @param {String} name
70510      @param {Object} context
70511    */
70512    send: function send(name, context) {
70513      return this._internalModel.send(name, context);
70514    },
70515
70516    /**
70517      @method transitionTo
70518      @private
70519      @param {String} name
70520    */
70521    transitionTo: function transitionTo(name) {
70522      return this._internalModel.transitionTo(name);
70523    },
70524
70525    /**
70526      Marks the record as deleted but does not save it. You must call
70527      `save` afterwards if you want to persist it. You might use this
70528      method if you want to allow the user to still `rollbackAttributes()`
70529      after a delete it was made.
70530       Example
70531       ```app/routes/model/delete.js
70532      import Ember from 'ember';
70533       export default Ember.Route.extend({
70534        actions: {
70535          softDelete: function() {
70536            this.controller.get('model').deleteRecord();
70537          },
70538          confirm: function() {
70539            this.controller.get('model').save();
70540          },
70541          undo: function() {
70542            this.controller.get('model').rollbackAttributes();
70543          }
70544        }
70545      });
70546      ```
70547       @method deleteRecord
70548    */
70549    deleteRecord: function deleteRecord() {
70550      this._internalModel.deleteRecord();
70551    },
70552
70553    /**
70554      Same as `deleteRecord`, but saves the record immediately.
70555       Example
70556       ```app/routes/model/delete.js
70557      import Ember from 'ember';
70558       export default Ember.Route.extend({
70559        actions: {
70560          delete: function() {
70561            var controller = this.controller;
70562            controller.get('model').destroyRecord().then(function() {
70563              controller.transitionToRoute('model.index');
70564            });
70565          }
70566        }
70567      });
70568      ```
70569       If you pass an object on the `adapterOptions` property of the options
70570      argument it will be passed to you adapter via the snapshot
70571       ```js
70572      record.destroyRecord({ adapterOptions: { subscribe: false } });
70573      ```
70574       ```app/adapters/post.js
70575      import MyCustomAdapter from './custom-adapter';
70576       export default MyCustomAdapter.extend({
70577        deleteRecord: function(store, type, snapshot) {
70578          if (snapshot.adapterOptions.subscribe) {
70579            // ...
70580          }
70581          // ...
70582        }
70583      });
70584      ```
70585       @method destroyRecord
70586      @param {Object} options
70587      @return {Promise} a promise that will be resolved when the adapter returns
70588      successfully or rejected if the adapter returns with an error.
70589    */
70590    destroyRecord: function destroyRecord(options) {
70591      this.deleteRecord();
70592      return this.save(options);
70593    },
70594
70595    /**
70596      @method unloadRecord
70597      @private
70598    */
70599    unloadRecord: function unloadRecord() {
70600      if (this.isDestroyed) {
70601        return;
70602      }
70603      this._internalModel.unloadRecord();
70604    },
70605
70606    /**
70607      @method _notifyProperties
70608      @private
70609    */
70610    _notifyProperties: function _notifyProperties(keys) {
70611      _ember["default"].beginPropertyChanges();
70612      var key;
70613      for (var i = 0, length = keys.length; i < length; i++) {
70614        key = keys[i];
70615        this.notifyPropertyChange(key);
70616      }
70617      _ember["default"].endPropertyChanges();
70618    },
70619
70620    /**
70621      Returns an object, whose keys are changed properties, and value is
70622      an [oldProp, newProp] array.
70623       The array represents the diff of the canonical state with the local state
70624      of the model. Note: if the model is created locally, the canonical state is
70625      empty since the adapter hasn't acknowledged the attributes yet:
70626       Example
70627       ```app/models/mascot.js
70628      import DS from 'ember-data';
70629       export default DS.Model.extend({
70630        name: attr('string'),
70631        isAdmin: attr('boolean', {
70632          defaultValue: false
70633        })
70634      });
70635      ```
70636       ```javascript
70637      var mascot = store.createRecord('mascot');
70638       mascot.changedAttributes(); // {}
70639       mascot.set('name', 'Tomster');
70640      mascot.changedAttributes(); // { name: [undefined, 'Tomster'] }
70641       mascot.set('isAdmin', true);
70642      mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] }
70643       mascot.save().then(function() {
70644        mascot.changedAttributes(); // {}
70645         mascot.set('isAdmin', false);
70646        mascot.changedAttributes(); // { isAdmin: [true, false] }
70647      });
70648      ```
70649       @method changedAttributes
70650      @return {Object} an object, whose keys are changed properties,
70651        and value is an [oldProp, newProp] array.
70652    */
70653    changedAttributes: function changedAttributes() {
70654      return this._internalModel.changedAttributes();
70655    },
70656
70657    //TODO discuss with tomhuda about events/hooks
70658    //Bring back as hooks?
70659    /**
70660      @method adapterWillCommit
70661      @private
70662    adapterWillCommit: function() {
70663      this.send('willCommit');
70664    },
70665     /**
70666      @method adapterDidDirty
70667      @private
70668    adapterDidDirty: function() {
70669      this.send('becomeDirty');
70670      this.updateRecordArraysLater();
70671    },
70672    */
70673
70674    /**
70675      If the model `hasDirtyAttributes` this function will discard any unsaved
70676      changes. If the model `isNew` it will be removed from the store.
70677       Example
70678       ```javascript
70679      record.get('name'); // 'Untitled Document'
70680      record.set('name', 'Doc 1');
70681      record.get('name'); // 'Doc 1'
70682      record.rollbackAttributes();
70683      record.get('name'); // 'Untitled Document'
70684      ```
70685       @since 1.13.0
70686      @method rollbackAttributes
70687    */
70688    rollbackAttributes: function rollbackAttributes() {
70689      this._internalModel.rollbackAttributes();
70690    },
70691
70692    /*
70693      @method _createSnapshot
70694      @private
70695    */
70696    _createSnapshot: function _createSnapshot() {
70697      return this._internalModel.createSnapshot();
70698    },
70699
70700    toStringExtension: function toStringExtension() {
70701      return get(this, 'id');
70702    },
70703
70704    /**
70705      Save the record and persist any changes to the record to an
70706      external source via the adapter.
70707       Example
70708       ```javascript
70709      record.set('name', 'Tomster');
70710      record.save().then(function() {
70711        // Success callback
70712      }, function() {
70713        // Error callback
70714      });
70715      ```
70716      If you pass an object on the `adapterOptions` property of the options
70717     argument it will be passed to you adapter via the snapshot
70718       ```js
70719      record.save({ adapterOptions: { subscribe: false } });
70720      ```
70721       ```app/adapters/post.js
70722      import MyCustomAdapter from './custom-adapter';
70723       export default MyCustomAdapter.extend({
70724        updateRecord: function(store, type, snapshot) {
70725          if (snapshot.adapterOptions.subscribe) {
70726            // ...
70727          }
70728          // ...
70729        }
70730      });
70731      ```
70732       @method save
70733      @param {Object} options
70734      @return {Promise} a promise that will be resolved when the adapter returns
70735      successfully or rejected if the adapter returns with an error.
70736    */
70737    save: function save(options) {
70738      var _this = this;
70739
70740      return _emberDataPrivateSystemPromiseProxies.PromiseObject.create({
70741        promise: this._internalModel.save(options).then(function () {
70742          return _this;
70743        })
70744      });
70745    },
70746
70747    /**
70748      Reload the record from the adapter.
70749       This will only work if the record has already finished loading.
70750       Example
70751       ```app/routes/model/view.js
70752      import Ember from 'ember';
70753       export default Ember.Route.extend({
70754        actions: {
70755          reload: function() {
70756            this.controller.get('model').reload().then(function(model) {
70757              // do something with the reloaded model
70758            });
70759          }
70760        }
70761      });
70762      ```
70763       @method reload
70764      @return {Promise} a promise that will be resolved with the record when the
70765      adapter returns successfully or rejected if the adapter returns
70766      with an error.
70767    */
70768    reload: function reload() {
70769      var _this2 = this;
70770
70771      return _emberDataPrivateSystemPromiseProxies.PromiseObject.create({
70772        promise: this._internalModel.reload().then(function () {
70773          return _this2;
70774        })
70775      });
70776    },
70777
70778    /**
70779      Override the default event firing from Ember.Evented to
70780      also call methods with the given name.
70781       @method trigger
70782      @private
70783      @param {String} name
70784    */
70785    trigger: function trigger(name) {
70786      var length = arguments.length;
70787      var args = new Array(length - 1);
70788
70789      for (var i = 1; i < length; i++) {
70790        args[i - 1] = arguments[i];
70791      }
70792
70793      _ember["default"].tryInvoke(this, name, args);
70794      this._super.apply(this, arguments);
70795    },
70796
70797    willDestroy: function willDestroy() {
70798      //TODO Move!
70799      this._super.apply(this, arguments);
70800      this._internalModel.clearRelationships();
70801      this._internalModel.recordObjectWillDestroy();
70802      //TODO should we set internalModel to null here?
70803    },
70804
70805    // This is a temporary solution until we refactor DS.Model to not
70806    // rely on the data property.
70807    willMergeMixin: function willMergeMixin(props) {
70808      var constructor = this.constructor;
70809      (0, _emberDataPrivateDebug.assert)('`' + intersection(Object.keys(props), RESERVED_MODEL_PROPS)[0] + '` is a reserved property name on DS.Model objects. Please choose a different property name for ' + constructor.toString(), !intersection(Object.keys(props), RESERVED_MODEL_PROPS)[0]);
70810      (0, _emberDataPrivateDebug.assert)("You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('<type>')` from " + constructor.toString(), Object.keys(props).indexOf('id') === -1);
70811    },
70812
70813    attr: function attr() {
70814      (0, _emberDataPrivateDebug.assert)("The `attr` method is not available on DS.Model, a DS.Snapshot was probably expected. Are you passing a DS.Model instead of a DS.Snapshot to your serializer?", false);
70815    },
70816
70817    /**
70818      Get the reference for the specified belongsTo relationship.
70819       Example
70820       ```javascript
70821      
70821// models/blog.js
70822      export default DS.Model.extend({
70823        user: DS.belongsTo({ async: true })
70824      });
70825       var blog = store.push({
70826        type: 'blog',
70827        id: 1,
70828        relationships: {
70829          user: { type: 'user', id: 1 }
70830        }
70831      });
70832      var userRef = blog.belongsTo('user');
70833       // check if the user relationship is loaded
70834      var isLoaded = userRef.value() !== null;
70835       // get the record of the reference (null if not yet available)
70836      var user = userRef.value();
70837       // get the identifier of the reference
70838      if (userRef.remoteType() === "id") {
70839        var id = userRef.id();
70840      } else if (userRef.remoteType() === "link") {
70841        var link = userRef.link();
70842      }
70843       // load user (via store.findRecord or store.findBelongsTo)
70844      userRef.load().then(...)
70845       // or trigger a reload
70846      userRef.reload().then(...)
70847       // provide data for reference
70848      userRef.push({
70849        type: 'user',
70850        id: 1,
70851        attributes: {
70852          username: "@user"
70853        }
70854      }).then(function(user) {
70855        userRef.value() === user;
70856      });
70857      ```
70858       @method belongsTo
70859      @param {String} name of the relationship
70860      @since 2.5.0
70861      @return {BelongsToReference} reference for this relationship
70862    */
70863    belongsTo: function belongsTo(name) {
70864      return this._internalModel.referenceFor('belongsTo', name);
70865    },
70866
70867    /**
70868      Get the reference for the specified hasMany relationship.
70869       Example
70870       ```javascript
70871      
70871// models/blog.js
70872      export default DS.Model.extend({
70873        comments: DS.hasMany({ async: true })
70874      });
70875       var blog = store.push({
70876        type: 'blog',
70877        id: 1,
70878        relationships: {
70879          comments: {
70880            data: [
70881              { type: 'comment', id: 1 },
70882              { type: 'comment', id: 2 }
70883            ]
70884          }
70885        }
70886      });
70887      var commentsRef = blog.hasMany('comments');
70888       // check if the comments are loaded already
70889      var isLoaded = commentsRef.value() !== null;
70890       // get the records of the reference (null if not yet available)
70891      var comments = commentsRef.value();
70892       // get the identifier of the reference
70893      if (commentsRef.remoteType() === "ids") {
70894        var ids = commentsRef.ids();
70895      } else if (commentsRef.remoteType() === "link") {
70896        var link = commentsRef.link();
70897      }
70898       // load comments (via store.findMany or store.findHasMany)
70899      commentsRef.load().then(...)
70900       // or trigger a reload
70901      commentsRef.reload().then(...)
70902       // provide data for reference
70903      commentsRef.push([{ type: 'comment', id: 1 }, { type: 'comment', id: 2 }]).then(function(comments) {
70904        commentsRef.value() === comments;
70905      });
70906      ```
70907       @method hasMany
70908      @param {String} name of the relationship
70909      @since 2.5.0
70910      @return {HasManyReference} reference for this relationship
70911    */
70912    hasMany: function hasMany(name) {
70913      return this._internalModel.referenceFor('hasMany', name);
70914    },
70915
70916    setId: _ember["default"].observer('id', function () {
70917      this._internalModel.setId(this.get('id'));
70918    })
70919  });
70920
70921  Model.reopenClass({
70922    /**
70923      Alias DS.Model's `create` method to `_create`. This allows us to create DS.Model
70924      instances from within the store, but if end users accidentally call `create()`
70925      (instead of `createRecord()`), we can raise an error.
70926       @method _create
70927      @private
70928      @static
70929    */
70930    _create: Model.create,
70931
70932    /**
70933      Override the class' `create()` method to raise an error. This
70934      prevents end users from inadvertently calling `create()` instead
70935      of `createRecord()`. The store is still able to create instances
70936      by calling the `_create()` method. To create an instance of a
70937      `DS.Model` use [store.createRecord](DS.Store.html#method_createRecord).
70938       @method create
70939      @private
70940      @static
70941    */
70942    create: function create() {
70943      throw new _ember["default"].Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.");
70944    },
70945
70946    /**
70947     Represents the model's class name as a string. This can be used to look up the model through
70948     DS.Store's modelFor method.
70949      `modelName` is generated for you by Ember Data. It will be a lowercased, dasherized string.
70950     For example:
70951      ```javascript
70952     store.modelFor('post').modelName; // 'post'
70953     store.modelFor('blog-post').modelName; // 'blog-post'
70954     ```
70955      The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
70956     keys to underscore (instead of dasherized), you might use the following code:
70957      ```javascript
70958     export default var PostSerializer = DS.RESTSerializer.extend({
70959       payloadKeyFromModelName: function(modelName) {
70960         return Ember.String.underscore(modelName);
70961       }
70962     });
70963     ```
70964     @property modelName
70965     @type String
70966     @readonly
70967    */
70968    modelName: null
70969  });
70970
70971  // if `Ember.setOwner` is defined, accessing `this.container` is
70972  // deprecated (but functional). In "standard" Ember usage, this
70973  // deprecation is actually created via an `.extend` of the factory
70974  // inside the container itself, but that only happens on models
70975  // with MODEL_FACTORY_INJECTIONS enabled :(
70976  if (_ember["default"].setOwner) {
70977    Object.defineProperty(Model.prototype, 'container', {
70978      configurable: true,
70979      enumerable: false,
70980      get: function get() {
70981        (0, _emberDataPrivateDebug.deprecate)('Using the injected `container` is deprecated. Please use the `getOwner` helper instead to access the owner of this object.', false, { id: 'ember-
70981application.injected-container', until: '3.0.0' });
70982
70983        return this.store.container;
70984      }
70985    });
70986  }
70987
70988  Model.reopenClass(_emberDataPrivateSystemRelationshipsExt.RelationshipsClassMethodsMixin);
70989  Model.reopenClass(_emberDataPrivateSystemModelAttr.AttrClassMethodsMixin);
70990
70991  exports["default"] = Model.extend(_emberDataPrivateSystemDebugDebugInfo["default"], _emberDataPrivateSystemRelationshipsBelongsTo.BelongsToMixin, _emberDataPrivateSystemRelationshipsExt.DidDefinePropertyMixin, _emberDataPrivateSystemRelationshipsExt.RelationshipsInstanceMethodsMixin, _emberDataPrivateSystemRelationshipsHasMany.HasManyMixin, _emberDataPrivateSystemModelAttr.AttrInstanceMethodsMixin);
70992});
70993define('ember-data/-private/system/model/states', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
70994  /**
70995    @module ember-data
70996  */
70997  'use strict';
70998
70999  var get = _ember['default'].get;
71000  /*
71001    This file encapsulates the various states that a record can transition
71002    through during its lifecycle.
71003  */
71004  /**
71005    ### State
71006  
71007    Each record has a `currentState` property that explicitly tracks what
71008    state a record is in at any given time. For instance, if a record is
71009    newly created and has not yet been sent to the adapter to be saved,
71010    it would be in the `root.loaded.created.uncommitted` state.  If a
71011    record has had local modifications made to it that are in the
71012    process of being saved, the record would be in the
71013    `root.loaded.updated.inFlight` state. (This state paths will be
71014    explained in more detail below.)
71015  
71016    Events are sent by the record or its store to the record's
71017    `currentState` property. How the state reacts to these events is
71018    dependent on which state it is in. In some states, certain events
71019    will be invalid and will cause an exception to be raised.
71020  
71021    States are hierarchical and every state is a substate of the
71022    `RootState`. For example, a record can be in the
71023    `root.deleted.uncommitted` state, then transition into the
71024    `root.deleted.inFlight` state. If a child state does not implement
71025    an event handler, the state manager will attempt to invoke the event
71026    on all parent states until the root state is reached. The state
71027    hierarchy of a record is described in terms of a path string. You
71028    can determine a record's current state by getting the state's
71029    `stateName` property:
71030  
71031    ```javascript
71032    record.get('currentState.stateName');
71033    //=> "root.created.uncommitted"
71034     ```
71035  
71036    The hierarchy of valid states that ship with ember data looks like
71037    this:
71038  
71039    ```text
71040    * root
71041      * deleted
71042        * saved
71043        * uncommitted
71044        * inFlight
71045      * empty
71046      * loaded
71047        * created
71048          * uncommitted
71049          * inFlight
71050        * saved
71051        * updated
71052          * uncommitted
71053          * inFlight
71054      * loading
71055    ```
71056  
71057    The `DS.Model` states are themselves stateless. What that means is
71058    that, the hierarchical states that each of *those* points to is a
71059    shared data structure. For performance reasons, instead of each
71060    record getting its own copy of the hierarchy of states, each record
71061    points to this global, immutable shared instance. How does a state
71062    know which record it should be acting on? We pass the record
71063    instance into the state's event handlers as the first argument.
71064  
71065    The record passed as the first parameter is where you should stash
71066    state about the record if needed; you should never store data on the state
71067    object itself.
71068  
71069    ### Events and Flags
71070  
71071    A state may implement zero or more events and flags.
71072  
71073    #### Events
71074  
71075    Events are named functions that are invoked when sent to a record. The
71076    record will first look for a method with the given name on the
71077    current state. If no method is found, it will search the current
71078    state's parent, and then its grandparent, and so on until reaching
71079    the top of the hierarchy. If the root is reached without an event
71080    handler being found, an exception will be raised. This can be very
71081    helpful when debugging new features.
71082  
71083    Here's an example implementation of a state with a `myEvent` event handler:
71084  
71085    ```javascript
71086    aState: DS.State.create({
71087      myEvent: function(manager, param) {
71088        console.log("Received myEvent with", param);
71089      }
71090    })
71091    ```
71092  
71093    To trigger this event:
71094  
71095    ```javascript
71096    record.send('myEvent', 'foo');
71097    //=> "Received myEvent with foo"
71098    ```
71099  
71100    Note that an optional parameter can be sent to a record's `send()` method,
71101    which will be passed as the second parameter to the event handler.
71102  
71103    Events should transition to a different state if appropriate. This can be
71104    done by calling the record's `transitionTo()` method with a path to the
71105    desired state. The state manager will attempt to resolve the state path
71106    relative to the current state. If no state is found at that path, it will
71107    attempt to resolve it relative to the current state's parent, and then its
71108    parent, and so on until the root is reached. For example, imagine a hierarchy
71109    like this:
71110  
71111        * created
71112          * uncommitted <-- currentState
71113          * inFlight
71114        * updated
71115          * inFlight
71116  
71117    If we are currently in the `uncommitted` state, calling
71118    `transitionTo('inFlight')` would transition to the `created.inFlight` state,
71119    while calling `transitionTo('updated.inFlight')` would transition to
71120    the `updated.inFlight` state.
71121  
71122    Remember that *only events* should ever cause a state transition. You should
71123    never call `transitionTo()` from outside a state's event handler. If you are
71124    tempted to do so, create a new event and send that to the state manager.
71125  
71126    #### Flags
71127  
71128    Flags are Boolean values that can be used to introspect a record's current
71129    state in a more user-friendly way than examining its state path. For example,
71130    instead of doing this:
71131  
71132    ```javascript
71133    var statePath = record.get('stateManager.currentPath');
71134    if (statePath === 'created.inFlight') {
71135      doSomething();
71136    }
71137    ```
71138  
71139    You can say:
71140  
71141    ```javascript
71142    if (record.get('isNew') && record.get('isSaving')) {
71143      doSomething();
71144    }
71145    ```
71146  
71147    If your state does not set a value for a given flag, the value will
71148    be inherited from its parent (or the first place in the state hierarchy
71149    where it is defined).
71150  
71151    The current set of flags are defined below. If you want to add a new flag,
71152    in addition to the area below, you will also need to declare it in the
71153    `DS.Model` class.
71154  
71155  
71156     * [isEmpty](DS.Model.html#property_isEmpty)
71157     * [isLoading](DS.Model.html#property_isLoading)
71158     * [isLoaded](DS.Model.html#property_isLoaded)
71159     * [isDirty](DS.Model.html#property_isDirty)
71160     * [isSaving](DS.Model.html#property_isSaving)
71161     * [isDeleted](DS.Model.html#property_isDeleted)
71162     * [isNew](DS.Model.html#property_isNew)
71163     * [isValid](DS.Model.html#property_isValid)
71164  
71165    @namespace DS
71166    @class RootState
71167  */
71168
71169  function _didSetProperty(internalModel, context) {
71170    if (context.value === context.originalValue) {
71171      delete internalModel._attributes[context.name];
71172      internalModel.send('propertyWasReset', context.name);
71173    } else if (context.value !== context.oldValue) {
71174      internalModel.send('becomeDirty');
71175    }
71176
71177    internalModel.updateRecordArraysLater();
71178  }
71179
71180  // Implementation notes:
71181  //
71182  // Each state has a boolean value for all of the following flags:
71183  //
71184  // * isLoaded: The record has a populated `data` property. When a
71185  //   record is loaded via `store.find`, `isLoaded` is false
71186  //   until the adapter sets it. When a record is created locally,
71187  //   its `isLoaded` property is always true.
71188  // * isDirty: The record has local changes that have not yet been
71189  //   saved by the adapter. This includes records that have been
71190  //   created (but not yet saved) or deleted.
71191  // * isSaving: The record has been committed, but
71192  //   the adapter has not yet acknowledged that the changes have
71193  //   been persisted to the backend.
71194  // * isDeleted: The record was marked for deletion. When `isDeleted`
71195  //   is true and `isDirty` is true, the record is deleted locally
71196  //   but the deletion was not yet persisted. When `isSaving` is
71197  //   true, the change is in-flight. When both `isDirty` and
71198  //   `isSaving` are false, the change has persisted.
71199  // * isNew: The record was created on the client and the adapter
71200  //   did not yet report that it was successfully saved.
71201  // * isValid: The adapter did not report any server-side validation
71202  //   failures.
71203
71204  // The dirty state is a abstract state whose functionality is
71205  // shared between the `created` and `updated` states.
71206  //
71207  // The deleted state shares the `isDirty` flag with the
71208  // subclasses of `DirtyState`, but with a very different
71209  // implementation.
71210  //
71211  // Dirty states have three child states:
71212  //
71213  // `uncommitted`: the store has not yet handed off the record
71214  //   to be saved.
71215  // `inFlight`: the store has handed off the record to be saved,
71216  //   but the adapter has not yet acknowledged success.
71217  // `invalid`: the record has invalid information and cannot be
71218  //   send to the adapter yet.
71219  var DirtyState = {
71220    initialState: 'uncommitted',
71221
71222    // FLAGS
71223    isDirty: true,
71224
71225    // SUBSTATES
71226
71227    // When a record first becomes dirty, it is `uncommitted`.
71228    // This means that there are local pending changes, but they
71229    // have not yet begun to be saved, and are not invalid.
71230    uncommitted: {
71231      // EVENTS
71232      didSetProperty: _didSetProperty,
71233
71234      //TODO(Igor) reloading now triggers a
71235      //loadingData event, though it seems fine?
71236      loadingData: _ember['default'].K,
71237
71238      propertyWasReset: function propertyWasReset(internalModel, name) {
71239        if (!internalModel.hasChangedAttributes()) {
71240          internalModel.send('rolledBack');
71241        }
71242      },
71243
71244      pushedData: function pushedData(internalModel) {
71245        internalModel.updateChangedAttributes();
71246
71247        if (!internalModel.hasChangedAttributes()) {
71248          internalModel.transitionTo('loaded.saved');
71249        }
71250      },
71251
71252      becomeDirty: _ember['default'].K,
71253
71254      willCommit: function willCommit(internalModel) {
71255        internalModel.transitionTo('inFlight');
71256      },
71257
71258      reloadRecord: function reloadRecord(internalModel, resolve) {
71259        resolve(internalModel.store.reloadRecord(internalModel));
71260      },
71261
71262      rolledBack: function rolledBack(internalModel) {
71263        internalModel.transitionTo('loaded.saved');
71264      },
71265
71266      becameInvalid: function becameInvalid(internalModel) {
71267        internalModel.transitionTo('invalid');
71268      },
71269
71270      rollback: function rollback(internalModel) {
71271        internalModel.rollbackAttributes();
71272        internalModel.triggerLater('ready');
71273      }
71274    },
71275
71276    // Once a record has been handed off to the adapter to be
71277    // saved, it is in the 'in flight' state. Changes to the
71278    // record cannot be made during this window.
71279    inFlight: {
71280      // FLAGS
71281      isSaving: true,
71282
71283      // EVENTS
71284      didSetProperty: _didSetProperty,
71285      becomeDirty: _ember['default'].K,
71286      pushedData: _ember['default'].K,
71287
71288      unloadRecord: assertAgainstUnloadRecord,
71289
71290      // TODO: More robust semantics around save-while-in-flight
71291      willCommit: _ember['default'].K,
71292
71293      didCommit: function didCommit(internalModel) {
71294        var dirtyType = get(this, 'dirtyType');
71295
71296        internalModel.transitionTo('saved');
71297        internalModel.send('invokeLifecycleCallbacks', dirtyType);
71298      },
71299
71300      becameInvalid: function becameInvalid(internalModel) {
71301        internalModel.transitionTo('invalid');
71302        internalModel.send('invokeLifecycleCallbacks');
71303      },
71304
71305      becameError: function becameError(internalModel) {
71306        internalModel.transitionTo('uncommitted');
71307        internalModel.triggerLater('becameError', internalModel);
71308      }
71309    },
71310
71311    // A record is in the `invalid` if the adapter has indicated
71312    // the the record failed server-side invalidations.
71313    invalid: {
71314      // FLAGS
71315      isValid: false,
71316
71317      // EVENTS
71318      deleteRecord: function deleteRecord(internalModel) {
71319        internalModel.transitionTo('deleted.uncommitted');
71320      },
71321
71322      didSetProperty: function didSetProperty(internalModel, context) {
71323        internalModel.removeErrorMessageFromAttribute(context.name);
71324
71325        _didSetProperty(internalModel, context);
71326
71327        if (!internalModel.hasErrors()) {
71328          this.becameValid(internalModel);
71329        }
71330      },
71331
71332      becameInvalid: _ember['default'].K,
71333      becomeDirty: _ember['default'].K,
71334      pushedData: _ember['default'].K,
71335
71336      willCommit: function willCommit(internalModel) {
71337        internalModel.clearErrorMessages();
71338        internalModel.transitionTo('inFlight');
71339      },
71340
71341      rolledBack: function rolledBack(internalModel) {
71342        internalModel.clearErrorMessages();
71343        internalModel.transitionTo('loaded.saved');
71344        internalModel.triggerLater('ready');
71345      },
71346
71347      becameValid: function becameValid(internalModel) {
71348        internalModel.transitionTo('uncommitted');
71349      },
71350
71351      invokeLifecycleCallbacks: function invokeLifecycleCallbacks(internalModel) {
71352        internalModel.triggerLater('becameInvalid', internalModel);
71353      }
71354    }
71355  };
71356
71357  // The created and updated states are created outside the state
71358  // chart so we can reopen their substates and add mixins as
71359  // necessary.
71360
71361  function deepClone(object) {
71362    var clone = {};
71363    var value;
71364
71365    for (var prop in object) {
71366      value = object[prop];
71367      if (value && typeof value === 'object') {
71368        clone[prop] = deepClone(value);
71369      } else {
71370        clone[prop] = value;
71371      }
71372    }
71373
71374    return clone;
71375  }
71376
71377  function mixin(original, hash) {
71378    for (var prop in hash) {
71379      original[prop] = hash[prop];
71380    }
71381
71382    return original;
71383  }
71384
71385  function dirtyState(options) {
71386    var newState = deepClone(DirtyState);
71387    return mixin(newState, options);
71388  }
71389
71390  var createdState = dirtyState({
71391    dirtyType: 'created',
71392    // FLAGS
71393    isNew: true
71394  });
71395
71396  createdState.invalid.rolledBack = function (internalModel) {
71397    internalModel.transitionTo('deleted.saved');
71398  };
71399  createdState.uncommitted.rolledBack = function (internalModel) {
71400    internalModel.transitionTo('deleted.saved');
71401  };
71402
71403  var updatedState = dirtyState({
71404    dirtyType: 'updated'
71405  });
71406
71407  function createdStateDeleteRecord(internalModel) {
71408    internalModel.transitionTo('deleted.saved');
71409    internalModel.send('invokeLifecycleCallbacks');
71410  }
71411
71412  createdState.uncommitted.deleteRecord = createdStateDeleteRecord;
71413
71414  createdState.invalid.deleteRecord = createdStateDeleteRecord;
71415
71416  createdState.uncommitted.rollback = function (internalModel) {
71417    DirtyState.uncommitted.rollback.apply(this, arguments);
71418    internalModel.transitionTo('deleted.saved');
71419  };
71420
71421  createdState.uncommitted.pushedData = function (internalModel) {
71422    internalModel.transitionTo('loaded.updated.uncommitted');
71423    internalModel.triggerLater('didLoad');
71424  };
71425
71426  createdState.uncommitted.propertyWasReset = _ember['default'].K;
71427
71428  function assertAgainstUnloadRecord(internalModel) {
71429    (0, _emberDataPrivateDebug.assert)("You can only unload a record which is not inFlight. `" + internalModel + "`", false);
71430  }
71431
71432  updatedState.inFlight.unloadRecord = assertAgainstUnloadRecord;
71433
71434  updatedState.uncommitted.deleteRecord = function (internalModel) {
71435    internalModel.transitionTo('deleted.uncommitted');
71436  };
71437
71438  var RootState = {
71439    // FLAGS
71440    isEmpty: false,
71441    isLoading: false,
71442    isLoaded: false,
71443    isDirty: false,
71444    isSaving: false,
71445    isDeleted: false,
71446    isNew: false,
71447    isValid: true,
71448
71449    // DEFAULT EVENTS
71450
71451    // Trying to roll back if you're not in the dirty state
71452    // doesn't change your state. For example, if you're in the
71453    // in-flight state, rolling back the record doesn't move
71454    // you out of the in-flight state.
71455    rolledBack: _ember['default'].K,
71456    unloadRecord: function unloadRecord(internalModel) {
71457      // clear relationships before moving to deleted state
71458      // otherwise it fails
71459      internalModel.clearRelationships();
71460      internalModel.transitionTo('deleted.saved');
71461    },
71462
71463    propertyWasReset: _ember['default'].K,
71464
71465    // SUBSTATES
71466
71467    // A record begins its lifecycle in the `empty` state.
71468    // If its data will come from the adapter, it will
71469    // transition into the `loading` state. Otherwise, if
71470    // the record is being created on the client, it will
71471    // transition into the `created` state.
71472    empty: {
71473      isEmpty: true,
71474
71475      // EVENTS
71476      loadingData: function loadingData(internalModel, promise) {
71477        internalModel._loadingPromise = promise;
71478        internalModel.transitionTo('loading');
71479      },
71480
71481      loadedData: function loadedData(internalModel) {
71482        internalModel.transitionTo('loaded.created.uncommitted');
71483        internalModel.triggerLater('ready');
71484      },
71485
71486      pushedData: function pushedData(internalModel) {
71487        internalModel.transitionTo('loaded.saved');
71488        internalModel.triggerLater('didLoad');
71489        internalModel.triggerLater('ready');
71490      }
71491    },
71492
71493    // A record enters this state when the store asks
71494    // the adapter for its data. It remains in this state
71495    // until the adapter provides the requested data.
71496    //
71497    // Usually, this process is asynchronous, using an
71498    // XHR to retrieve the data.
71499    loading: {
71500      // FLAGS
71501      isLoading: true,
71502
71503      exit: function exit(internalModel) {
71504        internalModel._loadingPromise = null;
71505      },
71506
71507      // EVENTS
71508      pushedData: function pushedData(internalModel) {
71509        internalModel.transitionTo('loaded.saved');
71510        internalModel.triggerLater('didLoad');
71511        internalModel.triggerLater('ready');
71512        //TODO this seems out of place here
71513        internalModel.didCleanError();
71514      },
71515
71516      becameError: function becameError(internalModel) {
71517        internalModel.triggerLater('becameError', internalModel);
71518      },
71519
71520      notFound: function notFound(internalModel) {
71521        internalModel.transitionTo('empty');
71522      }
71523    },
71524
71525    // A record enters this state when its data is populated.
71526    // Most of a record's lifecycle is spent inside substates
71527    // of the `loaded` state.
71528    loaded: {
71529      initialState: 'saved',
71530
71531      // FLAGS
71532      isLoaded: true,
71533
71534      //TODO(Igor) Reloading now triggers a loadingData event,
71535      //but it should be ok?
71536      loadingData: _ember['default'].K,
71537
71538      // SUBSTATES
71539
71540      // If there are no local changes to a record, it remains
71541      // in the `saved` state.
71542      saved: {
71543        setup: function setup(internalModel) {
71544          if (internalModel.hasChangedAttributes()) {
71545            internalModel.adapterDidDirty();
71546          }
71547        },
71548
71549        // EVENTS
71550        didSetProperty: _didSetProperty,
71551
71552        pushedData: _ember['default'].K,
71553
71554        becomeDirty: function becomeDirty(internalModel) {
71555          internalModel.transitionTo('updated.uncommitted');
71556        },
71557
71558        willCommit: function willCommit(internalModel) {
71559          internalModel.transitionTo('updated.inFlight');
71560        },
71561
71562        reloadRecord: function reloadRecord(internalModel, resolve) {
71563          resolve(internalModel.store.reloadRecord(internalModel));
71564        },
71565
71566        deleteRecord: function deleteRecord(internalModel) {
71567          internalModel.transitionTo('deleted.uncommitted');
71568        },
71569
71570        unloadRecord: function unloadRecord(internalModel) {
71571          // clear relationships before moving to deleted state
71572          // otherwise it fails
71573          internalModel.clearRelationships();
71574          internalModel.transitionTo('deleted.saved');
71575        },
71576
71577        didCommit: function didCommit(internalModel) {
71578          internalModel.send('invokeLifecycleCallbacks', get(internalModel, 'lastDirtyType'));
71579        },
71580
71581        // loaded.saved.notFound would be triggered by a failed
71582        // `reload()` on an unchanged record
71583        notFound: _ember['default'].K
71584
71585      },
71586
71587      // A record is in this state after it has been locally
71588      // created but before the adapter has indicated that
71589      // it has been saved.
71590      created: createdState,
71591
71592      // A record is in this state if it has already been
71593      // saved to the server, but there are new local changes
71594      // that have not yet been saved.
71595      updated: updatedState
71596    },
71597
71598    // A record is in this state if it was deleted from the store.
71599    deleted: {
71600      initialState: 'uncommitted',
71601      dirtyType: 'deleted',
71602
71603      // FLAGS
71604      isDeleted: true,
71605      isLoaded: true,
71606      isDirty: true,
71607
71608      // TRANSITIONS
71609      setup: function setup(internalModel) {
71610        internalModel.updateRecordArrays();
71611      },
71612
71613      // SUBSTATES
71614
71615      // When a record is deleted, it enters the `start`
71616      // state. It will exit this state when the record
71617      // starts to commit.
71618      uncommitted: {
71619
71620        // EVENTS
71621
71622        willCommit: function willCommit(internalModel) {
71623          internalModel.transitionTo('inFlight');
71624        },
71625
71626        rollback: function rollback(internalModel) {
71627          internalModel.rollbackAttributes();
71628          internalModel.triggerLater('ready');
71629        },
71630
71631        pushedData: _ember['default'].K,
71632        becomeDirty: _ember['default'].K,
71633        deleteRecord: _ember['default'].K,
71634
71635        rolledBack: function rolledBack(internalModel) {
71636          internalModel.transitionTo('loaded.saved');
71637          internalModel.triggerLater('ready');
71638        }
71639      },
71640
71641      // After a record starts committing, but
71642      // before the adapter indicates that the deletion
71643      // has saved to the server, a record is in the
71644      // `inFlight` substate of `deleted`.
71645      inFlight: {
71646        // FLAGS
71647        isSaving: true,
71648
71649        // EVENTS
71650
71651        unloadRecord: assertAgainstUnloadRecord,
71652
71653        // TODO: More robust semantics around save-while-in-flight
71654        willCommit: _ember['default'].K,
71655        didCommit: function didCommit(internalModel) {
71656          internalModel.transitionTo('saved');
71657
71658          internalModel.send('invokeLifecycleCallbacks');
71659        },
71660
71661        becameError: function becameError(internalModel) {
71662          internalModel.transitionTo('uncommitted');
71663          internalModel.triggerLater('becameError', internalModel);
71664        },
71665
71666        becameInvalid: function becameInvalid(internalModel) {
71667          internalModel.transitionTo('invalid');
71668          internalModel.triggerLater('becameInvalid', internalModel);
71669        }
71670      },
71671
71672      // Once the adapter indicates that the deletion has
71673      // been saved, the record enters the `saved` substate
71674      // of `deleted`.
71675      saved: {
71676        // FLAGS
71677        isDirty: false,
71678
71679        setup: function setup(internalModel) {
71680          internalModel.clearRelationships();
71681          var store = internalModel.store;
71682          store._dematerializeRecord(internalModel);
71683        },
71684
71685        invokeLifecycleCallbacks: function invokeLifecycleCallbacks(internalModel) {
71686          internalModel.triggerLater('didDelete', internalModel);
71687          internalModel.triggerLater('didCommit', internalModel);
71688        },
71689
71690        willCommit: _ember['default'].K,
71691
71692        didCommit: _ember['default'].K
71693      },
71694
71695      invalid: {
71696        isValid: false,
71697
71698        didSetProperty: function didSetProperty(internalModel, context) {
71699          internalModel.removeErrorMessageFromAttribute(context.name);
71700
71701          _didSetProperty(internalModel, context);
71702
71703          if (!internalModel.hasErrors()) {
71704            this.becameValid(internalModel);
71705          }
71706        },
71707
71708        becameInvalid: _ember['default'].K,
71709        becomeDirty: _ember['default'].K,
71710        deleteRecord: _ember['default'].K,
71711        willCommit: _ember['default'].K,
71712
71713        rolledBack: function rolledBack(internalModel) {
71714          internalModel.clearErrorMessages();
71715          internalModel.transitionTo('loaded.saved');
71716          internalModel.triggerLater('ready');
71717        },
71718
71719        becameValid: function becameValid(internalModel) {
71720          internalModel.transitionTo('uncommitted');
71721        }
71722
71723      }
71724    },
71725
71726    invokeLifecycleCallbacks: function invokeLifecycleCallbacks(internalModel, dirtyType) {
71727      if (dirtyType === 'created') {
71728        internalModel.triggerLater('didCreate', internalModel);
71729      } else {
71730        internalModel.triggerLater('didUpdate', internalModel);
71731      }
71732
71733      internalModel.triggerLater('didCommit', internalModel);
71734    }
71735  };
71736
71737  function wireState(object, parent, name) {
71738    // TODO: Use Object.create and copy instead
71739    object = mixin(parent ? Object.create(parent) : {}, object);
71740    object.parentState = parent;
71741    object.stateName = name;
71742
71743    for (var prop in object) {
71744      if (!object.hasOwnProperty(prop) || prop === 'parentState' || prop === 'stateName') {
71745        continue;
71746      }
71747      if (typeof object[prop] === 'object') {
71748        object[prop] = wireState(object[prop], object, name + "." + prop);
71749      }
71750    }
71751
71752    return object;
71753  }
71754
71755  RootState = wireState(RootState, null, "root");
71756
71757  exports['default'] = RootState;
71758});
71759define('ember-data/-private/system/normalize-link', ['exports'], function (exports) {
71760  'use strict';
71761
71762  exports['default'] = _normalizeLink;
71763
71764  /**
71765    This method normalizes a link to an "links object". If the passed link is
71766    already an object it's returned without any modifications.
71767  
71768    See http://jsonapi.org/format/#document-links for more information.
71769  
71770    @method _normalizeLink
71771    @private
71772    @param {String} link
71773    @return {Object|null}
71774    @for DS
71775  */
71776  function _normalizeLink(link) {
71777    switch (typeof link) {
71778      case 'object':
71779        return link;
71780      case 'string':
71781        return { href: link };
71782    }
71783    return null;
71784  }
71785});
71786define('ember-data/-private/system/normalize-model-name', ['exports', 'ember'], function (exports, _ember) {
71787  'use strict';
71788
71789  exports['default'] = normalizeModelName;
71790
71791  /**
71792    All modelNames are dasherized internally. Changing this function may
71793    require changes to other normalization hooks (such as typeForRoot).
71794    @method normalizeModelName
71795    @public
71796    @param {String} modelName
71797    @return {String} if the adapter can generate one, an ID
71798    @for DS
71799  */
71800  function normalizeModelName(modelName) {
71801    return _ember['default'].String.dasherize(modelName);
71802  }
71803});
71804define('ember-data/-private/system/ordered-set', ['exports', 'ember'], function (exports, _ember) {
71805  'use strict';
71806
71807  exports['default'] = OrderedSet;
71808
71809  var EmberOrderedSet = _ember['default'].OrderedSet;
71810  var guidFor = _ember['default'].guidFor;
71811  function OrderedSet() {
71812    this._super$constructor();
71813  }
71814
71815  OrderedSet.create = function () {
71816    var Constructor = this;
71817    return new Constructor();
71818  };
71819
71820  OrderedSet.prototype = Object.create(EmberOrderedSet.prototype);
71821  OrderedSet.prototype.constructor = OrderedSet;
71822  OrderedSet.prototype._super$constructor = EmberOrderedSet;
71823
71824  OrderedSet.prototype.addWithIndex = function (obj, idx) {
71825    var guid = guidFor(obj);
71826    var presenceSet = this.presenceSet;
71827    var list = this.list;
71828
71829    if (presenceSet[guid] === true) {
71830      return;
71831    }
71832
71833    presenceSet[guid] = true;
71834
71835    if (idx === undefined || idx === null) {
71836      list.push(obj);
71837    } else {
71838      list.splice(idx, 0, obj);
71839    }
71840
71841    this.size += 1;
71842
71843    return this;
71844  };
71845});
71846define('ember-data/-private/system/promise-proxies', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
71847  'use strict';
71848
71849  var Promise = _ember['default'].RSVP.Promise;
71850  var get = _ember['default'].get;
71851
71852  /**
71853    A `PromiseArray` is an object that acts like both an `Ember.Array`
71854    and a promise. When the promise is resolved the resulting value
71855    will be set to the `PromiseArray`'s `content` property. This makes
71856    it easy to create data bindings with the `PromiseArray` that will be
71857    updated when the promise resolves.
71858  
71859    For more information see the [Ember.PromiseProxyMixin
71860    documentation](/api/classes/Ember.PromiseProxyMixin.html).
71861  
71862    Example
71863  
71864    ```javascript
71865    var promiseArray = DS.PromiseArray.create({
71866      promise: $.getJSON('/some/remote/data.json')
71867    });
71868  
71869    promiseArray.get('length'); // 0
71870  
71871    promiseArray.then(function() {
71872      promiseArray.get('length'); // 100
71873    });
71874    ```
71875  
71876    @class PromiseArray
71877    @namespace DS
71878    @extends Ember.ArrayProxy
71879    @uses Ember.PromiseProxyMixin
71880  */
71881  var PromiseArray = _ember['default'].ArrayProxy.extend(_ember['default'].PromiseProxyMixin);
71882
71883  /**
71884    A `PromiseObject` is an object that acts like both an `Ember.Object`
71885    and a promise. When the promise is resolved, then the resulting value
71886    will be set to the `PromiseObject`'s `content` property. This makes
71887    it easy to create data bindings with the `PromiseObject` that will
71888    be updated when the promise resolves.
71889  
71890    For more information see the [Ember.PromiseProxyMixin
71891    documentation](/api/classes/Ember.PromiseProxyMixin.html).
71892  
71893    Example
71894  
71895    ```javascript
71896    var promiseObject = DS.PromiseObject.create({
71897      promise: $.getJSON('/some/remote/data.json')
71898    });
71899  
71900    promiseObject.get('name'); // null
71901  
71902    promiseObject.then(function() {
71903      promiseObject.get('name'); // 'Tomster'
71904    });
71905    ```
71906  
71907    @class PromiseObject
71908    @namespace DS
71909    @extends Ember.ObjectProxy
71910    @uses Ember.PromiseProxyMixin
71911  */
71912  var PromiseObject = _ember['default'].ObjectProxy.extend(_ember['default'].PromiseProxyMixin);
71913
71914  var promiseObject = function promiseObject(promise, label) {
71915    return PromiseObject.create({
71916      promise: Promise.resolve(promise, label)
71917    });
71918  };
71919
71920  var promiseArray = function promiseArray(promise, label) {
71921    return PromiseArray.create({
71922      promise: Promise.resolve(promise, label)
71923    });
71924  };
71925
71926  /**
71927    A PromiseManyArray is a PromiseArray that also proxies certain method calls
71928    to the underlying manyArray.
71929    Right now we proxy:
71930  
71931      * `reload()`
71932      * `createRecord()`
71933      * `on()`
71934      * `one()`
71935      * `trigger()`
71936      * `off()`
71937      * `has()`
71938  
71939    @class PromiseManyArray
71940    @namespace DS
71941    @extends Ember.ArrayProxy
71942  */
71943
71944  function proxyToContent(method) {
71945    return function () {
71946      var content = get(this, 'content');
71947      return content[method].apply(content, arguments);
71948    };
71949  }
71950
71951  var PromiseManyArray = PromiseArray.extend({
71952    reload: function reload() {
71953      //I don't think this should ever happen right now, but worth guarding if we refactor the async relationships
71954      (0, _emberDataPrivateDebug.assert)('You are trying to reload an async manyArray before it has been created', get(this, 'content'));
71955      return PromiseManyArray.create({
71956        promise: get(this, 'content').reload()
71957      });
71958    },
71959
71960    createRecord: proxyToContent('createRecord'),
71961
71962    on: proxyToContent('on'),
71963
71964    one: proxyToContent('one'),
71965
71966    trigger: proxyToContent('trigger'),
71967
71968    off: proxyToContent('off'),
71969
71970    has: proxyToContent('has')
71971  });
71972
71973  var promiseManyArray = function promiseManyArray(promise, label) {
71974    return PromiseManyArray.create({
71975      promise: Promise.resolve(promise, label)
71976    });
71977  };
71978
71979  exports.PromiseArray = PromiseArray;
71980  exports.PromiseObject = PromiseObject;
71981  exports.PromiseManyArray = PromiseManyArray;
71982  exports.promiseArray = promiseArray;
71983  exports.promiseObject = promiseObject;
71984  exports.promiseManyArray = promiseManyArray;
71985});
71986define("ember-data/-private/system/record-array-manager", ["exports", "ember", "ember-data/-private/system/record-arrays", "ember-data/-private/system/ordered-set"], function (exports, _ember, _emberDataPrivateSystemRecordArrays, _emberDataPrivateSystemOrderedSet) {
71987  /**
71988    @module ember-data
71989  */
71990
71991  "use strict";
71992
71993  var MapWithDefault = _ember["default"].MapWithDefault;var get = _ember["default"].get;
71994
71995  /**
71996    @class RecordArrayManager
71997    @namespace DS
71998    @private
71999    @extends Ember.Object
72000  */
72001  exports["default"] = _ember["default"].Object.extend({
72002    init: function init() {
72003      var _this = this;
72004
72005      this.filteredRecordArrays = MapWithDefault.create({
72006        defaultValue: function defaultValue() {
72007          return [];
72008        }
72009      });
72010
72011      this.liveRecordArrays = MapWithDefault.create({
72012        defaultValue: function defaultValue(typeClass) {
72013          return _this.createRecordArray(typeClass);
72014        }
72015      });
72016
72017      this.changedRecords = [];
72018      this._adapterPopulatedRecordArrays = [];
72019    },
72020
72021    recordDidChange: function recordDidChange(record) {
72022      if (this.changedRecords.push(record) !== 1) {
72023        return;
72024      }
72025
72026      _ember["default"].run.schedule('actions', this, this.updateRecordArrays);
72027    },
72028
72029    recordArraysForRecord: function recordArraysForRecord(record) {
72030      record._recordArrays = record._recordArrays || _emberDataPrivateSystemOrderedSet["default"].create();
72031      return record._recordArrays;
72032    },
72033
72034    /**
72035      This method is invoked whenever data is loaded into the store by the
72036      adapter or updated by the adapter, or when a record has changed.
72037       It updates all record arrays that a record belongs to.
72038       To avoid thrashing, it only runs at most once per run loop.
72039       @method updateRecordArrays
72040    */
72041    updateRecordArrays: function updateRecordArrays() {
72042      var _this2 = this;
72043
72044      this.changedRecords.forEach(function (internalModel) {
72045        if (get(internalModel, 'record.isDestroyed') || get(internalModel, 'record.isDestroying') || get(internalModel, 'currentState.stateName') === 'root.deleted.saved') {
72046          _this2._recordWasDeleted(internalModel);
72047        } else {
72048          _this2._recordWasChanged(internalModel);
72049        }
72050      });
72051
72052      this.changedRecords.length = 0;
72053    },
72054
72055    _recordWasDeleted: function _recordWasDeleted(record) {
72056      var recordArrays = record._recordArrays;
72057
72058      if (!recordArrays) {
72059        return;
72060      }
72061
72062      recordArrays.forEach(function (array) {
72063        return array.removeInternalModel(record);
72064      });
72065
72066      record._recordArrays = null;
72067    },
72068
72069    _recordWasChanged: function _recordWasChanged(record) {
72070      var _this3 = this;
72071
72072      var typeClass = record.type;
72073      var recordArrays = this.filteredRecordArrays.get(typeClass);
72074      var filter;
72075      recordArrays.forEach(function (array) {
72076        filter = get(array, 'filterFunction');
72077        _this3.updateFilterRecordArray(array, filter, typeClass, record);
72078      });
72079    },
72080
72081    //Need to update live arrays on loading
72082    recordWasLoaded: function recordWasLoaded(record) {
72083      var _this4 = this;
72084
72085      var typeClass = record.type;
72086      var recordArrays = this.filteredRecordArrays.get(typeClass);
72087      var filter;
72088
72089      recordArrays.forEach(function (array) {
72090        filter = get(array, 'filterFunction');
72091        _this4.updateFilterRecordArray(array, filter, typeClass, record);
72092      });
72093
72094      if (this.liveRecordArrays.has(typeClass)) {
72095        var liveRecordArray = this.liveRecordArrays.get(typeClass);
72096        this._addRecordToRecordArray(liveRecordArray, record);
72097      }
72098    },
72099    /**
72100      Update an individual filter.
72101       @method updateFilterRecordArray
72102      @param {DS.FilteredRecordArray} array
72103      @param {Function} filter
72104      @param {DS.Model} typeClass
72105      @param {InternalModel} record
72106    */
72107    updateFilterRecordArray: function updateFilterRecordArray(array, filter, typeClass, record) {
72108      var shouldBeInArray = filter(record.getRecord());
72109      var recordArrays = this.recordArraysForRecord(record);
72110      if (shouldBeInArray) {
72111        this._addRecordToRecordArray(array, record);
72112      } else {
72113        recordArrays["delete"](array);
72114        array.removeInternalModel(record);
72115      }
72116    },
72117
72118    _addRecordToRecordArray: function _addRecordToRecordArray(array, record) {
72119      var recordArrays = this.recordArraysForRecord(record);
72120      if (!recordArrays.has(array)) {
72121        array.addInternalModel(record);
72122        recordArrays.add(array);
72123      }
72124    },
72125
72126    populateLiveRecordArray: function populateLiveRecordArray(array, modelName) {
72127      var typeMap = this.store.typeMapFor(modelName);
72128      var records = typeMap.records;
72129      var record;
72130
72131      for (var i = 0; i < records.length; i++) {
72132        record = records[i];
72133
72134        if (!record.isDeleted() && !record.isEmpty()) {
72135          this._addRecordToRecordArray(array, record);
72136        }
72137      }
72138    },
72139
72140    /**
72141      This method is invoked if the `filterFunction` property is
72142      changed on a `DS.FilteredRecordArray`.
72143       It essentially re-runs the filter from scratch. This same
72144      method is invoked when the filter is created in th first place.
72145       @method updateFilter
72146      @param {Array} array
72147      @param {String} modelName
72148      @param {Function} filter
72149    */
72150    updateFilter: function updateFilter(array, modelName, filter) {
72151      var typeMap = this.store.typeMapFor(modelName);
72152      var records = typeMap.records;
72153      var record;
72154
72155      for (var i = 0; i < records.length; i++) {
72156        record = records[i];
72157
72158        if (!record.isDeleted() && !record.isEmpty()) {
72159          this.updateFilterRecordArray(array, filter, modelName, record);
72160        }
72161      }
72162    },
72163
72164    /**
72165      Get the `DS.RecordArray` for a type, which contains all loaded records of
72166      given type.
72167       @method liveRecordArrayFor
72168      @param {Class} typeClass
72169      @return {DS.RecordArray}
72170    */
72171    liveRecordArrayFor: function liveRecordArrayFor(typeClass) {
72172      return this.liveRecordArrays.get(typeClass);
72173    },
72174
72175    /**
72176      Create a `DS.RecordArray` for a type.
72177       @method createRecordArray
72178      @param {Class} typeClass
72179      @return {DS.RecordArray}
72180    */
72181    createRecordArray: function createRecordArray(typeClass) {
72182      var array = _emberDataPrivateSystemRecordArrays.RecordArray.create({
72183        type: typeClass,
72184        content: _ember["default"].A(),
72185        store: this.store,
72186        isLoaded: true,
72187        manager: this
72188      });
72189
72190      return array;
72191    },
72192
72193    /**
72194      Create a `DS.FilteredRecordArray` for a type and register it for updates.
72195       @method createFilteredRecordArray
72196      @param {DS.Model} typeClass
72197      @param {Function} filter
72198      @param {Object} query (optional
72199      @return {DS.FilteredRecordArray}
72200    */
72201    createFilteredRecordArray: function createFilteredRecordArray(typeClass, filter, query) {
72202      var array = _emberDataPrivateSystemRecordArrays.FilteredRecordArray.create({
72203        query: query,
72204        type: typeClass,
72205        content: _ember["default"].A(),
72206        store: this.store,
72207        manager: this,
72208        filterFunction: filter
72209      });
72210
72211      this.registerFilteredRecordArray(array, typeClass, filter);
72212
72213      return array;
72214    },
72215
72216    /**
72217      Create a `DS.AdapterPopulatedRecordArray` for a type with given query.
72218       @method createAdapterPopulatedRecordArray
72219      @param {DS.Model} typeClass
72220      @param {Object} query
72221      @return {DS.AdapterPopulatedRecordArray}
72222    */
72223    createAdapterPopulatedRecordArray: function createAdapterPopulatedRecordArray(typeClass, query) {
72224      var array = _emberDataPrivateSystemRecordArrays.AdapterPopulatedRecordArray.create({
72225        type: typeClass,
72226        query: query,
72227        content: _ember["default"].A(),
72228        store: this.store,
72229        manager: this
72230      });
72231
72232      this._adapterPopulatedRecordArrays.push(array);
72233
72234      return array;
72235    },
72236
72237    /**
72238      Register a RecordArray for a given type to be backed by
72239      a filter function. This will cause the array to update
72240      automatically when records of that type change attribute
72241      values or states.
72242       @method registerFilteredRecordArray
72243      @param {DS.RecordArray} array
72244      @param {DS.Model} typeClass
72245      @param {Function} filter
72246    */
72247    registerFilteredRecordArray: function registerFilteredRecordArray(array, typeClass, filter) {
72248      var recordArrays = this.filteredRecordArrays.get(typeClass);
72249      recordArrays.push(array);
72250
72251      this.updateFilter(array, typeClass, filter);
72252    },
72253
72254    /**
72255      Unregister a RecordArray.
72256      So manager will not update this array.
72257       @method unregisterRecordArray
72258      @param {DS.RecordArray} array
72259    */
72260    unregisterRecordArray: function unregisterRecordArray(array) {
72261      var typeClass = array.type;
72262
72263      // unregister filtered record array
72264      var recordArrays = this.filteredRecordArrays.get(typeClass);
72265      var removedFromFiltered = remove(recordArrays, array);
72266
72267      // remove from adapter populated record array
72268      var removedFromAdapterPopulated = remove(this._adapterPopulatedRecordArrays, array);
72269
72270      if (!removedFromFiltered && !removedFromAdapterPopulated) {
72271
72272        // unregister live record array
72273        if (this.liveRecordArrays.has(typeClass)) {
72274          var liveRecordArrayForType = this.liveRecordArrayFor(typeClass);
72275          if (array === liveRecordArrayForType) {
72276            this.liveRecordArrays["delete"](typeClass);
72277          }
72278        }
72279      }
72280    },
72281
72282    willDestroy: function willDestroy() {
72283      this._super.apply(this, arguments);
72284
72285      this.filteredRecordArrays.forEach(function (value) {
72286        return flatten(value).forEach(destroy);
72287      });
72288      this.liveRecordArrays.forEach(destroy);
72289      this._adapterPopulatedRecordArrays.forEach(destroy);
72290    }
72291  });
72292
72293  function destroy(entry) {
72294    entry.destroy();
72295  }
72296
72297  function flatten(list) {
72298    var length = list.length;
72299    var result = _ember["default"].A();
72300
72301    for (var i = 0; i < length; i++) {
72302      result = result.concat(list[i]);
72303    }
72304
72305    return result;
72306  }
72307
72308  function remove(array, item) {
72309    var index = array.indexOf(item);
72310
72311    if (index !== -1) {
72312      array.splice(index, 1);
72313      return true;
72314    }
72315
72316    return false;
72317  }
72318});
72319define("ember-data/-private/system/record-arrays", ["exports", "ember-data/-private/system/record-arrays/record-array", "ember-data/-private/system/record-arrays/filtered-record-array", "ember-data/-private/system/record-arrays/adapter-populated-record-array"], function (exports, _emberDataPrivateSystemRecordArraysRecordArray, _emberDataPrivateSystemRecordArraysFilteredRecordArray, _emberDataPrivateSystemRecordArraysAdapterPopulatedRecordArray) {
72320  /**
72321    @module ember-data
72322  */
72323
72324  "use strict";
72325
72326  exports.RecordArray = _emberDataPrivateSystemRecordArraysRecordArray["default"];
72327  exports.FilteredRecordArray = _emberDataPrivateSystemRecordArraysFilteredRecordArray["default"];
72328  exports.AdapterPopulatedRecordArray = _emberDataPrivateSystemRecordArraysAdapterPopulatedRecordArray["default"];
72329});
72330define("ember-data/-private/system/record-arrays/adapter-populated-record-array", ["exports", "ember", "ember-data/-private/system/record-arrays/record-array", "ember-data/-private/system/clone-null", "ember-data/-private/features"], function (exports, _ember, _emberDataPrivateSystemRecordArraysRecordArray, _emberDataPrivateSystemCloneNull, _emberDataPrivateFeatures) {
72331  "use strict";
72332
72333  /**
72334    @module ember-data
72335  */
72336
72337  var get = _ember["default"].get;
72338
72339  /**
72340    Represents an ordered list of records whose order and membership is
72341    determined by the adapter. For example, a query sent to the adapter
72342    may trigger a search on the server, whose results would be loaded
72343    into an instance of the `AdapterPopulatedRecordArray`.
72344  
72345    @class AdapterPopulatedRecordArray
72346    @namespace DS
72347    @extends DS.RecordArray
72348  */
72349  exports["default"] = _emberDataPrivateSystemRecordArraysRecordArray["default"].extend({
72350    query: null,
72351
72352    replace: function replace() {
72353      var type = get(this, 'type').toString();
72354      throw new Error("The result of a server query (on " + type + ") is immutable.");
72355    },
72356
72357    _update: function _update() {
72358      var store = get(this, 'store');
72359      var modelName = get(this, 'type.modelName');
72360      var query = get(this, 'query');
72361
72362      return store._query(modelName, query, this);
72363    },
72364
72365    /**
72366      @method loadRecords
72367      @param {Array} records
72368      @param {Object} payload normalized payload
72369      @private
72370    */
72371    loadRecords: function loadRecords(records, payload) {
72372      var _this = this;
72373
72374      //TODO Optimize
72375      var internalModels = _ember["default"].A(records).mapBy('_internalModel');
72376      this.setProperties({
72377        content: _ember["default"].A(internalModels),
72378        isLoaded: true,
72379        isUpdating: false,
72380        meta: (0, _emberDataPrivateSystemCloneNull["default"])(payload.meta)
72381      });
72382
72383      if (true) {
72384        this.set('links', (0, _emberDataPrivateSystemCloneNull["default"])(payload.links));
72385      }
72386
72387      internalModels.forEach(function (record) {
72388        _this.manager.recordArraysForRecord(record).add(_this);
72389      });
72390
72391      // TODO: should triggering didLoad event be the last action of the runLoop?
72392      _ember["default"].run.once(this, 'trigger', 'didLoad');
72393    }
72394  });
72395});
72396define('ember-data/-private/system/record-arrays/filtered-record-array', ['exports', 'ember', 'ember-data/-private/system/record-arrays/record-array'], function (exports, _ember, _emberDataPrivateSystemRecordArraysRecordArray) {
72397  'use strict';
72398
72399  /**
72400    @module ember-data
72401  */
72402
72403  var get = _ember['default'].get;
72404
72405  /**
72406    Represents a list of records whose membership is determined by the
72407    store. As records are created, loaded, or modified, the store
72408    evaluates them to determine if they should be part of the record
72409    array.
72410  
72411    @class FilteredRecordArray
72412    @namespace DS
72413    @extends DS.RecordArray
72414  */
72415  exports['default'] = _emberDataPrivateSystemRecordArraysRecordArray['default'].extend({
72416    /**
72417      The filterFunction is a function used to test records from the store to
72418      determine if they should be part of the record array.
72419       Example
72420       ```javascript
72421      var allPeople = store.peekAll('person');
72422      allPeople.mapBy('name'); // ["Tom Dale", "Yehuda Katz", "Trek Glowacki"]
72423       var people = store.filter('person', function(person) {
72424        if (person.get('name').match(/Katz$/)) { return true; }
72425      });
72426      people.mapBy('name'); // ["Yehuda Katz"]
72427       var notKatzFilter = function(person) {
72428        return !person.get('name').match(/Katz$/);
72429      };
72430      people.set('filterFunction', notKatzFilter);
72431      people.mapBy('name'); // ["Tom Dale", "Trek Glowacki"]
72432      ```
72433       @method filterFunction
72434      @param {DS.Model} record
72435      @return {Boolean} `true` if the record should be in the array
72436    */
72437    filterFunction: null,
72438    isLoaded: true,
72439
72440    replace: function replace() {
72441      var type = get(this, 'type').toString();
72442      throw new Error("The result of a client-side filter (on " + type + ") is immutable.");
72443    },
72444
72445    /**
72446      @method updateFilter
72447      @private
72448    */
72449    _updateFilter: function _updateFilter() {
72450      var manager = get(this, 'manager');
72451      manager.updateFilter(this, get(this, 'type'), get(this, 'filterFunction'));
72452    },
72453
72454    updateFilter: _ember['default'].observer('filterFunction', function () {
72455      _ember['default'].run.once(this, this._updateFilter);
72456    })
72457  });
72458});
72459define("ember-data/-private/system/record-arrays/record-array", ["exports", "ember", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/snapshot-record-array"], function (exports, _ember, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemSnapshotRecordArray) {
72460  /**
72461    @module ember-data
72462  */
72463
72464  "use strict";
72465
72466  var get = _ember["default"].get;
72467  var set = _ember["default"].set;
72468
72469  /**
72470    A record array is an array that contains records of a certain type. The record
72471    array materializes records as needed when they are retrieved for the first
72472    time. You should not create record arrays yourself. Instead, an instance of
72473    `DS.RecordArray` or its subclasses will be returned by your application's store
72474    in response to queries.
72475  
72476    @class RecordArray
72477    @namespace DS
72478    @extends Ember.ArrayProxy
72479    @uses Ember.Evented
72480  */
72481
72482  exports["default"] = _ember["default"].ArrayProxy.extend(_ember["default"].Evented, {
72483    /**
72484      The model type contained by this record array.
72485       @property type
72486      @type DS.Model
72487    */
72488    type: null,
72489
72490    /**
72491      The array of client ids backing the record array. When a
72492      record is requested from the record array, the record
72493      for the client id at the same index is materialized, if
72494      necessary, by the store.
72495       @property content
72496      @private
72497      @type Ember.Array
72498    */
72499    content: null,
72500
72501    /**
72502      The flag to signal a `RecordArray` is finished loading data.
72503       Example
72504       ```javascript
72505      var people = store.peekAll('person');
72506      people.get('isLoaded'); // true
72507      ```
72508       @property isLoaded
72509      @type Boolean
72510    */
72511    isLoaded: false,
72512    /**
72513      The flag to signal a `RecordArray` is currently loading data.
72514       Example
72515       ```javascript
72516      var people = store.peekAll('person');
72517      people.get('isUpdating'); // false
72518      people.update();
72519      people.get('isUpdating'); // true
72520      ```
72521       @property isUpdating
72522      @type Boolean
72523    */
72524    isUpdating: false,
72525
72526    /**
72527      The store that created this record array.
72528       @property store
72529      @private
72530      @type DS.Store
72531    */
72532    store: null,
72533
72534    /**
72535      Retrieves an object from the content by index.
72536       @method objectAtContent
72537      @private
72538      @param {Number} index
72539      @return {DS.Model} record
72540    */
72541    objectAtContent: function objectAtContent(index) {
72542      var content = get(this, 'content');
72543      var internalModel = content.objectAt(index);
72544      return internalModel && internalModel.getRecord();
72545    },
72546
72547    /**
72548      Used to get the latest version of all of the records in this array
72549      from the adapter.
72550       Example
72551       ```javascript
72552      var people = store.peekAll('person');
72553      people.get('isUpdating'); // false
72554       people.update().then(function() {
72555        people.get('isUpdating'); // false
72556      });
72557       people.get('isUpdating'); // true
72558      ```
72559       @method update
72560    */
72561    update: function update() {
72562      if (get(this, 'isUpdating')) {
72563        return;
72564      }
72565
72566      this.set('isUpdating', true);
72567      return this._update();
72568    },
72569
72570    /*
72571      Update this RecordArray and return a promise which resolves once the update
72572      is finished.
72573     */
72574    _update: function _update() {
72575      var store = get(this, 'store');
72576      var modelName = get(this, 'type.modelName');
72577
72578      return store.findAll(modelName, { reload: true });
72579    },
72580
72581    /**
72582      Adds an internal model to the `RecordArray` without duplicates
72583       @method addInternalModel
72584      @private
72585      @param {InternalModel} internalModel
72586      @param {number} an optional index to insert at
72587    */
72588    addInternalModel: function addInternalModel(internalModel, idx) {
72589      var content = get(this, 'content');
72590      if (idx === undefined) {
72591        content.addObject(internalModel);
72592      } else if (!content.contains(internalModel)) {
72593        content.insertAt(idx, internalModel);
72594      }
72595    },
72596
72597    /**
72598      Removes an internalModel to the `RecordArray`.
72599       @method removeInternalModel
72600      @private
72601      @param {InternalModel} internalModel
72602    */
72603    removeInternalModel: function removeInternalModel(internalModel) {
72604      get(this, 'content').removeObject(internalModel);
72605    },
72606
72607    /**
72608      Saves all of the records in the `RecordArray`.
72609       Example
72610       ```javascript
72611      var messages = store.peekAll('message');
72612      messages.forEach(function(message) {
72613        message.set('hasBeenSeen', true);
72614      });
72615      messages.save();
72616      ```
72617       @method save
72618      @return {DS.PromiseArray} promise
72619    */
72620    save: function save() {
72621      var recordArray = this;
72622      var promiseLabel = "DS: RecordArray#save " + get(this, 'type');
72623      var promise = _ember["default"].RSVP.all(this.invoke("save"), promiseLabel).then(function (array) {
72624        return recordArray;
72625      }, null, "DS: RecordArray#save return RecordArray");
72626
72627      return _emberDataPrivateSystemPromiseProxies.PromiseArray.create({ promise: promise });
72628    },
72629
72630    _dissociateFromOwnRecords: function _dissociateFromOwnRecords() {
72631      var _this = this;
72632
72633      this.get('content').forEach(function (record) {
72634        var recordArrays = record._recordArrays;
72635
72636        if (recordArrays) {
72637          recordArrays["delete"](_this);
72638        }
72639      });
72640    },
72641
72642    /**
72643      @method _unregisterFromManager
72644      @private
72645    */
72646    _unregisterFromManager: function _unregisterFromManager() {
72647      var manager = get(this, 'manager');
72648      manager.unregisterRecordArray(this);
72649    },
72650
72651    willDestroy: function willDestroy() {
72652      this._unregisterFromManager();
72653      this._dissociateFromOwnRecords();
72654      set(this, 'content', undefined);
72655      this._super.apply(this, arguments);
72656    },
72657
72658    createSnapshot: function createSnapshot(options) {
72659      var meta = this.get('meta');
72660      return new _emberDataPrivateSystemSnapshotRecordArray["default"](this, meta, options);
72661    }
72662  });
72663});
72664define('ember-data/-private/system/references', ['exports', 'ember-data/-private/system/references/record', 'ember-data/-private/system/references/belongs-to', 'ember-data/-private/system/references/has-many'], function (exports, _emberDataPrivateSystemReferencesRecord, _emberDataPrivateSystemReferencesBelongsTo, _emberDataPrivateSystemReferencesHasMany) {
72665  'use strict';
72666
72667  exports.RecordReference = _emberDataPrivateSystemReferencesRecord['default'];
72668  exports.BelongsToReference = _emberDataPrivateSystemReferencesBelongsTo['default'];
72669  exports.HasManyReference = _emberDataPrivateSystemReferencesHasMany['default'];
72670});
72671define('ember-data/-private/system/references/belongs-to', ['exports', 'ember-data/model', 'ember', 'ember-data/-private/system/references/reference', 'ember-data/-private/features', 'ember-data/-private/debug'], function (exports, _emberDataModel, _ember, _emberDataPrivateSystemReferencesReference, _emberDataPrivateFeatures, _emberDataPrivateDebug) {
72672  'use strict';
72673
72674  var BelongsToReference = function BelongsToReference(store, parentInternalModel, belongsToRelationship
72674) {
72675    this._super$constructor(store, parentInternalModel);
72676    this.belongsToRelationship = belongsToRelationship;
72677    this.type = belongsToRelationship.relationshipMeta.type;
72678    this.parent = parentInternalModel.recordReference;
72679
72680    // TODO inverse
72681  };
72682
72683  BelongsToReference.prototype = Object.create(_emberDataPrivateSystemReferencesReference['default'].prototype);
72684  BelongsToReference.prototype.constructor = BelongsToReference;
72685  BelongsToReference.prototype._super$constructor = _emberDataPrivateSystemReferencesReference['default'];
72686
72687  BelongsToReference.prototype.remoteType = function () {
72688    if (this.belongsToRelationship.link) {
72689      return "link";
72690    }
72691
72692    return "id";
72693  };
72694
72695  BelongsToReference.prototype.id = function () {
72696    var inverseRecord = this.belongsToRelationship.inverseRecord;
72697    return inverseRecord && inverseRecord.id;
72698  };
72699
72700  BelongsToReference.prototype.link = function () {
72701    return this.belongsToRelationship.link;
72702  };
72703
72704  BelongsToReference.prototype.meta = function () {
72705    return this.belongsToRelationship.meta;
72706  };
72707
72708  BelongsToReference.prototype.push = function (objectOrPromise) {
72709    var _this = this;
72710
72711    return _ember['default'].RSVP.resolve(objectOrPromise).then(function (data) {
72712      var record;
72713
72714      if (data instanceof _emberDataModel['default']) {
72715        if (false) {
72716          (0, _emberDataPrivateDebug.deprecate)("BelongsToReference#push(DS.Model) is deprecated. Update relationship via `model.set('relationshipName', value)` instead.", false, {
72717            id: 'ds.references.belongs-to.push-record',
72718            until: '3.0'
72719          });
72720        }
72721        record = data;
72722      } else {
72723        record = _this.store.push(data);
72724      }
72725
72726      (0, _emberDataPrivateDebug.assertPolymorphicType)(_this.internalModel, _this.belongsToRelationship.relationshipMeta, record._internalModel);
72727
72728      _this.belongsToRelationship.setCanonicalRecord(record._internalModel);
72729
72730      return record;
72731    });
72732  };
72733
72734  BelongsToReference.prototype.value = function () {
72735    var inverseRecord = this.belongsToRelationship.inverseRecord;
72736
72737    if (inverseRecord && inverseRecord.record) {
72738      return inverseRecord.record;
72739    }
72740
72741    return null;
72742  };
72743
72744  BelongsToReference.prototype.load = function () {
72745    var _this2 = this;
72746
72747    if (this.remoteType() === "id") {
72748      return this.belongsToRelationship.getRecord();
72749    }
72750
72751    if (this.remoteType() === "link") {
72752      return this.belongsToRelationship.findLink().then(function (internalModel) {
72753        return _this2.value();
72754      });
72755    }
72756  };
72757
72758  BelongsToReference.prototype.reload = function () {
72759    var _this3 = this;
72760
72761    return this.belongsToRelationship.reload().then(function (internalModel) {
72762      return _this3.value();
72763    });
72764  };
72765
72766  exports['default'] = BelongsToReference;
72767});
72768define('ember-data/-private/system/references/has-many', ['exports', 'ember', 'ember-data/-private/system/references/reference', 'ember-data/-private/debug', 'ember-data/-private/features'], function (exports, _ember, _emberDataPrivateSystemReferencesReference, _emberDataPrivateDebug, _emberDataPrivateFeatures) {
72769  'use strict';
72770
72771  var get = _ember['default'].get;
72772
72773  var HasManyReference = function HasManyReference(store, parentInternalModel, hasManyRelationship) {
72774    this._super$constructor(store, parentInternalModel);
72775    this.hasManyRelationship = hasManyRelationship;
72776    this.type = hasManyRelationship.relationshipMeta.type;
72777    this.parent = parentInternalModel.recordReference;
72778
72779    // TODO inverse
72780  };
72781
72782  HasManyReference.prototype = Object.create(_emberDataPrivateSystemReferencesReference['default'].prototype);
72783  HasManyReference.prototype.constructor = HasManyReference;
72784  HasManyReference.prototype._super$constructor = _emberDataPrivateSystemReferencesReference['default'];
72785
72786  HasManyReference.prototype.remoteType = function () {
72787    if (this.hasManyRelationship.link) {
72788      return "link";
72789    }
72790
72791    return "ids";
72792  };
72793
72794  HasManyReference.prototype.link = function () {
72795    return this.hasManyRelationship.link;
72796  };
72797
72798  HasManyReference.prototype.ids = function () {
72799    var members = this.hasManyRelationship.members;
72800    var ids = members.toArray().map(function (internalModel) {
72801      return internalModel.id;
72802    });
72803
72804    return ids;
72805  };
72806
72807  HasManyReference.prototype.meta = function () {
72808    return this.hasManyRelationship.manyArray.meta;
72809  };
72810
72811  HasManyReference.prototype.push = function (objectOrPromise) {
72812    var _this = this;
72813
72814    return _ember['default'].RSVP.resolve(objectOrPromise).then(function (payload) {
72815      var array = payload;
72816
72817      if (false) {
72818        (0, _emberDataPrivateDebug.deprecate)("HasManyReference#push(array) is deprecated. Push a JSON-API document instead.", !Array.isArray(payload), {
72819          id: 'ds.references.has-many.push-array',
72820          until: '3.0'
72821        });
72822      }
72823
72824      var useLegacyArrayPush = true;
72825      if (typeof payload === "object" && payload.data) {
72826        array = payload.data;
72827        useLegacyArrayPush = array.length && array[0].data;
72828
72829        if (false) {
72830          (0, _emberDataPrivateDebug.deprecate)("HasManyReference#push() expects a valid JSON-API document.", !useLegacyArrayPush, {
72831            id: 'ds.references.has-many.push-invalid-json-api',
72832            until: '3.0'
72833          });
72834        }
72835      }
72836
72837      if (!false) {
72838        useLegacyArrayPush = true;
72839      }
72840
72841      var internalModels = undefined;
72842      if (useLegacyArrayPush) {
72843        internalModels = array.map(function (obj) {
72844          var record = _this.store.push(obj);
72845
72846          (0, _emberDataPrivateDebug.runInDebug)(function () {
72847            var relationshipMeta = _this.hasManyRelationship.relationshipMeta;
72848            (0, _emberDataPrivateDebug.assertPolymorphicType)(_this.internalModel, relationshipMeta, record._internalModel);
72849          });
72850
72851          return record._internalModel;
72852        });
72853      } else {
72854        var records = _this.store.push(payload);
72855        internalModels = _ember['default'].A(records).mapBy('_internalModel');
72856
72857        (0, _emberDataPrivateDebug.runInDebug)(function () {
72858          internalModels.forEach(function (internalModel) {
72859            var relationshipMeta = _this.hasManyRelationship.relationshipMeta;
72860            (0, _emberDataPrivateDebug.assertPolymorphicType)(_this.internalModel, relationshipMeta, internalModel);
72861          });
72862        });
72863      }
72864
72865      _this.hasManyRelationship.computeChanges(internalModels);
72866
72867      return _this.hasManyRelationship.manyArray;
72868    });
72869  };
72870
72871  HasManyReference.prototype._isLoaded = function () {
72872    var hasData = get(this.hasManyRelationship, 'hasData');
72873    if (!hasData) {
72874      return false;
72875    }
72876
72877    var members = this.hasManyRelationship.members.toArray();
72878    var isEveryLoaded = members.every(function (internalModel) {
72879      return internalModel.isLoaded() === true;
72880    });
72881
72882    return isEveryLoaded;
72883  };
72884
72885  HasManyReference.prototype.value = function () {
72886    if (this._isLoaded()) {
72887      return this.hasManyRelationship.manyArray;
72888    }
72889
72890    return null;
72891  };
72892
72893  HasManyReference.prototype.load = function () {
72894    if (!this._isLoaded()) {
72895      return this.hasManyRelationship.getRecords();
72896    }
72897
72898    var manyArray = this.hasManyRelationship.manyArray;
72899    return _ember['default'].RSVP.resolve(manyArray);
72900  };
72901
72902  HasManyReference.prototype.reload = function () {
72903    return this.hasManyRelationship.reload();
72904  };
72905
72906  exports['default'] = HasManyReference;
72907});
72908define('ember-data/-private/system/references/record', ['exports', 'ember', 'ember-data/-private/system/references/reference'], function (exports, _ember, _emberDataPrivateSystemReferencesReference) {
72909  'use strict';
72910
72911  var RecordReference = function RecordReference(store, internalModel) {
72912    this._super$constructor(store, internalModel);
72913    this.type = internalModel.modelName;
72914    this._id = internalModel.id;
72915  };
72916
72917  RecordReference.prototype = Object.create(_emberDataPrivateSystemReferencesReference['default'].prototype);
72918  RecordReference.prototype.constructor = RecordReference;
72919  RecordReference.prototype._super$constructor = _emberDataPrivateSystemReferencesReference['default'];
72920
72921  RecordReference.prototype.id = function () {
72922    return this._id;
72923  };
72924
72925  RecordReference.prototype.remoteType = function () {
72926    return 'identity';
72927  };
72928
72929  RecordReference.prototype.push = function (objectOrPromise) {
72930    var _this = this;
72931
72932    return _ember['default'].RSVP.resolve(objectOrPromise).then(function (data) {
72933      var record = _this.store.push(data);
72934      return record;
72935    });
72936  };
72937
72938  RecordReference.prototype.value = function () {
72939    return this.internalModel.record;
72940  };
72941
72942  RecordReference.prototype.load = function () {
72943    return this.store.findRecord(this.type, this._id);
72944  };
72945
72946  RecordReference.prototype.reload = function () {
72947    var record = this.value();
72948    if (record) {
72949      return record.reload();
72950    }
72951
72952    return this.load();
72953  };
72954
72955  exports['default'] = RecordReference;
72956});
72957define("ember-data/-private/system/references/reference", ["exports"], function (exports) {
72958  "use strict";
72959
72960  var Reference = function Reference(store, internalModel) {
72961    this.store = store;
72962    this.internalModel = internalModel;
72963  };
72964
72965  Reference.prototype = {
72966    constructor: Reference
72967  };
72968
72969  exports["default"] = Reference;
72970});
72971define('ember-data/-private/system/relationship-meta', ['exports', 'ember-inflector', 'ember-data/-private/system/normalize-model-name'], function (exports, _emberInflector, _emberDataPrivateSystemNormalizeModelName) {
72972  'use strict';
72973
72974  exports.typeForRelationshipMeta = typeForRelationshipMeta;
72975  exports.relationshipFromMeta = relationshipFromMeta;
72976
72977  function typeForRelationshipMeta(meta) {
72978    var modelName;
72979
72980    modelName = meta.type || meta.key;
72981    if (meta.kind === 'hasMany') {
72982      modelName = (0, _emberInflector.singularize)((0, _emberDataPrivateSystemNormalizeModelName['default'])(modelName));
72983    }
72984    return modelName;
72985  }
72986
72987  function relationshipFromMeta(meta) {
72988    return {
72989      key: meta.key,
72990      kind: meta.kind,
72991      type: typeForRelationshipMeta(meta),
72992      options: meta.options,
72993      parentType: meta.parentType,
72994      isRelationship: true
72995    };
72996  }
72997});
72998define("ember-data/-private/system/relationships/belongs-to", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/normalize-model-name"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemNormalizeModelName) {
72999  "use strict";
73000
73001  exports["default"] = belongsTo;
73002
73003  /**
73004    `DS.belongsTo` is used to define One-To-One and One-To-Many
73005    relationships on a [DS.Model](/api/data/classes/DS.Model.html).
73006  
73007  
73008    `DS.belongsTo` takes an optional hash as a second parameter, currently
73009    supported options are:
73010  
73011    - `async`: A boolean value used to explicitly declare this to be an async relationship.
73012    - `inverse`: A string used to identify the inverse property on a
73013      related model in a One-To-Many relationship. See [Explicit Inverses](#toc_explicit-inverses)
73014  
73015    #### One-To-One
73016    To declare a one-to-one relationship between two models, use
73017    `DS.belongsTo`:
73018  
73019    ```app/models/user.js
73020    import DS from 'ember-data';
73021  
73022    export default DS.Model.extend({
73023      profile: DS.belongsTo('profile')
73024    });
73025    ```
73026  
73027    ```app/models/profile.js
73028    import DS from 'ember-data';
73029  
73030    export default DS.Model.extend({
73031      user: DS.belongsTo('user')
73032    });
73033    ```
73034  
73035    #### One-To-Many
73036    To declare a one-to-many relationship between two models, use
73037    `DS.belongsTo` in combination with `DS.hasMany`, like this:
73038  
73039    ```app/models/post.js
73040    import DS from 'ember-data';
73041  
73042    export default DS.Model.extend({
73043      comments: DS.hasMany('comment')
73044    });
73045    ```
73046  
73047    ```app/models/comment.js
73048    import DS from 'ember-data';
73049  
73050    export default DS.Model.extend({
73051      post: DS.belongsTo('post')
73052    });
73053    ```
73054  
73055    You can avoid passing a string as the first parameter. In that case Ember Data
73056    will infer the type from the key name.
73057  
73058    ```app/models/comment.js
73059    import DS from 'ember-data';
73060  
73061    export default DS.Model.extend({
73062      post: DS.belongsTo()
73063    });
73064    ```
73065  
73066    will lookup for a Post type.
73067  
73068    @namespace
73069    @method belongsTo
73070    @for DS
73071    @param {String} modelName (optional) type of the relationship
73072    @param {Object} options (optional) a hash of options
73073    @return {Ember.computed} relationship
73074  */
73075  function belongsTo(modelName, options) {
73076    var opts, userEnteredModelName;
73077    if (typeof modelName === 'object') {
73078      opts = modelName;
73079      userEnteredModelName = undefined;
73080    } else {
73081      opts = options;
73082      userEnteredModelName = modelName;
73083    }
73084
73085    if (typeof userEnteredModelName === 'string') {
73086      userEnteredModelName = (0, _emberDataPrivateSystemNormalizeModelName["default"])(userEnteredModelName);
73087    }
73088
73089    (0, _emberDataPrivateDebug.assert)("The first argument to DS.belongsTo must be a string representing a model type key, not an instance of " + _ember["default"].inspect(userEnteredModelName) + ". E.g., to define a relation to the Person model, use DS.belongsTo('person')", typeof userEnteredModelName === 'string' || typeof userEnteredModelName === 'undefined');
73090
73091    opts = opts || {};
73092
73093    var meta = {
73094      type: userEnteredModelName,
73095      isRelationship: true,
73096      options: opts,
73097      kind: 'belongsTo',
73098      key: null
73099    };
73100
73101    return _ember["default"].computed({
73102      get: function get(key) {
73103        if (opts.hasOwnProperty('serialize')) {
73104          (0, _emberDataPrivateDebug.warn)("You provided a serialize option on the \"" + key + "\" property in the \"" + this._internalModel.modelName + "\" class, this belongs in the serializer. See DS.Serializer and it's implementations http://emberjs.com/api/data/classes/DS.Serializer.html", false, {
73105            id: 'ds.model.serialize-option-in-belongs-to'
73106          });
73107        }
73108
73109        if (opts.hasOwnProperty('embedded')) {
73110          (0, _emberDataPrivateDebug.warn)("You provided an embedded option on the \"" + key + "\" property in the \"" + this._internalModel.modelName + "\" class, this belongs in the serializer. See DS.EmbeddedRecordsMixin http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html", false, {
73111            id: 'ds.model.embedded-option-in-belongs-to'
73112          });
73113        }
73114
73115        return this._internalModel._relationships.get(key).getRecord();
73116      },
73117      set: function set(key, value) {
73118        if (value === undefined) {
73119          value = null;
73120        }
73121        if (value && value.then) {
73122          this._internalModel._relationships.get(key).setRecordPromise(value);
73123        } else if (value) {
73124          this._internalModel._relationships.get(key).setRecord(value._internalModel);
73125        } else {
73126          this._internalModel._relationships.get(key).setRecord(value);
73127        }
73128
73129        return this._internalModel._relationships.get(key).getRecord();
73130      }
73131    }).meta(meta);
73132  }
73133
73134  /*
73135    These observers observe all `belongsTo` relationships on the record. See
73136    `relationships/ext` to see how these observers get their dependencies.
73137  */
73138  var BelongsToMixin = _ember["default"].Mixin.create({
73139    notifyBelongsToChanged: function notifyBelongsToChanged(key) {
73140      this.notifyPropertyChange(key);
73141    }
73142  });
73143  exports.BelongsToMixin = BelongsToMixin;
73144});
73145define("ember-data/-private/system/relationships/ext", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/relationship-meta", "ember-data/-private/system/empty-object"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemRelationshipMeta, _emberDataPrivateSystemEmptyObject) {
73146  "use strict";
73147
73148  var get = _ember["default"].get;
73149  var Map = _ember["default"].Map;
73150  var MapWithDefault = _ember["default"].MapWithDefault;
73151
73152  var relationshipsDescriptor = _ember["default"].computed(function () {
73153    if (_ember["default"].testing === true && relationshipsDescriptor._cacheable === true) {
73154      relationshipsDescriptor._cacheable = false;
73155    }
73156
73157    var map = new MapWithDefault({
73158      defaultValue: function defaultValue() {
73159        return [];
73160      }
73161    });
73162
73163    // Loop through each computed property on the class
73164    this.eachComputedProperty(function (name, meta) {
73165      // If the computed property is a relationship, add
73166      // it to the map.
73167      if (meta.isRelationship) {
73168        meta.key = name;
73169        var relationshipsForType = map.get((0, _emberDataPrivateSystemRelationshipMeta.typeForRelationshipMeta)(meta));
73170
73171        relationshipsForType.push({
73172          name: name,
73173          kind: meta.kind
73174        });
73175      }
73176    });
73177
73178    return map;
73179  }).readOnly();
73180
73181  var relatedTypesDescriptor = _ember["default"].computed(function () {
73182    var _this = this;
73183
73184    if (_ember["default"].testing === true && relatedTypesDescriptor._cacheable === true) {
73185      relatedTypesDescriptor._cacheable = false;
73186    }
73187
73188    var modelName;
73189    var types = _ember["default"].A();
73190
73191    // Loop through each computed property on the class,
73192    // and create an array of the unique types involved
73193    // in relationships
73194    this.eachComputedProperty(function (name, meta) {
73195      if (meta.isRelationship) {
73196        meta.key = name;
73197        modelName = (0, _emberDataPrivateSystemRelationshipMeta.typeForRelationshipMeta)(meta);
73198
73199        (0, _emberDataPrivateDebug.assert)("You specified a hasMany (" + meta.type + ") on " + meta.parentType + " but " + meta.type + " was not found.", modelName);
73200
73201        if (!types.contains(modelName)) {
73202          (0, _emberDataPrivateDebug.assert)("Trying to sideload " + name + " on " + _this.toString() + " but the type doesn't exist.", !!modelName);
73203          types.push(modelName);
73204        }
73205      }
73206    });
73207
73208    return types;
73209  }).readOnly();
73210
73211  var relationshipsByNameDescriptor = _ember["default"].computed(function () {
73212    if (_ember["default"].testing === true && relationshipsByNameDescriptor._cacheable === true) {
73213      relationshipsByNameDescriptor._cacheable = false;
73214    }
73215
73216    var map = Map.create();
73217
73218    this.eachComputedProperty(function (name, meta) {
73219      if (meta.isRelationship) {
73220        meta.key = name;
73221        var relationship = (0, _emberDataPrivateSystemRelationshipMeta.relationshipFromMeta)(meta);
73222        relationship.type = (0, _emberDataPrivateSystemRelationshipMeta.typeForRelationshipMeta)(meta);
73223        map.set(name, relationship);
73224      }
73225    });
73226
73227    return map;
73228  }).readOnly();
73229
73230  /**
73231    @module ember-data
73232  */
73233
73234  /*
73235    This file defines several extensions to the base `DS.Model` class that
73236    add support for one-to-many relationships.
73237  */
73238
73239  /**
73240    @class Model
73241    @namespace DS
73242  */
73243  var DidDefinePropertyMixin = _ember["default"].Mixin.create({
73244
73245    /**
73246      This Ember.js hook allows an object to be notified when a property
73247      is defined.
73248       In this case, we use it to be notified when an Ember Data user defines a
73249      belongs-to relationship. In that case, we need to set up observers for
73250      each one, allowing us to track relationship changes and automatically
73251      reflect changes in the inverse has-many array.
73252       This hook passes the class being set up, as well as the key and value
73253      being defined. So, for example, when the user does this:
73254       ```javascript
73255      DS.Model.extend({
73256        parent: DS.belongsTo('user')
73257      });
73258      ```
73259       This hook would be called with "parent" as the key and the computed
73260      property returned by `DS.belongsTo` as the value.
73261       @method didDefineProperty
73262      @param {Object} proto
73263      @param {String} key
73264      @param {Ember.ComputedProperty} value
73265    */
73266    didDefineProperty: function didDefineProperty(proto, key, value) {
73267      // Check if the value being set is a computed property.
73268      if (value instanceof _ember["default"].ComputedProperty) {
73269
73270        // If it is, get the metadata for the relationship. This is
73271        // populated by the `DS.belongsTo` helper when it is creating
73272        // the computed property.
73273        var meta = value.meta();
73274
73275        meta.parentType = proto.constructor;
73276      }
73277    }
73278  });
73279
73280  exports.DidDefinePropertyMixin = DidDefinePropertyMixin;
73281
73282  /*
73283    These DS.Model extensions add class methods that provide relationship
73284    introspection abilities about relationships.
73285  
73286    A note about the computed properties contained here:
73287  
73288    **These properties are effectively sealed once called for the first time.**
73289    To avoid repeatedly doing expensive iteration over a model's fields, these
73290    values are computed once and then cached for the remainder of the runtime of
73291    your application.
73292  
73293    If your application needs to modify a class after its initial definition
73294    (for example, using `reopen()` to add additional attributes), make sure you
73295    do it before using your model with the store, which uses these properties
73296    extensively.
73297  */
73298
73299  var RelationshipsClassMethodsMixin = _ember["default"].Mixin.create({
73300
73301    /**
73302      For a given relationship name, returns the model type of the relationship.
73303       For example, if you define a model like this:
73304       ```app/models/post.js
73305      import DS from 'ember-data';
73306       export default DS.Model.extend({
73307        comments: DS.hasMany('comment')
73308      });
73309     ```
73310       Calling `App.Post.typeForRelationship('comments')` will return `App.Comment`.
73311       @method typeForRelationship
73312      @static
73313      @param {String} name the name of the relationship
73314      @param {store} store an instance of DS.Store
73315      @return {DS.Model} the type of the relationship, or undefined
73316    */
73317    typeForRelationship: function typeForRelationship(name, store) {
73318      var relationship = get(this, 'relationshipsByName').get(name);
73319      return relationship && store.modelFor(relationship.type);
73320    },
73321
73322    inverseMap: _ember["default"].computed(function () {
73323      return new _emberDataPrivateSystemEmptyObject["default"]();
73324    }),
73325
73326    /**
73327      Find the relationship which is the inverse of the one asked for.
73328       For example, if you define models like this:
73329       ```app/models/post.js
73330      import DS from 'ember-data';
73331       export default DS.Model.extend({
73332        comments: DS.hasMany('message')
73333      });
73334      ```
73335       ```app/models/message.js
73336      import DS from 'ember-data';
73337       export default DS.Model.extend({
73338        owner: DS.belongsTo('post')
73339      });
73340      ```
73341       App.Post.inverseFor('comments') -> { type: App.Message, name: 'owner', kind: 'belongsTo' }
73342      App.Message.inverseFor('owner') -> { type: App.Post, name: 'comments', kind: 'hasMany' }
73343       @method inverseFor
73344      @static
73345      @param {String} name the name of the relationship
73346      @return {Object} the inverse relationship, or null
73347    */
73348    inverseFor: function inverseFor(name, store) {
73349      var inverseMap = get(this, 'inverseMap');
73350      if (inverseMap[name]) {
73351        return inverseMap[name];
73352      } else {
73353        var inverse = this._findInverseFor(name, store);
73354        inverseMap[name] = inverse;
73355        return inverse;
73356      }
73357    },
73358
73359    //Calculate the inverse, ignoring the cache
73360    _findInverseFor: function _findInverseFor(name, store) {
73361
73362      var inverseType = this.typeForRelationship(name, store);
73363      if (!inverseType) {
73364        return null;
73365      }
73366
73367      var propertyMeta = this.metaForProperty(name);
73368      //If inverse is manually specified to be null, like  `comments: DS.hasMany('message', { inverse: null })`
73369      var options = propertyMeta.options;
73370      if (options.inverse === null) {
73371        return null;
73372      }
73373
73374      var inverseName, inverseKind, inverse;
73375
73376      //If inverse is specified manually, return the inverse
73377      if (options.inverse) {
73378        inverseName = options.inverse;
73379        inverse = _ember["default"].get(inverseType, 'relationshipsByName').get(inverseName);
73380
73381        (0, _emberDataPrivateDebug.assert)("We found no inverse relationships by the name of '" + inverseName + "' on the '" + inverseType.modelName + "' model. This is most likely due to a missing attribute on your model definition.", !_ember["default"].isNone(inverse));
73382
73383        inverseKind = inverse.kind;
73384      } else {
73385        //No inverse was specified manually, we need to use a heuristic to guess one
73386        if (propertyMeta.type === propertyMeta.parentType.modelName) {
73387          (0, _emberDataPrivateDebug.warn)("Detected a reflexive relationship by the name of '" + n
73387ame + "' without an inverse option. Look at http://emberjs.com/guides/models/defining-models/#toc_reflexive-relation for how to explicitly specify inverses.", false, {
73388            id: 'ds.model.reflexive-relationship-without-inverse'
73389          });
73390        }
73391
73392        var possibleRelationships = findPossibleInverses(this, inverseType);
73393
73394        if (possibleRelationships.length === 0) {
73395          return null;
73396        }
73397
73398        var filteredRelationships = possibleRelationships.filter(function (possibleRelationship) {
73399          var optionsForRelationship = inverseType.metaForProperty(possibleRelationship.name).options;
73400          return name === optionsForRelationship.inverse;
73401        });
73402
73403        (0, _emberDataPrivateDebug.assert)("You defined the '" + name + "' relationship on " + this + ", but you defined the inverse relationships of type " + inverseType.toString() + " multiple times. Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses", filteredRelationships.length < 2);
73404
73405        if (filteredRelationships.length === 1) {
73406          possibleRelationships = filteredRelationships;
73407        }
73408
73409        (0, _emberDataPrivateDebug.assert)("You defined the '" + name + "' relationship on " + this + ", but multiple possible inverse relationships of type " + this + " were found on " + inverseType + ". Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses", possibleRelationships.length === 1);
73410
73411        inverseName = possibleRelationships[0].name;
73412        inverseKind = possibleRelationships[0].kind;
73413      }
73414
73415      function findPossibleInverses(type, inverseType, relationshipsSoFar) {
73416        var possibleRelationships = relationshipsSoFar || [];
73417
73418        var relationshipMap = get(inverseType, 'relationships');
73419        if (!relationshipMap) {
73420          return possibleRelationships;
73421        }
73422
73423        var relationships = relationshipMap.get(type.modelName);
73424
73425        relationships = relationships.filter(function (relationship) {
73426          var optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
73427
73428          if (!optionsForRelationship.inverse) {
73429            return true;
73430          }
73431
73432          return name === optionsForRelationship.inverse;
73433        });
73434
73435        if (relationships) {
73436          possibleRelationships.push.apply(possibleRelationships, relationships);
73437        }
73438
73439        //Recurse to support polymorphism
73440        if (type.superclass) {
73441          findPossibleInverses(type.superclass, inverseType, possibleRelationships);
73442        }
73443
73444        return possibleRelationships;
73445      }
73446
73447      return {
73448        type: inverseType,
73449        name: inverseName,
73450        kind: inverseKind
73451      };
73452    },
73453
73454    /**
73455      The model's relationships as a map, keyed on the type of the
73456      relationship. The value of each entry is an array containing a descriptor
73457      for each relationship with that type, describing the name of the relationship
73458      as well as the type.
73459       For example, given the following model definition:
73460       ```app/models/blog.js
73461      import DS from 'ember-data';
73462       export default DS.Model.extend({
73463        users: DS.hasMany('user'),
73464        owner: DS.belongsTo('user'),
73465        posts: DS.hasMany('post')
73466      });
73467      ```
73468       This computed property would return a map describing these
73469      relationships, like this:
73470       ```javascript
73471      import Ember from 'ember';
73472      import Blog from 'app/models/blog';
73473       var relationships = Ember.get(Blog, 'relationships');
73474      relationships.get(App.User);
73475      //=> [ { name: 'users', kind: 'hasMany' },
73476      //     { name: 'owner', kind: 'belongsTo' } ]
73477      relationships.get(App.Post);
73478      //=> [ { name: 'posts', kind: 'hasMany' } ]
73479      ```
73480       @property relationships
73481      @static
73482      @type Ember.Map
73483      @readOnly
73484    */
73485
73486    relationships: relationshipsDescriptor,
73487
73488    /**
73489      A hash containing lists of the model's relationships, grouped
73490      by the relationship kind. For example, given a model with this
73491      definition:
73492       ```app/models/blog.js
73493      import DS from 'ember-data';
73494       export default DS.Model.extend({
73495        users: DS.hasMany('user'),
73496        owner: DS.belongsTo('user'),
73497         posts: DS.hasMany('post')
73498      });
73499      ```
73500       This property would contain the following:
73501       ```javascript
73502      import Ember from 'ember';
73503      import Blog from 'app/models/blog';
73504       var relationshipNames = Ember.get(Blog, 'relationshipNames');
73505      relationshipNames.hasMany;
73506      //=> ['users', 'posts']
73507      relationshipNames.belongsTo;
73508      //=> ['owner']
73509      ```
73510       @property relationshipNames
73511      @static
73512      @type Object
73513      @readOnly
73514    */
73515    relationshipNames: _ember["default"].computed(function () {
73516      var names = {
73517        hasMany: [],
73518        belongsTo: []
73519      };
73520
73521      this.eachComputedProperty(function (name, meta) {
73522        if (meta.isRelationship) {
73523          names[meta.kind].push(name);
73524        }
73525      });
73526
73527      return names;
73528    }),
73529
73530    /**
73531      An array of types directly related to a model. Each type will be
73532      included once, regardless of the number of relationships it has with
73533      the model.
73534       For example, given a model with this definition:
73535       ```app/models/blog.js
73536      import DS from 'ember-data';
73537       export default DS.Model.extend({
73538        users: DS.hasMany('user'),
73539        owner: DS.belongsTo('user'),
73540         posts: DS.hasMany('post')
73541      });
73542      ```
73543       This property would contain the following:
73544       ```javascript
73545      import Ember from 'ember';
73546      import Blog from 'app/models/blog';
73547       var relatedTypes = Ember.get(Blog, 'relatedTypes');
73548      //=> [ App.User, App.Post ]
73549      ```
73550       @property relatedTypes
73551      @static
73552      @type Ember.Array
73553      @readOnly
73554    */
73555    relatedTypes: relatedTypesDescriptor,
73556
73557    /**
73558      A map whose keys are the relationships of a model and whose values are
73559      relationship descriptors.
73560       For example, given a model with this
73561      definition:
73562       ```app/models/blog.js
73563      import DS from 'ember-data';
73564       export default DS.Model.extend({
73565        users: DS.hasMany('user'),
73566        owner: DS.belongsTo('user'),
73567         posts: DS.hasMany('post')
73568      });
73569      ```
73570       This property would contain the following:
73571       ```javascript
73572      import Ember from 'ember';
73573      import Blog from 'app/models/blog';
73574       var relationshipsByName = Ember.get(Blog, 'relationshipsByName');
73575      relationshipsByName.get('users');
73576      //=> { key: 'users', kind: 'hasMany', type: 'user', options: Object, isRelationship: true }
73577      relationshipsByName.get('owner');
73578      //=> { key: 'owner', kind: 'belongsTo', type: 'user', options: Object, isRelationship: true }
73579      ```
73580       @property relationshipsByName
73581      @static
73582      @type Ember.Map
73583      @readOnly
73584    */
73585    relationshipsByName: relationshipsByNameDescriptor,
73586
73587    /**
73588      A map whose keys are the fields of the model and whose values are strings
73589      describing the kind of the field. A model's fields are the union of all of its
73590      attributes and relationships.
73591       For example:
73592       ```app/models/blog.js
73593      import DS from 'ember-data';
73594       export default DS.Model.extend({
73595        users: DS.hasMany('user'),
73596        owner: DS.belongsTo('user'),
73597         posts: DS.hasMany('post'),
73598         title: DS.attr('string')
73599      });
73600      ```
73601       ```js
73602      import Ember from 'ember';
73603      import Blog from 'app/models/blog';
73604       var fields = Ember.get(Blog, 'fields');
73605      fields.forEach(function(kind, field) {
73606        console.log(field, kind);
73607      });
73608       // prints:
73609      // users, hasMany
73610      // owner, belongsTo
73611      // posts, hasMany
73612      // title, attribute
73613      ```
73614       @property fields
73615      @static
73616      @type Ember.Map
73617      @readOnly
73618    */
73619    fields: _ember["default"].computed(function () {
73620      var map = Map.create();
73621
73622      this.eachComputedProperty(function (name, meta) {
73623        if (meta.isRelationship) {
73624          map.set(name, meta.kind);
73625        } else if (meta.isAttribute) {
73626          map.set(name, 'attribute');
73627        }
73628      });
73629
73630      return map;
73631    }).readOnly(),
73632
73633    /**
73634      Given a callback, iterates over each of the relationships in the model,
73635      invoking the callback with the name of each relationship and its relationship
73636      descriptor.
73637       @method eachRelationship
73638      @static
73639      @param {Function} callback the callback to invoke
73640      @param {any} binding the value to which the callback's `this` should be bound
73641    */
73642    eachRelationship: function eachRelationship(callback, binding) {
73643      get(this, 'relationshipsByName').forEach(function (relationship, name) {
73644        callback.call(binding, name, relationship);
73645      });
73646    },
73647
73648    /**
73649      Given a callback, iterates over each of the types related to a model,
73650      invoking the callback with the related type's class. Each type will be
73651      returned just once, regardless of how many different relationships it has
73652      with a model.
73653       @method eachRelatedType
73654      @static
73655      @param {Function} callback the callback to invoke
73656      @param {any} binding the value to which the callback's `this` should be bound
73657    */
73658    eachRelatedType: function eachRelatedType(callback, binding) {
73659      var relationshipTypes = get(this, 'relatedTypes');
73660
73661      for (var i = 0; i < relationshipTypes.length; i++) {
73662        var type = relationshipTypes[i];
73663        callback.call(binding, type);
73664      }
73665    },
73666
73667    determineRelationshipType: function determineRelationshipType(knownSide, store) {
73668      var knownKey = knownSide.key;
73669      var knownKind = knownSide.kind;
73670      var inverse = this.inverseFor(knownKey, store);
73671      // let key;
73672      var otherKind = undefined;
73673
73674      if (!inverse) {
73675        return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
73676      }
73677
73678      // key = inverse.name;
73679      otherKind = inverse.kind;
73680
73681      if (otherKind === 'belongsTo') {
73682        return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
73683      } else {
73684        return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
73685      }
73686    }
73687
73688  });
73689
73690  exports.RelationshipsClassMethodsMixin = RelationshipsClassMethodsMixin;
73691
73692  var RelationshipsInstanceMethodsMixin = _ember["default"].Mixin.create({
73693    /**
73694      Given a callback, iterates over each of the relationships in the model,
73695      invoking the callback with the name of each relationship and its relationship
73696      descriptor.
73697        The callback method you provide should have the following signature (all
73698      parameters are optional):
73699       ```javascript
73700      function(name, descriptor);
73701      ```
73702       - `name` the name of the current property in the iteration
73703      - `descriptor` the meta object that describes this relationship
73704       The relationship descriptor argument is an object with the following properties.
73705      - **key** <span class="type">String</span> the name of this relationship on the Model
73706     - **kind** <span class="type">String</span> "hasMany" or "belongsTo"
73707     - **options** <span class="type">Object</span> the original options hash passed when the relationship was declared
73708     - **parentType** <span class="type">DS.Model</span> the type of the Model that owns this relationship
73709     - **type** <span class="type">String</span> the type name of the related Model
73710       Note that in addition to a callback, you can also pass an optional target
73711      object that will be set as `this` on the context.
73712       Example
73713       ```app/serializers/application.js
73714      import DS from 'ember-data';
73715       export default DS.JSONSerializer.extend({
73716        serialize: function(record, options) {
73717          var json = {};
73718           record.eachRelationship(function(name, descriptor) {
73719            if (descriptor.kind === 'hasMany') {
73720              var serializedHasManyName = name.toUpperCase() + '_IDS';
73721              json[serializedHasManyName] = record.get(name).mapBy('id');
73722            }
73723          });
73724           return json;
73725        }
73726      });
73727      ```
73728       @method eachRelationship
73729      @param {Function} callback the callback to invoke
73730      @param {any} binding the value to which the callback's `this` should be bound
73731    */
73732    eachRelationship: function eachRelationship(callback, binding) {
73733      this.constructor.eachRelationship(callback, binding);
73734    },
73735
73736    relationshipFor: function relationshipFor(name) {
73737      return get(this.constructor, 'relationshipsByName').get(name);
73738    },
73739
73740    inverseFor: function inverseFor(key) {
73741      return this.constructor.inverseFor(key, this.store);
73742    }
73743
73744  });
73745  exports.RelationshipsInstanceMethodsMixin = RelationshipsInstanceMethodsMixin;
73746});
73747define("ember-data/-private/system/relationships/has-many", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/normalize-model-name", "ember-data/-private/system/is-array-like"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemNormalizeModelName, _emberDataPrivateSystemIsArrayLike) {
73748  "use strict";
73749
73750  exports["default"] = hasMany;
73751
73752  /**
73753    @module ember-data
73754  */
73755
73756  /**
73757    `DS.hasMany` is used to define One-To-Many and Many-To-Many
73758    relationships on a [DS.Model](/api/data/classes/DS.Model.html).
73759  
73760    `DS.hasMany` takes an optional hash as a second parameter, currently
73761    supported options are:
73762  
73763    - `async`: A boolean value used to explicitly declare this to be an async relationship.
73764    - `inverse`: A string used to identify the inverse property on a related model.
73765  
73766    #### One-To-Many
73767    To declare a one-to-many relationship between two models, use
73768    `DS.belongsTo` in combination with `DS.hasMany`, like this:
73769  
73770    ```app/models/post.js
73771    import DS from 'ember-data';
73772  
73773    export default DS.Model.extend({
73774      comments: DS.hasMany('comment')
73775    });
73776    ```
73777  
73778    ```app/models/comment.js
73779    import DS from 'ember-data';
73780  
73781    export default DS.Model.extend({
73782      post: DS.belongsTo('post')
73783    });
73784    ```
73785  
73786    #### Many-To-Many
73787    To declare a many-to-many relationship between two models, use
73788    `DS.hasMany`:
73789  
73790    ```app/models/post.js
73791    import DS from 'ember-data';
73792  
73793    export default DS.Model.extend({
73794      tags: DS.hasMany('tag')
73795    });
73796    ```
73797  
73798    ```app/models/tag.js
73799    import DS from 'ember-data';
73800  
73801    export default DS.Model.extend({
73802      posts: DS.hasMany('post')
73803    });
73804    ```
73805  
73806    You can avoid passing a string as the first parameter. In that case Ember Data
73807    will infer the type from the singularized key name.
73808  
73809    ```app/models/post.js
73810    import DS from 'ember-data';
73811  
73812    export default DS.Model.extend({
73813      tags: DS.hasMany()
73814    });
73815    ```
73816  
73817    will lookup for a Tag type.
73818  
73819    #### Explicit Inverses
73820  
73821    Ember Data will do its best to discover which relationships map to
73822    one another. In the one-to-many code above, for example, Ember Data
73823    can figure out that changing the `comments` relationship should update
73824    the `post` relationship on the inverse because post is the only
73825    relationship to that model.
73826  
73827    However, sometimes you may have multiple `belongsTo`/`hasManys` for the
73828    same type. You can specify which property on the related model is
73829    the inverse using `DS.hasMany`'s `inverse` option:
73830  
73831    ```app/models/comment.js
73832    import DS from 'ember-data';
73833  
73834    export default DS.Model.extend({
73835      onePost: DS.belongsTo('post'),
73836      twoPost: DS.belongsTo('post'),
73837      redPost: DS.belongsTo('post'),
73838      bluePost: DS.belongsTo('post')
73839    });
73840    ```
73841  
73842    ```app/models/post.js
73843    import DS from 'ember-data';
73844  
73845    export default DS.Model.extend({
73846      comments: DS.hasMany('comment', {
73847        inverse: 'redPost'
73848      })
73849    });
73850    ```
73851  
73852    You can also specify an inverse on a `belongsTo`, which works how
73853    you'd expect.
73854  
73855    @namespace
73856    @method hasMany
73857    @for DS
73858    @param {String} type (optional) type of the relationship
73859    @param {Object} options (optional) a hash of options
73860    @return {Ember.computed} relationship
73861  */
73862  function hasMany(type, options) {
73863    if (typeof type === 'object') {
73864      options = type;
73865      type = undefined;
73866    }
73867
73868    (0, _emberDataPrivateDebug.assert)("The first argument to DS.hasMany must be a string representing a model type key, not an instance of " + _ember["default"].inspect(type) + ". E.g., to define a relation to the Comment model, use DS.hasMany('comment')", typeof type === 'string' || typeof type === 'undefined');
73869
73870    options = options || {};
73871
73872    if (typeof type === 'string') {
73873      type = (0, _emberDataPrivateSystemNormalizeModelName["default"])(type);
73874    }
73875
73876    // Metadata about relationships is stored on the meta of
73877    // the relationship. This is used for introspection and
73878    // serialization. Note that `key` is populated lazily
73879    // the first time the CP is called.
73880    var meta = {
73881      type: type,
73882      isRelationship: true,
73883      options: options,
73884      kind: 'hasMany',
73885      key: null
73886    };
73887
73888    return _ember["default"].computed({
73889      get: function get(key) {
73890        var relationship = this._internalModel._relationships.get(key);
73891        return relationship.getRecords();
73892      },
73893      set: function set(key, records) {
73894        (0, _emberDataPrivateDebug.assert)("You must pass an array of records to set a hasMany relationship", (0, _emberDataPrivateSystemIsArrayLike["default"])(records));
73895        (0, _emberDataPrivateDebug.assert)("All elements of a hasMany relationship must be instances of DS.Model, you passed " + _ember["default"].inspect(records), (function () {
73896          return _ember["default"].A(records).every(function (record) {
73897            return record.hasOwnProperty('_internalModel') === true;
73898          });
73899        })());
73900
73901        var relationship = this._internalModel._relationships.get(key);
73902        relationship.clear();
73903        relationship.addRecords(_ember["default"].A(records).mapBy('_internalModel'));
73904        return relationship.getRecords();
73905      }
73906    }).meta(meta);
73907  }
73908
73909  var HasManyMixin = _ember["default"].Mixin.create({
73910    notifyHasManyAdded: function notifyHasManyAdded(key) {
73911      //We need to notifyPropertyChange in the adding case because we need to make sure
73912      //we fetch the newly added record in case it is unloaded
73913      //TODO(Igor): Consider whether we could do this only if the record state is unloaded
73914
73915      //Goes away once hasMany is double promisified
73916      this.notifyPropertyChange(key);
73917    }
73918  });
73919  exports.HasManyMixin = HasManyMixin;
73920});
73921define("ember-data/-private/system/relationships/state/belongs-to", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/relationships/state/relationship"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemRelationshipsStateRelationship) {
73922  "use strict";
73923
73924  exports["default"] = BelongsToRelationship;
73925
73926  function BelongsToRelationship(store, record, inverseKey, relationshipMeta) {
73927    this._super$constructor(store, record, inverseKey, relationshipMeta);
73928    this.record = record;
73929    this.key = relationshipMeta.key;
73930    this.inverseRecord = null;
73931    this.canonicalState = null;
73932  }
73933
73934  BelongsToRelationship.prototype = Object.create(_emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype);
73935  BelongsToRelationship.prototype.constructor = BelongsToRelationship;
73936  BelongsToRelationship.prototype._super$constructor = _emberDataPrivateSystemRelationshipsStateRelationship["default"];
73937
73938  BelongsToRelationship.prototype.setRecord = function (newRecord) {
73939    if (newRecord) {
73940      this.addRecord(newRecord);
73941    } else if (this.inverseRecord) {
73942      this.removeRecord(this.inverseRecord);
73943    }
73944    this.setHasData(true);
73945    this.setHasLoaded(true);
73946  };
73947
73948  BelongsToRelationship.prototype.setCanonicalRecord = function (newRecord) {
73949    if (newRecord) {
73950      this.addCanonicalRecord(newRecord);
73951    } else if (this.canonicalState) {
73952      this.removeCanonicalRecord(this.canonicalState);
73953    }
73954    this.flushCanonicalLater();
73955    this.setHasData(true);
73956    this.setHasLoaded(true);
73957  };
73958
73959  BelongsToRelationship.prototype._super$addCanonicalRecord = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.addCanonicalRecord;
73960  BelongsToRelationship.prototype.addCanonicalRecord = function (newRecord) {
73961    if (this.canonicalMembers.has(newRecord)) {
73962      return;
73963    }
73964
73965    if (this.canonicalState) {
73966      this.removeCanonicalRecord(this.canonicalState);
73967    }
73968
73969    this.canonicalState = newRecord;
73970    this._super$addCanonicalRecord(newRecord);
73971  };
73972
73973  BelongsToRelationship.prototype._super$flushCanonical = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.flushCanonical;
73974  BelongsToRelationship.prototype.flushCanonical = function () {
73975    //temporary fix to not remove newly created records if server returned null.
73976    //TODO remove once we have proper diffing
73977    if (this.inverseRecord && this.inverseRecord.isNew() && !this.canonicalState) {
73978      return;
73979    }
73980    this.inverseRecord = this.canonicalState;
73981    this.record.notifyBelongsToChanged(this.key);
73982    this._super$flushCanonical();
73983  };
73984
73985  BelongsToRelationship.prototype._super$addRecord = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.addRecord;
73986  BelongsToRelationship.prototype.addRecord = function (newRecord) {
73987    if (this.members.has(newRecord)) {
73988      return;
73989    }
73990
73991    (0, _emberDataPrivateDebug.assertPolymorphicType)(this.record, this.relationshipMeta, newRecord);
73992
73993    if (this.inverseRecord) {
73994      this.removeRecord(this.inverseRecord);
73995    }
73996
73997    this.inverseRecord = newRecord;
73998    this._super$addRecord(newRecord);
73999    this.record.notifyBelongsToChanged(this.key);
74000  };
74001
74002  BelongsToRelationship.prototype.setRecordPromise = function (newPromise) {
74003    var content = newPromise.get && newPromise.get('content');
74004    (0, _emberDataPrivateDebug.assert)("You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.", content !== undefined);
74005    this.setRecord(content ? content._internalModel : content);
74006  };
74007
74008  BelongsToRelationship.prototype._super$removeRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.removeRecordFromOwn;
74009  BelongsToRelationship.prototype.removeRecordFromOwn = function (record) {
74010    if (!this.members.has(record)) {
74011      return;
74012    }
74013    this.inverseRecord = null;
74014    this._super$removeRecordFromOwn(record);
74015    this.record.notifyBelongsToChanged(this.key);
74016  };
74017
74018  BelongsToRelationship.prototype._super$removeCanonicalRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.removeCanonicalRecordFromOwn;
74019  BelongsToRelationship.prototype.removeCanonicalRecordFromOwn = function (record) {
74020    if (!this.canonicalMembers.has(record)) {
74021      return;
74022    }
74023    this.canonicalState = null;
74024    this._super$removeCanonicalRecordFromOwn(record);
74025  };
74026
74027  BelongsToRelationship.prototype.findRecord = function () {
74028    if (this.inverseRecord) {
74029      return this.store._findByInternalModel(this.inverseRecord);
74030    } else {
74031      return _ember["default"].RSVP.Promise.resolve(null);
74032    }
74033  };
74034
74035  BelongsToRelationship.prototype.fetchLink = function () {
74036    var _this = this;
74037
74038    return this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function (record) {
74039      if (record) {
74040        _this.addRecord(record);
74041      }
74042      return record;
74043    });
74044  };
74045
74046  BelongsToRelationship.prototype.getRecord = function () {
74047    var _this2 = this;
74048
74049    //TODO(Igor) flushCanonical here once our syncing is not stupid
74050    if (this.isAsync) {
74051      var promise;
74052      if (this.link) {
74053        if (this.hasLoaded) {
74054          promise = this.findRecord();
74055        } else {
74056          promise = this.findLink().then(function () {
74057            return _this2.findRecord();
74058          });
74059        }
74060      } else {
74061        promise = this.findRecord();
74062      }
74063
74064      return _emberDataPrivateSystemPromiseProxies.PromiseObject.create({
74065        promise: promise,
74066        content: this.inverseRecord ? this.inverseRecord.getRecord() : null
74067      });
74068    } else {
74069      if (this.inverseRecord === null) {
74070        return null;
74071      }
74072      var toReturn = this.inverseRecord.getRecord();
74073      (0, _emberDataPrivateDebug.assert)("You looked up the '" + this.key + "' relationship on a '" + this.record.type.modelName + "' with i
74073d " + this.record.id + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.belongsTo({ async: true })`)", toReturn === null || !toReturn.get('isEmpty'));
74074      return toReturn;
74075    }
74076  };
74077
74078  BelongsToRelationship.prototype.reload = function () {
74079    // TODO handle case when reload() is triggered multiple times
74080
74081    if (this.link) {
74082      return this.fetchLink();
74083    }
74084
74085    // reload record, if it is already loaded
74086    if (this.inverseRecord && this.inverseRecord.record) {
74087      return this.inverseRecord.record.reload();
74088    }
74089
74090    return this.findRecord();
74091  };
74092});
74093define("ember-data/-private/system/relationships/state/create", ["exports", "ember", "ember-data/-private/system/relationships/state/has-many", "ember-data/-private/system/relationships/state/belongs-to", "ember-data/-private/system/empty-object"], function (exports, _ember, _emberDataPrivateSystemRelationshipsStateHasMany, _emberDataPrivateSystemRelationshipsStateBelongsTo, _emberDataPrivateSystemEmptyObject) {
74094  "use strict";
74095
74096  exports["default"] = Relationships;
74097
74098  var get = _ember["default"].get;
74099
74100  function shouldFindInverse(relationshipMeta) {
74101    var options = relationshipMeta.options;
74102    return !(options && options.inverse === null);
74103  }
74104
74105  function createRelationshipFor(record, relationshipMeta, store) {
74106    var inverseKey = undefined;
74107    var inverse = null;
74108    if (shouldFindInverse(relationshipMeta)) {
74109      inverse = record.type.inverseFor(relationshipMeta.key, store);
74110    }
74111
74112    if (inverse) {
74113      inverseKey = inverse.name;
74114    }
74115
74116    if (relationshipMeta.kind === 'hasMany') {
74117      return new _emberDataPrivateSystemRelationshipsStateHasMany["default"](store, record, inverseKey, relationshipMeta);
74118    } else {
74119      return new _emberDataPrivateSystemRelationshipsStateBelongsTo["default"](store, record, inverseKey, relationshipMeta);
74120    }
74121  }
74122  function Relationships(record) {
74123    this.record = record;
74124    this.initializedRelationships = new _emberDataPrivateSystemEmptyObject["default"]();
74125  }
74126
74127  Relationships.prototype.has = function (key) {
74128    return !!this.initializedRelationships[key];
74129  };
74130
74131  Relationships.prototype.get = function (key) {
74132    var relationships = this.initializedRelationships;
74133    var relationshipsByName = get(this.record.type, 'relationshipsByName');
74134    if (!relationships[key] && relationshipsByName.get(key)) {
74135      relationships[key] = createRelationshipFor(this.record, relationshipsByName.get(key), this.record.store);
74136    }
74137    return relationships[key];
74138  };
74139});
74140define("ember-data/-private/system/relationships/state/has-many", ["exports", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/relationships/state/relationship", "ember-data/-private/system/ordered-set", "ember-data/-private/system/many-array"], function (exports, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemRelationshipsStateRelationship, _emberDataPrivateSystemOrderedSet, _emberDataPrivateSystemManyArray) {
74141  "use strict";
74142
74143  exports["default"] = ManyRelationship;
74144
74145  function ManyRelationship(store, record, inverseKey, relationshipMeta) {
74146    this._super$constructor(store, record, inverseKey, relationshipMeta);
74147    this.belongsToType = relationshipMeta.type;
74148    this.canonicalState = [];
74149    this.manyArray = _emberDataPrivateSystemManyArray["default"].create({
74150      canonicalState: this.canonicalState,
74151      store: this.store,
74152      relationship: this,
74153      type: this.store.modelFor(this.belongsToType),
74154      record: record
74155    });
74156    this.isPolymorphic = relationshipMeta.options.polymorphic;
74157    this.manyArray.isPolymorphic = this.isPolymorphic;
74158  }
74159
74160  ManyRelationship.prototype = Object.create(_emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype);
74161  ManyRelationship.prototype.constructor = ManyRelationship;
74162  ManyRelationship.prototype._super$constructor = _emberDataPrivateSystemRelationshipsStateRelationship["default"];
74163
74164  ManyRelationship.prototype.destroy = function () {
74165    this.manyArray.destroy();
74166  };
74167
74168  ManyRelationship.prototype._super$updateMeta = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.updateMeta;
74169  ManyRelationship.prototype.updateMeta = function (meta) {
74170    this._super$updateMeta(meta);
74171    this.manyArray.set('meta', meta);
74172  };
74173
74174  ManyRelationship.prototype._super$addCanonicalRecord = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.addCanonicalRecord;
74175  ManyRelationship.prototype.addCanonicalRecord = function (record, idx) {
74176    if (this.canonicalMembers.has(record)) {
74177      return;
74178    }
74179    if (idx !== undefined) {
74180      this.canonicalState.splice(idx, 0, record);
74181    } else {
74182      this.canonicalState.push(record);
74183    }
74184    this._super$addCanonicalRecord(record, idx);
74185  };
74186
74187  ManyRelationship.prototype._super$addRecord = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.addRecord;
74188  ManyRelationship.prototype.addRecord = function (record, idx) {
74189    if (this.members.has(record)) {
74190      return;
74191    }
74192    this._super$addRecord(record, idx);
74193    this.manyArray.internalAddRecords([record], idx);
74194  };
74195
74196  ManyRelationship.prototype._super$removeCanonicalRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.removeCanonicalRecordFromOwn;
74197  ManyRelationship.prototype.removeCanonicalRecordFromOwn = function (record, idx) {
74198    var i = idx;
74199    if (!this.canonicalMembers.has(record)) {
74200      return;
74201    }
74202    if (i === undefined) {
74203      i = this.canonicalState.indexOf(record);
74204    }
74205    if (i > -1) {
74206      this.canonicalState.splice(i, 1);
74207    }
74208    this._super$removeCanonicalRecordFromOwn(record, idx);
74209  };
74210
74211  ManyRelationship.prototype._super$flushCanonical = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.flushCanonical;
74212  ManyRelationship.prototype.flushCanonical = function () {
74213    this.manyArray.flushCanonical();
74214    this._super$flushCanonical();
74215  };
74216
74217  ManyRelationship.prototype._super$removeRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship["default"].prototype.removeRecordFromOwn;
74218  ManyRelationship.prototype.removeRecordFromOwn = function (record, idx) {
74219    if (!this.members.has(record)) {
74220      return;
74221    }
74222    this._super$removeRecordFromOwn(record, idx);
74223    if (idx !== undefined) {
74224      //TODO(Igor) not used currently, fix
74225      this.manyArray.currentState.removeAt(idx);
74226    } else {
74227      this.manyArray.internalRemoveRecords([record]);
74228    }
74229  };
74230
74231  ManyRelationship.prototype.notifyRecordRelationshipAdded = function (record, idx) {
74232    (0, _emberDataPrivateDebug.assertPolymorphicType)(this.record, this.relationshipMeta, record);
74233
74234    this.record.notifyHasManyAdded(this.key, record, idx);
74235  };
74236
74237  ManyRelationship.prototype.reload = function () {
74238    var _this = this;
74239
74240    var manyArrayLoadedState = this.manyArray.get('isLoaded');
74241
74242    if (this._loadingPromise) {
74243      if (this._loadingPromise.get('isPending')) {
74244        return this._loadingPromise;
74245      }
74246      if (this._loadingPromise.get('isRejected')) {
74247        this.manyArray.set('isLoaded', manyArrayLoadedState);
74248      }
74249    }
74250
74251    if (this.link) {
74252      this._loadingPromise = (0, _emberDataPrivateSystemPromiseProxies.promiseManyArray)(this.fetchLink(), 'Reload with link');
74253      return this._loadingPromise;
74254    } else {
74255      this._loadingPromise = (0, _emberDataPrivateSystemPromiseProxies.promiseManyArray)(this.store.scheduleFetchMany(this.manyArray.toArray()).then(function () {
74256        return _this.manyArray;
74257      }), 'Reload with ids');
74258      return this._loadingPromise;
74259    }
74260  };
74261
74262  ManyRelationship.prototype.computeChanges = function (records) {
74263    var members = this.canonicalMembers;
74264    var recordsToRemove = [];
74265    var length;
74266    var record;
74267    var i;
74268
74269    records = setForArray(records);
74270
74271    members.forEach(function (member) {
74272      if (records.has(member)) {
74273        return;
74274      }
74275
74276      recordsToRemove.push(member);
74277    });
74278
74279    this.removeCanonicalRecords(recordsToRemove);
74280
74281    // Using records.toArray() since currently using
74282    // removeRecord can modify length, messing stuff up
74283    // forEach since it directly looks at "length" each
74284    // iteration
74285    records = records.toArray();
74286    length = records.length;
74287    for (i = 0; i < length; i++) {
74288      record = records[i];
74289      this.removeCanonicalRecord(record);
74290      this.addCanonicalRecord(record, i);
74291    }
74292  };
74293
74294  ManyRelationship.prototype.fetchLink = function () {
74295    var _this2 = this;
74296
74297    return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function (records) {
74298      if (records.hasOwnProperty('meta')) {
74299        _this2.updateMeta(records.meta);
74300      }
74301      _this2.store._backburner.join(function () {
74302        _this2.updateRecordsFromAdapter(records);
74303        _this2.manyArray.set('isLoaded', true);
74304      });
74305      return _this2.manyArray;
74306    });
74307  };
74308
74309  ManyRelationship.prototype.findRecords = function () {
74310    var _this3 = this;
74311
74312    var manyArray = this.manyArray.toArray();
74313    var internalModels = new Array(manyArray.length);
74314
74315    for (var i = 0; i < manyArray.length; i++) {
74316      internalModels[i] = manyArray[i]._internalModel;
74317    }
74318
74319    //TODO CLEANUP
74320    return this.store.findMany(internalModels).then(function () {
74321      if (!_this3.manyArray.get('isDestroyed')) {
74322        //Goes away after the manyArray refactor
74323        _this3.manyArray.set('isLoaded', true);
74324      }
74325      return _this3.manyArray;
74326    });
74327  };
74328  ManyRelationship.prototype.notifyHasManyChanged = function () {
74329    this.record.notifyHasManyAdded(this.key);
74330  };
74331
74332  ManyRelationship.prototype.getRecords = function () {
74333    var _this4 = this;
74334
74335    //TODO(Igor) sync server here, once our syncing is not stupid
74336    if (this.isAsync) {
74337      var promise;
74338      if (this.link) {
74339        if (this.hasLoaded) {
74340          promise = this.findRecords();
74341        } else {
74342          promise = this.findLink().then(function () {
74343            return _this4.findRecords();
74344          });
74345        }
74346      } else {
74347        promise = this.findRecords();
74348      }
74349      this._loadingPromise = _emberDataPrivateSystemPromiseProxies.PromiseManyArray.create({
74350        content: this.manyArray,
74351        promise: promise
74352      });
74353      return this._loadingPromise;
74354    } else {
74355      (0, _emberDataPrivateDebug.assert)("You looked up the '" + this.key + "' relationship on a '" + this.record.type.modelName + "' with id " + this.record.id + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)", this.manyArray.isEvery('isEmpty', false));
74356
74357      //TODO(Igor) WTF DO I DO HERE?
74358      if (!this.manyArray.get('isDestroyed')) {
74359        this.manyArray.set('isLoaded', true);
74360      }
74361      return this.manyArray;
74362    }
74363  };
74364
74365  function setForArray(array) {
74366    var set = new _emberDataPrivateSystemOrderedSet["default"]();
74367
74368    if (array) {
74369      for (var i = 0, l = array.length; i < l; i++) {
74370        set.add(array[i]);
74371      }
74372    }
74373
74374    return set;
74375  }
74376});
74377define("ember-data/-private/system/relationships/state/relationship", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/ordered-set"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemOrderedSet) {
74378  "use strict";
74379
74380  exports["default"] = Relationship;
74381
74382  function Relationship(store, record, inverseKey, relationshipMeta) {
74383    var async = relationshipMeta.options.async;
74384    this.members = new _emberDataPrivateSystemOrderedSet["default"]();
74385    this.canonicalMembers = new _emberDataPrivateSystemOrderedSet["default"]();
74386    this.store = store;
74387    this.key = relationshipMeta.key;
74388    this.inverseKey = inverseKey;
74389    this.record = record;
74390    this.isAsync = typeof async === 'undefined' ? true : async;
74391    this.relationshipMeta = relationshipMeta;
74392    //This probably breaks for polymorphic relationship in complex scenarios, due to
74393    //multiple possible modelNames
74394    this.inverseKeyForImplicit = this.record.constructor.modelName + this.key;
74395    this.linkPromise = null;
74396    this.meta = null;
74397    this.hasData = false;
74398    this.hasLoaded = false;
74399  }
74400
74401  Relationship.prototype = {
74402    constructor: Relationship,
74403
74404    destroy: _ember["default"].K,
74405
74406    updateMeta: function updateMeta(meta) {
74407      this.meta = meta;
74408    },
74409
74410    clear: function clear() {
74411      var members = this.members.list;
74412      var member;
74413
74414      while (members.length > 0) {
74415        member = members[0];
74416        this.removeRecord(member);
74417      }
74418    },
74419
74420    removeRecords: function removeRecords(records) {
74421      var _this = this;
74422
74423      records.forEach(function (record) {
74424        return _this.removeRecord(record);
74425      });
74426    },
74427
74428    addRecords: function addRecords(records, idx) {
74429      var _this2 = this;
74430
74431      records.forEach(function (record) {
74432        _this2.addRecord(record, idx);
74433        if (idx !== undefined) {
74434          idx++;
74435        }
74436      });
74437    },
74438
74439    addCanonicalRecords: function addCanonicalRecords(records, idx) {
74440      for (var i = 0; i < records.length; i++) {
74441        if (idx !== undefined) {
74442          this.addCanonicalRecord(records[i], i + idx);
74443        } else {
74444          this.addCanonicalRecord(records[i]);
74445        }
74446      }
74447    },
74448
74449    addCanonicalRecord: function addCanonicalRecord(record, idx) {
74450      if (!this.canonicalMembers.has(record)) {
74451        this.canonicalMembers.add(record);
74452        if (this.inverseKey) {
74453          record._relationships.get(this.inverseKey).addCanonicalRecord(this.record);
74454        } else {
74455          if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
74456            record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, { options: {} });
74457          }
74458          record._implicitRelationships[this.inverseKeyForImplicit].addCanonicalRecord(this.record);
74459        }
74460      }
74461      this.flushCanonicalLater();
74462      this.setHasData(true);
74463    },
74464
74465    removeCanonicalRecords: function removeCanonicalRecords(records, idx) {
74466      for (var i = 0; i < records.length; i++) {
74467        if (idx !== undefined) {
74468          this.removeCanonicalRecord(records[i], i + idx);
74469        } else {
74470          this.removeCanonicalRecord(records[i]);
74471        }
74472      }
74473    },
74474
74475    removeCanonicalRecord: function removeCanonicalRecord(record, idx) {
74476      if (this.canonicalMembers.has(record)) {
74477        this.removeCanonicalRecordFromOwn(record);
74478        if (this.inverseKey) {
74479          this.removeCanonicalRecordFromInverse(record);
74480        } else {
74481          if (record._implicitRelationships[this.inverseKeyForImplicit]) {
74482            record._implicitRelationships[this.inverseKeyForImplicit].removeCanonicalRecord(this.record);
74483          }
74484        }
74485      }
74486      this.flushCanonicalLater();
74487    },
74488
74489    addRecord: function addRecord(record, idx) {
74490      if (!this.members.has(record)) {
74491        this.members.addWithIndex(record, idx);
74492        this.notifyRecordRelationshipAdded(record, idx);
74493        if (this.inverseKey) {
74494          record._relationships.get(this.inverseKey).addRecord(this.record);
74495        } else {
74496          if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
74497            record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, { options: {} });
74498          }
74499          record._implicitRelationships[this.inverseKeyForImplicit].addRecord(this.record);
74500        }
74501        this.record.updateRecordArraysLater();
74502      }
74503      this.setHasData(true);
74504    },
74505
74506    removeRecord: function removeRecord(record) {
74507      if (this.members.has(record)) {
74508        this.removeRecordFromOwn(record);
74509        if (this.inverseKey) {
74510          this.removeRecordFromInverse(record);
74511        } else {
74512          if (record._implicitRelationships[this.inverseKeyForImplicit]) {
74513            record._implicitRelationships[this.inverseKeyForImplicit].removeRecord(this.record);
74514          }
74515        }
74516      }
74517    },
74518
74519    removeRecordFromInverse: function removeRecordFromInverse(record) {
74520      var inverseRelationship = record._relationships.get(this.inverseKey);
74521      //Need to check for existence, as the record might unloading at the moment
74522      if (inverseRelationship) {
74523        inverseRelationship.removeRecordFromOwn(this.record);
74524      }
74525    },
74526
74527    removeRecordFromOwn: function removeRecordFromOwn(record) {
74528      this.members["delete"](record);
74529      this.notifyRecordRelationshipRemoved(record);
74530      this.record.updateRecordArrays();
74531    },
74532
74533    removeCanonicalRecordFromInverse: function removeCanonicalRecordFromInverse(record) {
74534      var inverseRelationship = record._relationships.get(this.inverseKey);
74535      //Need to check for existence, as the record might unloading at the moment
74536      if (inverseRelationship) {
74537        inverseRelationship.removeCanonicalRecordFromOwn(this.record);
74538      }
74539    },
74540
74541    removeCanonicalRecordFromOwn: function removeCanonicalRecordFromOwn(record) {
74542      this.canonicalMembers["delete"](record);
74543      this.flushCanonicalLater();
74544    },
74545
74546    flushCanonical: function flushCanonical() {
74547      this.willSync = false;
74548      //a hack for not removing new records
74549      //TODO remove once we have proper diffing
74550      var newRecords = [];
74551      for (var i = 0; i < this.members.list.length; i++) {
74552        if (this.members.list[i].isNew()) {
74553          newRecords.push(this.members.list[i]);
74554        }
74555      }
74556      //TODO(Igor) make this less abysmally slow
74557      this.members = this.canonicalMembers.copy();
74558      for (i = 0; i < newRecords.length; i++) {
74559        this.members.add(newRecords[i]);
74560      }
74561    },
74562
74563    flushCanonicalLater: function flushCanonicalLater() {
74564      var _this3 = this;
74565
74566      if (this.willSync) {
74567        return;
74568      }
74569      this.willSync = true;
74570      this.store._backburner.join(function () {
74571        return _this3.store._backburner.schedule('syncRelationships', _this3, _this3.flushCanonical);
74572      });
74573    },
74574
74575    updateLink: function updateLink(link) {
74576      (0, _emberDataPrivateDebug.warn)("You have pushed a record of type '" + this.record.type.modelName + "' with '" + this.key + "' as a link, but the association is not an async relationship.", this.isAsync, {
74577        id: 'ds.store.push-link-for-sync-relationship'
74578      });
74579      (0, _emberDataPrivateDebug.assert)("You have pushed a record of type '" + this.record.type.modelName + "' with '" + this.key + "' as a link, but the value of that link is not a string.", typeof link === 'string' || link === null);
74580      if (link !== this.link) {
74581        this.link = link;
74582        this.linkPromise = null;
74583        this.setHasLoaded(false);
74584        this.record.notifyPropertyChange(this.key);
74585      }
74586    },
74587
74588    findLink: function findLink() {
74589      if (this.linkPromise) {
74590        return this.linkPromise;
74591      } else {
74592        var promise = this.fetchLink();
74593        this.linkPromise = promise;
74594        return promise.then(function (result) {
74595          return result;
74596        });
74597      }
74598    },
74599
74600    updateRecordsFromAdapter: function updateRecordsFromAdapter(records) {
74601      //TODO(Igor) move this to a proper place
74602      //TODO Once we have adapter support, we need to handle updated and canonical changes
74603      this.computeChanges(records);
74604      this.setHasData(true);
74605      this.setHasLoaded(true);
74606    },
74607
74608    notifyRecordRelationshipAdded: _ember["default"].K,
74609    notifyRecordRelationshipRemoved: _ember["default"].K,
74610
74611    /*
74612      `hasData` for a relationship is a flag to indicate if we consider the
74613      content of this relationship "known". Snapshots uses this to tell the
74614      difference between unknown (`undefined`) or empty (`null`). The reason for
74615      this is that we wouldn't want to serialize unknown relationships as `null`
74616      as that might overwrite remote state.
74617       All relationships for a newly created (`store.createRecord()`) are
74618      considered known (`hasData === true`).
74619     */
74620    setHasData: function setHasData(value) {
74621      this.hasData = value;
74622    },
74623
74624    /*
74625      `hasLoaded` is a flag to indicate if we have gotten data from the adapter or
74626      not when the relationship has a link.
74627       This is used to be able to tell when to fetch the link and when to return
74628      the local data in scenarios where the local state is considered known
74629      (`hasData === true`).
74630       Updating the link will automatically set `hasLoaded` to `false`.
74631     */
74632    setHasLoaded: function setHasLoaded(value) {
74633      this.hasLoaded = value;
74634    }
74635  };
74636});
74637define('ember-data/-private/system/snapshot-record-array', ['exports'], function (exports) {
74638  'use strict';
74639
74640  exports['default'] = SnapshotRecordArray;
74641
74642  /**
74643    @module ember-data
74644  */
74645
74646  /**
74647    @class SnapshotRecordArray
74648    @namespace DS
74649    @private
74650    @constructor
74651    @param {Array} snapshots An array of snapshots
74652    @param {Object} meta
74653  */
74654  function SnapshotRecordArray(recordArray, meta) {
74655    var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
74656
74657    /**
74658      An array of snapshots
74659      @private
74660      @property _snapshots
74661      @type {Array}
74662    */
74663    this._snapshots = null;
74664    /**
74665      An array of records
74666      @private
74667      @property _recordArray
74668      @type {Array}
74669    */
74670    this._recordArray = recordArray;
74671    /**
74672      Number of records in the array
74673      @property length
74674      @type {Number}
74675    */
74676    this.length = recordArray.get('length');
74677    /**
74678      The type of the underlying records for the snapshots in the array, as a DS.Model
74679      @property type
74680      @type {DS.Model}
74681    */
74682    this.type = recordArray.get('type');
74683    /**
74684      Meta object
74685      @property meta
74686      @type {Object}
74687    */
74688    this.meta = meta;
74689    /**
74690      A hash of adapter options
74691      @property adapterOptions
74692      @type {Object}
74693    */
74694    this.adapterOptions = options.adapterOptions;
74695
74696    this.include = options.include;
74697  }
74698
74699  /**
74700    Get snapshots of the underlying record array
74701    @method snapshots
74702    @return {Array} Array of snapshots
74703  */
74704  SnapshotRecordArray.prototype.snapshots = function () {
74705    if (this._snapshots) {
74706      return this._snapshots;
74707    }
74708    var recordArray = this._recordArray;
74709    this._snapshots = recordArray.invoke('createSnapshot');
74710
74711    return this._snapshots;
74712  };
74713});
74714define("ember-data/-private/system/snapshot", ["exports", "ember", "ember-data/-private/system/empty-object"], function (exports, _ember, _emberDataPrivateSystemEmptyObject) {
74715  "use strict";
74716
74717  exports["default"] = Snapshot;
74718
74719  /**
74720    @module ember-data
74721  */
74722
74723  var get = _ember["default"].get;
74724
74725  /**
74726    @class Snapshot
74727    @namespace DS
74728    @private
74729    @constructor
74730    @param {DS.Model} internalModel The model to create a snapshot from
74731  */
74732  function Snapshot(internalModel) {
74733    var _this = this;
74734
74735    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
74736
74737    this._attributes = new _emberDataPrivateSystemEmptyObject["default"]();
74738    this._belongsToRelationships = new _emberDataPrivateSystemEmptyObject["default"]();
74739    this._belongsToIds = new _emberDataPrivateSystemEmptyObject["default"]();
74740    this._hasManyRelationships = new _emberDataPrivateSystemEmptyObject["default"]();
74741    this._hasManyIds = new _emberDataPrivateSystemEmptyObject["default"]();
74742
74743    var record = internalModel.getRecord();
74744    this.record = record;
74745    record.eachAttribute(function (keyName) {
74746      return _this._attributes[keyName] = get(record, keyName);
74747    });
74748
74749    this.id = internalModel.id;
74750    this._internalModel = internalModel;
74751    this.type = internalModel.type;
74752    this.modelName = internalModel.type.modelName;
74753
74754    /**
74755      A hash of adapter options
74756      @property adapterOptions
74757      @type {Object}
74758    */
74759    this.adapterOptions = options.adapterOptions;
74760
74761    this.include = options.include;
74762
74763    this._changedAttributes = record.changedAttributes();
74764  }
74765
74766  Snapshot.prototype = {
74767    constructor: Snapshot,
74768
74769    /**
74770      The id of the snapshot's underlying record
74771       Example
74772       ```javascript
74773      // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
74774      postSnapshot.id; // => '1'
74775      ```
74776       @property id
74777      @type {String}
74778    */
74779    id: null,
74780
74781    /**
74782      The underlying record for this snapshot. Can be used to access methods and
74783      properties defined on the record.
74784       Example
74785       ```javascript
74786      var json = snapshot.record.toJSON();
74787      ```
74788       @property record
74789      @type {DS.Model}
74790    */
74791    record: null,
74792
74793    /**
74794      The type of the underlying record for this snapshot, as a DS.Model.
74795       @property type
74796      @type {DS.Model}
74797    */
74798    type: null,
74799
74800    /**
74801      The name of the type of the underlying record for this snapshot, as a string.
74802       @property modelName
74803      @type {String}
74804    */
74805    modelName: null,
74806
74807    /**
74808      Returns the value of an attribute.
74809       Example
74810       ```javascript
74811      // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
74812      postSnapshot.attr('author'); // => 'Tomster'
74813      postSnapshot.attr('title'); // => 'Ember.js rocks'
74814      ```
74815       Note: Values are loaded eagerly and cached when the snapshot is created.
74816       @method attr
74817      @param {String} keyName
74818      @return {Object} The attribute value or undefined
74819    */
74820    attr: function attr(keyName) {
74821      if (keyName in this._attributes) {
74822        return this._attributes[keyName];
74823      }
74824      throw new _ember["default"].Error("Model '" + _ember["default"].inspect(this.record) + "' has no attribute named '" + keyName + "' defined.");
74825    },
74826
74827    /**
74828      Returns all attributes and their corresponding values.
74829       Example
74830       ```javascript
74831      // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
74832      postSnapshot.attributes(); // => { author: 'Tomster', title: 'Ember.js rocks' }
74833      ```
74834       @method attributes
74835      @return {Object} All attributes of the current snapshot
74836    */
74837    attributes: function attributes() {
74838      return _ember["default"].copy(this._attributes);
74839    },
74840
74841    /**
74842      Returns all changed attributes and their old and new values.
74843       Example
74844       ```javascript
74845      // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
74846      postModel.set('title', 'Ember.js rocks!');
74847      postSnapshot.changedAttributes(); // => { title: ['Ember.js rocks', 'Ember.js rocks!'] }
74848      ```
74849       @method changedAttributes
74850      @return {Object} All changed attributes of the current snapshot
74851    */
74852    changedAttributes: function changedAttributes() {
74853      var changedAttributes = new _emberDataPrivateSystemEmptyObject["default"]();
74854      var changedAttributeKeys = Object.keys(this._changedAttributes);
74855
74856      for (var i = 0, _length = changedAttributeKeys.length; i < _length; i++) {
74857        var key = changedAttributeKeys[i];
74858        changedAttributes[key] = _ember["default"].copy(this._changedAttributes[key]);
74859      }
74860
74861      return changedAttributes;
74862    },
74863
74864    /**
74865      Returns the current value of a belongsTo relationship.
74866       `belongsTo` takes an optional hash of options as a second parameter,
74867      currently supported options are:
74868      - `id`: set to `true` if you only want the ID of the related record to be
74869        returned.
74870       Example
74871       ```javascript
74872      // store.push('post', { id: 1, title: 'Hello World' });
74873      // store.createRecord('comment', { body: 'Lorem ipsum', post: post });
74874      commentSnapshot.belongsTo('post'); // => DS.Snapshot
74875      commentSnapshot.belongsTo('post', { id: true }); // => '1'
74876       // store.push('comment', { id: 1, body: 'Lorem ipsum' });
74877      commentSnapshot.belongsTo('post'); // => undefined
74878      ```
74879       Calling `belongsTo` will return a new Snapshot as long as there's any known
74880      data for the relationship available, such as an ID. If the relationship is
74881      known but unset, `belongsTo` will return `null`. If the contents of the
74882      relationship is unknown `belongsTo` will return `undefined`.
74883       Note: Relationships are loaded lazily and cached upon first access.
74884       @method belongsTo
74885      @param {String} keyName
74886      @param {Object} [options]
74887      @return {(DS.Snapshot|String|null|undefined)} A snapshot or ID of a known
74888        relationship or null if the relationship is known but unset. undefined
74889        will be returned if the contents of the relationship is unknown.
74890    */
74891    belongsTo: function belongsTo(keyName, options) {
74892      var id = options && options.id;
74893      var relationship, inverseRecord, hasData;
74894      var result;
74895
74896      if (id && keyName in this._belongsToIds) {
74897        return this._belongsToIds[keyName];
74898      }
74899
74900      if (!id && keyName in this._belongsToRelationships) {
74901        return this._belongsToRelationships[keyName];
74902      }
74903
74904      relationship = this._internalModel._relationships.get(keyName);
74905      if (!(relationship && relationship.relationshipMeta.kind === 'belongsTo')) {
74906        throw new _ember["default"].Error("Model '" + _ember["default"].inspect(this.record) + "' has no belongsTo relationship named '" + keyName + "' defined.");
74907      }
74908
74909      hasData = get(relationship, 'hasData');
74910      inverseRecord = get(relationship, 'inverseRecord');
74911
74912      if (hasData) {
74913        if (inverseRecord && !inverseRecord.isDeleted()) {
74914          if (id) {
74915            result = get(inverseRecord, 'id');
74916          } else {
74917            result = inverseRecord.createSnapshot();
74918          }
74919        } else {
74920          result = null;
74921        }
74922      }
74923
74924      if (id) {
74925        this._belongsToIds[keyName] = result;
74926      } else {
74927        this._belongsToRelationships[keyName] = result;
74928      }
74929
74930      return result;
74931    },
74932
74933    /**
74934      Returns the current value of a hasMany relationship.
74935       `hasMany` takes an optional hash of options as a second parameter,
74936      currently supported options are:
74937      - `ids`: set to `true` if you only want the IDs of the related records to be
74938        returned.
74939       Example
74940       ```javascript
74941      // store.push('post', { id: 1, title: 'Hello World', comments: [2, 3] });
74942      postSnapshot.hasMany('comments'); // => [DS.Snapshot, DS.Snapshot]
74943      postSnapshot.hasMany('comments', { ids: true }); // => ['2', '3']
74944       // store.push('post', { id: 1, title: 'Hello World' });
74945      postSnapshot.hasMany('comments'); // => undefined
74946      ```
74947       Note: Relationships are loaded lazily and cached upon first access.
74948       @method hasMany
74949      @param {String} keyName
74950      @param {Object} [options]
74951      @return {(Array|undefined)} An array of snapshots or IDs of a known
74952        relationship or an empty array if the relationship is known but unset.
74953        undefined will be returned if the contents of the relationship is unknown.
74954    */
74955    hasMany: function hasMany(keyName, options) {
74956      var ids = options && options.ids;
74957      var relationship, members, hasData;
74958      var results;
74959
74960      if (ids && keyName in this._hasManyIds) {
74961        return this._hasManyIds[keyName];
74962      }
74963
74964      if (!ids && keyName in this._hasManyRelationships) {
74965        return this._hasManyRelationships[keyName];
74966      }
74967
74968      relationship = this._internalModel._relationships.get(keyName);
74969      if (!(relationship && relationship.relationshipMeta.kind === 'hasMany')) {
74970        throw new _ember["default"].Error("Model '" + _ember["default"].inspect(this.record) + "' has no hasMany relationship named '" + keyName + "' defined.");
74971      }
74972
74973      hasData = get(relationship, 'hasData');
74974      members = get(relationship, 'members');
74975
74976      if (hasData) {
74977        results = [];
74978        members.forEach(function (member) {
74979          if (!member.isDeleted()) {
74980            if (ids) {
74981              results.push(member.id);
74982            } else {
74983              results.push(member.createSnapshot());
74984            }
74985          }
74986        });
74987      }
74988
74989      if (ids) {
74990        this._hasManyIds[keyName] = results;
74991      } else {
74992        this._hasManyRelationships[keyName] = results;
74993      }
74994
74995      return results;
74996    },
74997
74998    /**
74999      Iterates through all the attributes of the model, calling the passed
75000      function on each attribute.
75001       Example
75002       ```javascript
75003      snapshot.eachAttribute(function(name, meta) {
75004        // ...
75005      });
75006      ```
75007       @method eachAttribute
75008      @param {Function} callback the callback to execute
75009      @param {Object} [binding] the value to which the callback's `this` should be bound
75010    */
75011    eachAttribute: function eachAttribute(callback, binding) {
75012      this.record.eachAttribute(callback, binding);
75013    },
75014
75015    /**
75016      Iterates through all the relationships of the model, calling the passed
75017      function on each relationship.
75018       Example
75019       ```javascript
75020      snapshot.eachRelationship(function(name, relationship) {
75021        // ...
75022      });
75023      ```
75024       @method eachRelationship
75025      @param {Function} callback the callback to execute
75026      @param {Object} [binding] the value to which the callback's `this` should be bound
75027    */
75028    eachRelationship: function eachRelationship(callback, binding) {
75029      this.record.eachRelationship(callback, binding);
75030    },
75031
75032    /**
75033      @method serialize
75034      @param {Object} options
75035      @return {Object} an object whose values are primitive JSON values only
75036     */
75037    serialize: function serialize(options) {
75038      return this.record.store.serializerFor(this.modelName).serialize(this, options);
75039    }
75040  };
75041});
75042define('ember-data/-private/system/store', ['exports', 'ember', 'ember-data/model', 'ember-data/-private/debug', 'ember-data/-private/system/normalize-link', 'ember-data/-private/system/normalize-model-name', 'ember-data/adapters/errors', 'ember-data/-private/system/promise-proxies', 'ember-data/-private/system/store/common', 'ember-data/-private/system/store/serializer-response', 'ember-data/-private/system/store/serializers', 'ember-data/-private/system/store/finders', 'ember-data/-private/utils', 'ember-data/-private/system/coerce-id', 'ember-data/-private/system/record-array-manager', 'ember-data/-private/system/store/container-instance-cache', 'ember-data/-private/system/model/internal-model', 'ember-data/-private/system/empty-object', 'ember-data/-private/features'], function (exports, _ember, _emberDataModel, _emberDataPrivateDebug, _emberDataPrivateSystemNormalizeLink, _emberDataPrivateSystemNormalizeModelName, _emberDataAdaptersErrors, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemStoreCommon, _emberDataPrivateSystemStoreSerializerResponse, _emberDataPrivateSystemStoreSerializers, _emberDataPrivateSystemStoreFinders, _emberDataPrivateUtils, _emberDataPrivateSystemCoerceId, _emberDataPrivateSystemRecordArrayManager, _emberDataPrivateSystemStoreContainerInstanceCache, _emberDataPrivateSystemModelInternalModel, _emberDataPrivateSystemEmptyObject, _emberDataPrivateFeatures) {
75043  /**
75044    @module ember-data
75045  */
75046
75047  'use strict';
75048
75049  var badIdFormatAssertion = '`id` passed to `findRecord()` has to be non-empty string or number';
75050
75051  exports.badIdFormatAssertion = badIdFormatAssertion;
75052
75053  var Backburner = _ember['default']._Backburner;
75054  var Map = _ember['default'].Map;
75055
75056  //Get the materialized model from the internalModel/promise that returns
75057  //an internal model and return it in a promiseObject. Useful for returning
75058  //from find methods
75059  function promiseRecord(internalModel, label) {
75060    var toReturn = internalModel.then(function (model) {
75061      return model.getRecord();
75062    });
75063    return (0, _emberDataPrivateSystemPromiseProxies.promiseObject)(toReturn, label);
75064  }
75065
75066  var get = _ember['default'].get;
75067  var set = _ember['default'].set;
75068  var once = _ember['default'].run.once;
75069  var isNone = _ember['default'].isNone;
75070  var isPresent = _ember['default'].isPresent;
75071  var Promise = _ember['default'].RSVP.Promise;
75072  var copy = _ember['default'].copy;
75073  var Store;
75074
75075  var Service = _ember['default'].Service;
75076
75077  // Implementors Note:
75078  //
75079  //   The variables in this file are consistently named according to the following
75080  //   scheme:
75081  //
75082  //   * +id+ means an identifier managed by an external source, provided inside
75083  //     the data provided by that source. These are always coerced to be strings
75084  //     before being used internally.
75085  //   * +clientId+ means a transient numerical identifier generated at runtime by
75086  //     the data store. It is important primarily because newly created objects may
75087  //     not yet have an externally generated id.
75088  //   * +internalModel+ means a record internalModel object, which holds metadata about a
75089  //     record, even if it has not yet been fully materialized.
75090  //   * +type+ means a DS.Model.
75091
75092  /**
75093    The store contains all of the data for records loaded from the server.
75094    It is also responsible for creating instances of `DS.Model` that wrap
75095    the individual data for a record, so that they can be bound to in your
75096    Handlebars templates.
75097  
75098    Define your application's store like this:
75099  
75100    ```app/services/store.js
75101    import DS from 'ember-data';
75102  
75103    export default DS.Store.extend({
75104    });
75105    ```
75106  
75107    Most Ember.js applications will only have a single `DS.Store` that is
75108    automatically created by their `Ember.Application`.
75109  
75110    You can retrieve models from the store in several ways. To retrieve a record
75111    for a specific id, use `DS.Store`'s `findRecord()` method:
75112  
75113    ```javascript
75114    store.findRecord('person', 123).then(function (person) {
75115    });
75116    ```
75117  
75118    By default, the store will talk to your backend using a standard
75119    REST mechanism. You can customize how the store talks to your
75120    backend by specifying a custom adapter:
75121  
75122    ```app/adapters/application.js
75123    import DS from 'ember-data';
75124  
75125    export default DS.Adapter.extend({
75126    });
75127    ```
75128  
75129    You can learn more about writing a custom adapter by reading the `DS.Adapter`
75130    documentation.
75131  
75132    ### Store createRecord() vs. push() vs. pushPayload()
75133  
75134    The store provides multiple ways to create new record objects. They have
75135    some subtle differences in their use which are detailed below:
75136  
75137    [createRecord](#method_createRecord) is used for creating new
75138    records on the client side. This will return a new record in the
75139    `created.uncommitted` state. In order to persist this record to the
75140    backend you will need to call `record.save()`.
75141  
75142    [push](#method_push) is used to notify Ember Data's store of new or
75143    updated records that exist in the backend. This will return a record
75144    in the `loaded.saved` state. The primary use-case for `store#push` is
75145    to notify Ember Data about record updates (full or partial) that happen
75146    outside of the normal adapter methods (for example
75147    [SSE](http://dev.w3.org/html5/eventsource/) or [Web
75148    Sockets](http://www.w3.org/TR/2009/WD-websockets-20091222/)).
75149  
75150    [pushPayload](#method_pushPayload) is a convenience wrapper for
75151    `store#push` that will deserialize payloads if the
75152    Serializer implements a `pushPayload` method.
75153  
75154    Note: When creating a new record using any of the above methods
75155    Ember Data will update `DS.RecordArray`s such as those returned by
75156    `store#peekAll()`, `store#findAll()` or `store#filter()`. This means any
75157    data bindings or computed properties that depend on the RecordArray
75158    will automatically be synced to include the new or updated record
75159    values.
75160  
75161    @class Store
75162    @namespace DS
75163    @extends Ember.Service
75164  */
75165  exports.Store = Store = Service.extend({
75166
75167    /**
75168      @method init
75169      @private
75170    */
75171    init: function init() {
75172      this._super.apply(this, arguments);
75173      this._backburner = new Backburner(['normalizeRelationships', 'syncRelationships', 'finished']);
75174      // internal bookkeeping; not observable
75175      this.typeMaps = {};
75176      this.recordArrayManager = _emberDataPrivateSystemRecordArrayManager['default'].create({
75177        store: this
75178      });
75179      this._pendingSave = [];
75180      this._instanceCache = new _emberDataPrivateSystemStoreContainerInstanceCache['default']((0, _emberDataPrivateUtils.getOwner)(this));
75181      //Used to keep track of all the find requests that need to be coalesced
75182      this._pendingFetch = Map.create();
75183    },
75184
75185    /**
75186      The adapter to use to communicate to a backend server or other persistence layer.
75187       This can be specified as an instance, class, or string.
75188       If you want to specify `app/adapters/custom.js` as a string, do:
75189       ```js
75190      adapter: 'custom'
75191      ```
75192       @property adapter
75193      @default DS.JSONAPIAdapter
75194      @type {(DS.Adapter|String)}
75195    */
75196    adapter: '-json-api',
75197
75198    /**
75199      Returns a JSON representation of the record using a custom
75200      type-specific serializer, if one exists.
75201       The available options are:
75202       * `includeId`: `true` if the record's ID should be included in
75203        the JSON representation
75204       @method serialize
75205      @private
75206      @param {DS.Model} record the record to serialize
75207      @param {Object} options an options hash
75208    */
75209    serialize: function serialize(record, options) {
75210      var snapshot = record._internalModel.createSnapshot();
75211      return snapshot.serialize(options);
75212    },
75213
75214    /**
75215      This property returns the adapter, after resolving a possible
75216      string key.
75217       If the supplied `adapter` was a class, or a String property
75218      path resolved to a class, this property will instantiate the
75219      class.
75220       This property is cacheable, so the same instance of a specified
75221      adapter class should be used for the lifetime of the store.
75222       @property defaultAdapter
75223      @private
75224      @return DS.Adapter
75225    */
75226    defaultAdapter: _ember['default'].computed('adapter', function () {
75227      var adapter = get(this, 'adapter');
75228
75229      (0, _emberDataPrivateDebug.assert)('You tried to set `adapter` property to an instance of `DS.Adapter`, where it should be a name', typeof adapter === 'string');
75230
75231      adapter = this.retrieveManagedInstance('adapter', adapter);
75232
75233      return adapter;
75234    }),
75235
75236    // .....................
75237    // . CREATE NEW RECORD .
75238    // .....................
75239
75240    /**
75241      Create a new record in the current store. The properties passed
75242      to this method are set on the newly created record.
75243       To create a new instance of a `Post`:
75244       ```js
75245      store.createRecord('post', {
75246        title: "Rails is omakase"
75247      });
75248      ```
75249       To create a new instance of a `Post` that has a relationship with a `User` record:
75250       ```js
75251      var user = this.store.peekRecord('user', 1);
75252      store.createRecord('post', {
75253        title: "Rails is omakase",
75254        user: user
75255      });
75256      ```
75257       @method createRecord
75258      @param {String} modelName
75259      @param {Object} inputProperties a hash of properties to set on the
75260        newly created record.
75261      @return {DS.Model} record
75262    */
75263    createRecord: function createRecord(modelName, inputProperties) {
75264      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's createRecord method", isPresent(modelName));
75265      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75266      var typeClass = this.modelFor(modelName);
75267      var properties = copy(inputProperties) || new _emberDataPrivateSystemEmptyObject['default']();
75268
75269      // If the passed properties do not include a primary key,
75270      // give the adapter an opportunity to generate one. Typically,
75271      // client-side ID generators will use something like uuid.js
75272      // to avoid conflicts.
75273
75274      if (isNone(properties.id)) {
75275        properties.id = this._generateId(modelName, properties);
75276      }
75277
75278      // Coerce ID to a string
75279      properties.id = (0, _emberDataPrivateSystemCoerceId['default'])(properties.id);
75280
75281      var internalModel = this.buildInternalModel(typeClass, properties.id);
75282      var record = internalModel.getRecord();
75283
75284      // Move the record out of its initial `empty` state into
75285      // the `loaded` state.
75286      internalModel.loadedData();
75287
75288      // Set the properties specified on the record.
75289      record.setProperties(properties);
75290
75291      internalModel.eachRelationship(function (key, descriptor) {
75292        internalModel._relationships.get(key).setHasData(true);
75293      });
75294
75295      return record;
75296    },
75297
75298    /**
75299      If possible, this method asks the adapter to generate an ID for
75300      a newly created record.
75301       @method _generateId
75302      @private
75303      @param {String} modelName
75304      @param {Object} properties from the new record
75305      @return {String} if the adapter can generate one, an ID
75306    */
75307    _generateId: function _generateId(modelName, properties) {
75308      var adapter = this.adapterFor(modelName);
75309
75310      if (adapter && adapter.generateIdForRecord) {
75311        return adapter.generateIdForRecord(this, modelName, properties);
75312      }
75313
75314      return null;
75315    },
75316
75317    // .................
75318    // . DELETE RECORD .
75319    // .................
75320
75321    /**
75322      For symmetry, a record can be deleted via the store.
75323       Example
75324       ```javascript
75325      var post = store.createRecord('post', {
75326        title: "Rails is omakase"
75327      });
75328       store.deleteRecord(post);
75329      ```
75330       @method deleteRecord
75331      @param {DS.Model} record
75332    */
75333    deleteRecord: function deleteRecord(record) {
75334      record.deleteRecord();
75335    },
75336
75337    /**
75338      For symmetry, a record can be unloaded via the store. Only
75339      non-dirty records can be unloaded.
75340       Example
75341       ```javascript
75342      store.findRecord('post', 1).then(function(post) {
75343        store.unloadRecord(post);
75344      });
75345      ```
75346       @method unloadRecord
75347      @param {DS.Model} record
75348    */
75349    unloadRecord: function unloadRecord(record) {
75350      record.unloadRecord();
75351    },
75352
75353    // ................
75354    // . FIND RECORDS .
75355    // ................
75356
75357    /**
75358      @method find
75359      @param {String} modelName
75360      @param {String|Integer} id
75361      @param {Object} options
75362      @return {Promise} promise
75363      @private
75364    */
75365    find: function find(modelName, id, options) {
75366      // The default `model` hook in Ember.Route calls `find(modelName, id)`,
75367      // that's why we have to keep this method around even though `findRecord` is
75368      // the public way to get a record by modelName and id.
75369
75370      if (arguments.length === 1) {
75371        (0, _emberDataPrivateDebug.assert)('Using store.find(type) has been removed. Use store.findAll(type) to retrieve all records for a given type.');
75372      }
75373
75374      if (_ember['default'].typeOf(id) === 'object') {
75375        (0, _emberDataPrivateDebug.assert)('Calling store.find() with a query object is no longer supported. Use store.query() instead.');
75376      }
75377
75378      if (options) {
75379        (0, _emberDataPrivateDebug.assert)('Calling store.find(type, id, { preload: preload }) is no longer supported. Use store.findRecord(type, id, { preload: preload }) instead.');
75380      }
75381
75382      (0, _emberDataPrivateDebug.assert)("You need to pass the model name and id to the store's find method", arguments.length === 2);
75383      (0, _emberDataPrivateDebug.assert)("You cannot pass `" + _ember['default'].inspect(id) + "` as id to the store's find method", _ember['default'].typeOf(id) === 'string' || _ember['default'].typeOf(id) === 'number');
75384      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75385
75386      return this.findRecord(modelName, id);
75387    },
75388
75389    /**
75390      This method returns a record for a given type and id combination.
75391       The `findRecord` method will always resolve its promise with the same
75392      object for a given type and `id`.
75393       The `findRecord` method will always return a **promise** that will be
75394      resolved with the record.
75395       Example
75396       ```app/routes/post.js
75397      import Ember from 'ember';
75398       export default Ember.Route.extend({
75399        model: function(params) {
75400          return this.store.findRecord('post', params.post_id);
75401        }
75402      });
75403      ```
75404       If the record is not yet available, the store will ask the adapter's `find`
75405      method to find the necessary data. If the record is already present in the
75406      store, it depends on the reload behavior _when_ the returned promise
75407      resolves.
75408       ### Reloading
75409       The reload behavior is configured either via the passed `options` hash or
75410      the result of the adapter's `shouldReloadRecord`.
75411       If `{ reload: true }` is passed or `adapter.shouldReloadRecord` evaluates
75412      to `true`, then the returned promise resolves once the adapter returns
75413      data, regardless if the requested record is already in the store:
75414       ```js
75415      store.push({
75416        data: {
75417          id: 1,
75418          type: 'post',
75419          revision: 1
75420        }
75421      });
75422       // adapter#findRecord resolves with
75423      // [
75424      //   {
75425      //     id: 1,
75426      //     type: 'post',
75427      //     revision: 2
75428      //   }
75429      // ]
75430      store.findRecord('post', 1, { reload: true }).then(function(post) {
75431        post.get("revision"); // 2
75432      });
75433      ```
75434       If no reload is indicated via the abovementioned ways, then the promise
75435      immediately resolves with the cached version in the store.
75436       ### Background Reloading
75437       Optionally, if `adapter.shouldBackgroundReloadRecord` evaluates to `true`,
75438      then a background reload is started, which updates the records' data, once
75439      it is available:
75440       ```js
75441      
75441// app/adapters/post.js
75442      import ApplicationAdapter from "./application";
75443       export default ApplicationAdapter.extend({
75444        shouldReloadRecord(store, snapshot) {
75445          return false;
75446        },
75447         shouldBackgroundReloadRecord(store, snapshot) {
75448          return true;
75449        }
75450      });
75451       // ...
75452       store.push({
75453        data: {
75454          id: 1,
75455          type: 'post',
75456          revision: 1
75457        }
75458      });
75459       var blogPost = store.findRecord('post', 1).then(function(post) {
75460        post.get('revision'); // 1
75461      });
75462       // later, once adapter#findRecord resolved with
75463      // [
75464      //   {
75465      //     id: 1,
75466      //     type: 'post',
75467      //     revision: 2
75468      //   }
75469      // ]
75470       blogPost.get('revision'); // 2
75471      ```
75472       If you would like to force or prevent background reloading, you can set a
75473      boolean value for `backgroundReload` in the options object for
75474      `findRecord`.
75475       ```app/routes/post/edit.js
75476      import Ember from 'ember';
75477       export default Ember.Route.extend({
75478        model: function(params) {
75479          return this.store.findRecord('post', params.post_id, { backgroundReload: false });
75480        }
75481      });
75482      ```
75483      If you pass an object on the `adapterOptions` property of the options
75484     argument it will be passed to you adapter via the snapshot
75485       ```app/routes/post/edit.js
75486      import Ember from 'ember';
75487       export default Ember.Route.extend({
75488        model: function(params) {
75489          return this.store.findRecord('post', params.post_id, {
75490            adapterOptions: { subscribe: false }
75491          });
75492        }
75493      });
75494      ```
75495       ```app/adapters/post.js
75496      import MyCustomAdapter from './custom-adapter';
75497       export default MyCustomAdapter.extend({
75498        findRecord: function(store, type, id, snapshot) {
75499          if (snapshot.adapterOptions.subscribe) {
75500            // ...
75501          }
75502          // ...
75503        }
75504      });
75505      ```
75506       See [peekRecord](#method_peekRecord) to get the cached version of a record.
75507       @since 1.13.0
75508      @method findRecord
75509      @param {String} modelName
75510      @param {(String|Integer)} id
75511      @param {Object} options
75512      @return {Promise} promise
75513    */
75514    findRecord: function findRecord(modelName, id, options) {
75515      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's findRecord method", isPresent(modelName));
75516      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75517      (0, _emberDataPrivateDebug.assert)(badIdFormatAssertion, typeof id === 'string' && id.length > 0 || typeof id === 'number' && !isNaN(id));
75518
75519      var internalModel = this._internalModelForId(modelName, id);
75520      options = options || {};
75521
75522      if (!this.hasRecordForId(modelName, id)) {
75523        return this._findByInternalModel(internalModel, options);
75524      }
75525
75526      var fetchedInternalModel = this._findRecord(internalModel, options);
75527
75528      return promiseRecord(fetchedInternalModel, "DS: Store#findRecord " + internalModel.typeKey + " with id: " + get(internalModel, 'id'));
75529    },
75530
75531    _findRecord: function _findRecord(internalModel, options) {
75532      // Refetch if the reload option is passed
75533      if (options.reload) {
75534        return this.scheduleFetch(internalModel, options);
75535      }
75536
75537      var snapshot = internalModel.createSnapshot(options);
75538      var typeClass = internalModel.type;
75539      var adapter = this.adapterFor(typeClass.modelName);
75540
75541      // Refetch the record if the adapter thinks the record is stale
75542      if (adapter.shouldReloadRecord(this, snapshot)) {
75543        return this.scheduleFetch(internalModel, options);
75544      }
75545
75546      if (options.backgroundReload === false) {
75547        return Promise.resolve(internalModel);
75548      }
75549
75550      // Trigger the background refetch if backgroundReload option is passed
75551      if (options.backgroundReload || adapter.shouldBackgroundReloadRecord(this, snapshot)) {
75552        this.scheduleFetch(internalModel, options);
75553      }
75554
75555      // Return the cached record
75556      return Promise.resolve(internalModel);
75557    },
75558
75559    _findByInternalModel: function _findByInternalModel(internalModel, options) {
75560      options = options || {};
75561
75562      if (options.preload) {
75563        internalModel._preloadData(options.preload);
75564      }
75565
75566      var fetchedInternalModel = this._findEmptyInternalModel(internalModel, options);
75567
75568      return promiseRecord(fetchedInternalModel, "DS: Store#findRecord " + internalModel.typeKey + " with i
75568d: " + get(internalModel, 'id'));
75569    },
75570
75571    _findEmptyInternalModel: function _findEmptyInternalModel(internalModel, options) {
75572      if (internalModel.isEmpty()) {
75573        return this.scheduleFetch(internalModel, options);
75574      }
75575
75576      //TODO double check about reloading
75577      if (internalModel.isLoading()) {
75578        return internalModel._loadingPromise;
75579      }
75580
75581      return Promise.resolve(internalModel);
75582    },
75583
75584    /**
75585      This method makes a series of requests to the adapter's `find` method
75586      and returns a promise that resolves once they are all loaded.
75587       @private
75588      @method findByIds
75589      @param {String} modelName
75590      @param {Array} ids
75591      @return {Promise} promise
75592    */
75593    findByIds: function findByIds(modelName, ids) {
75594      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's findByIds method", isPresent(modelName));
75595      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75596      var promises = new Array(ids.length);
75597
75598      for (var i = 0; i < ids.length; i++) {
75599        promises[i] = this.findRecord(modelName, ids[i]);
75600      }
75601
75602      return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(_ember['default'].RSVP.all(promises).then(_ember['default'].A, null, "DS: Store#findByIds of " + modelName + " complete"));
75603    },
75604
75605    /**
75606      This method is called by `findRecord` if it discovers that a particular
75607      type/id pair hasn't been loaded yet to kick off a request to the
75608      adapter.
75609       @method fetchRecord
75610      @private
75611      @param {InternalModel} internalModel model
75612      @return {Promise} promise
75613     */
75614    // TODO rename this to have an underscore
75615    fetchRecord: function fetchRecord(internalModel, options) {
75616      var typeClass = internalModel.type;
75617      var id = internalModel.id;
75618      var adapter = this.adapterFor(typeClass.modelName);
75619
75620      (0, _emberDataPrivateDebug.assert)("You tried to find a record but you have no adapter (for " + typeClass + ")", adapter);
75621      (0, _emberDataPrivateDebug.assert)("You tried to find a record but your adapter (for " + typeClass + ") does not implement 'findRecord'", typeof adapter.findRecord === 'function' || typeof adapter.find === 'function');
75622
75623      var promise = (0, _emberDataPrivateSystemStoreFinders._find)(adapter, this, typeClass, id, internalModel, options);
75624      return promise;
75625    },
75626
75627    scheduleFetchMany: function scheduleFetchMany(records) {
75628      var internalModels = new Array(records.length);
75629      var fetches = new Array(records.length);
75630      for (var i = 0; i < records.length; i++) {
75631        internalModels[i] = records[i]._internalModel;
75632      }
75633
75634      for (var i = 0; i < internalModels.length; i++) {
75635        fetches[i] = this.scheduleFetch(internalModels[i]);
75636      }
75637
75638      return _ember['default'].RSVP.Promise.all(fetches);
75639    },
75640
75641    scheduleFetch: function scheduleFetch(internalModel, options) {
75642      var typeClass = internalModel.type;
75643
75644      if (internalModel._loadingPromise) {
75645        return internalModel._loadingPromise;
75646      }
75647
75648      var resolver = _ember['default'].RSVP.defer('Fetching ' + typeClass + 'with id: ' + internalModel.id);
75649      var pendingFetchItem = {
75650        record: internalModel,
75651        resolver: resolver,
75652        options: options
75653      };
75654      var promise = resolver.promise;
75655
75656      internalModel.loadingData(promise);
75657
75658      if (!this._pendingFetch.get(typeClass)) {
75659        this._pendingFetch.set(typeClass, [pendingFetchItem]);
75660      } else {
75661        this._pendingFetch.get(typeClass).push(pendingFetchItem);
75662      }
75663      _ember['default'].run.scheduleOnce('afterRender', this, this.flushAllPendingFetches);
75664
75665      return promise;
75666    },
75667
75668    flushAllPendingFetches: function flushAllPendingFetches() {
75669      if (this.isDestroyed || this.isDestroying) {
75670        return;
75671      }
75672
75673      this._pendingFetch.forEach(this._flushPendingFetchForType, this);
75674      this._pendingFetch = Map.create();
75675    },
75676
75677    _flushPendingFetchForType: function _flushPendingFetchForType(pendingFetchItems, typeClass) {
75678      var store = this;
75679      var adapter = store.adapterFor(typeClass.modelName);
75680      var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
75681      var records = _ember['default'].A(pendingFetchItems).mapBy('record');
75682
75683      function _fetchRecord(recordResolverPair) {
75684        recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record, recordResolverPair.options)); // TODO adapter options
75685      }
75686
75687      function resolveFoundRecords(records) {
75688        records.forEach(function (record) {
75689          var pair = _ember['default'].A(pendingFetchItems).findBy('record', record);
75690          if (pair) {
75691            var resolver = pair.resolver;
75692            resolver.resolve(record);
75693          }
75694        });
75695        return records;
75696      }
75697
75698      function makeMissingRecordsRejector(requestedRecords) {
75699        return function rejectMissingRecords(resolvedRecords) {
75700          resolvedRecords = _ember['default'].A(resolvedRecords);
75701          var missingRecords = requestedRecords.reject(function (record) {
75702            return resolvedRecords.contains(record);
75703          });
75704          if (missingRecords.length) {
75705            (0, _emberDataPrivateDebug.warn)('Ember Data expected to find records with the following ids in the adapter response but they were missing: ' + _ember['default'].inspect(_ember['default'].A(missingRecords).mapBy('id')), false, {
75706              id: 'ds.store.missing-records-from-adapter'
75707            });
75708          }
75709          rejectRecords(missingRecords);
75710        };
75711      }
75712
75713      function makeRecordsRejector(records) {
75714        return function (error) {
75715          rejectRecords(records, error);
75716        };
75717      }
75718
75719      function rejectRecords(records, error) {
75720        records.forEach(function (record) {
75721          var pair = _ember['default'].A(pendingFetchItems).findBy('record', record);
75722          if (pair) {
75723            var resolver = pair.resolver;
75724            resolver.reject(error);
75725          }
75726        });
75727      }
75728
75729      if (pendingFetchItems.length === 1) {
75730        _fetchRecord(pendingFetchItems[0]);
75731      } else if (shouldCoalesce) {
75732
75733        // TODO: Improve records => snapshots => records => snapshots
75734        //
75735        // We want to provide records to all store methods and snapshots to all
75736        // adapter methods. To make sure we're doing that we're providing an array
75737        // of snapshots to adapter.groupRecordsForFindMany(), which in turn will
75738        // return grouped snapshots instead of grouped records.
75739        //
75740        // But since the _findMany() finder is a store method we need to get the
75741        // records from the grouped snapshots even though the _findMany() finder
75742        // will once again convert the records to snapshots for adapter.findMany()
75743
75744        var snapshots = _ember['default'].A(records).invoke('createSnapshot');
75745        var groups = adapter.groupRecordsForFindMany(this, snapshots);
75746        groups.forEach(function (groupOfSnapshots) {
75747          var groupOfRecords = _ember['default'].A(groupOfSnapshots).mapBy('_internalModel');
75748          var requestedRecords = _ember['default'].A(groupOfRecords);
75749          var ids = requestedRecords.mapBy('id');
75750          if (ids.length > 1) {
75751            (0, _emberDataPrivateSystemStoreFinders._findMany)(adapter, store, typeClass, ids, requestedRecords).then(resolveFoundRecords).then(makeMissingRecordsRejector(requestedRecords)).then(null, makeRecordsRejector(requestedRecords));
75752          } else if (ids.length === 1) {
75753            var pair = _ember['default'].A(pendingFetchItems).findBy('record', groupOfRecords[0]);
75754            _fetchRecord(pair);
75755          } else {
75756            (0, _emberDataPrivateDebug.assert)("You cannot return an empty array from adapter's method groupRecordsForFindMany", false);
75757          }
75758        });
75759      } else {
75760        pendingFetchItems.forEach(_fetchRecord);
75761      }
75762    },
75763
75764    /**
75765      Get the reference for the specified record.
75766       Example
75767       ```javascript
75768      var userRef = store.getReference('user', 1);
75769       // check if the user is loaded
75770      var isLoaded = userRef.value() !== null;
75771       // get the record of the reference (null if not yet available)
75772      var user = userRef.value();
75773       // get the identifier of the reference
75774      if (userRef.remoteType() === "id") {
75775      var id = userRef.id();
75776      }
75777       // load user (via store.find)
75778      userRef.load().then(...)
75779       // or trigger a reload
75780      userRef.reload().then(...)
75781       // provide data for reference
75782      userRef.push({ id: 1, username: "@user" }).then(function(user) {
75783      userRef.value() === user;
75784      });
75785      ```
75786       @method getReference
75787      @param {String} type
75788      @param {String|Integer} id
75789      @since 2.5.0
75790      @return {RecordReference}
75791    */
75792    getReference: function getReference(type, id) {
75793      return this._internalModelForId(type, id).recordReference;
75794    },
75795
75796    /**
75797      Get a record by a given type and ID without triggering a fetch.
75798       This method will synchronously return the record if it is available in the store,
75799      otherwise it will return `null`. A record is available if it has been fetched earlier, or
75800      pushed manually into the store.
75801       _Note: This is an synchronous method and does not return a promise._
75802       ```js
75803      var post = store.peekRecord('post', 1);
75804       post.get('id'); // 1
75805      ```
75806       @since 1.13.0
75807      @method peekRecord
75808      @param {String} modelName
75809      @param {String|Integer} id
75810      @return {DS.Model|null} record
75811    */
75812    peekRecord: function peekRecord(modelName, id) {
75813      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's peekRecord method", isPresent(modelName));
75814      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75815      if (this.hasRecordForId(modelName, id)) {
75816        return this._internalModelForId(modelName, id).getRecord();
75817      } else {
75818        return null;
75819      }
75820    },
75821
75822    /**
75823      This method is called by the record's `reload` method.
75824       This method calls the adapter's `find` method, which returns a promise. When
75825      **that** promise resolves, `reloadRecord` will resolve the promise returned
75826      by the record's `reload`.
75827       @method reloadRecord
75828      @private
75829      @param {DS.Model} internalModel
75830      @return {Promise} promise
75831    */
75832    reloadRecord: function reloadRecord(internalModel) {
75833      var modelName = internalModel.type.modelName;
75834      var adapter = this.adapterFor(modelName);
75835      var id = internalModel.id;
75836
75837      (0, _emberDataPrivateDebug.assert)("You cannot reload a re
75837cord without an ID", id);
75838      (0, _emberDataPrivateDebug.assert)("You tried to reload a record but you have no adapter (for " + modelName + ")", adapter);
75839      (0, _emberDataPrivateDebug.assert)("You tried to reload a record but your adapter does not implement `findRecord`", typeof adapter.findRecord === 'function' || typeof adapter.find === 'function');
75840
75841      return this.scheduleFetch(internalModel);
75842    },
75843
75844    /**
75845      Returns true if a record for a given type and ID is already loaded.
75846       @method hasRecordForId
75847      @param {(String|DS.Model)} modelName
75848      @param {(String|Integer)} inputId
75849      @return {Boolean}
75850    */
75851    hasRecordForId: function hasRecordForId(modelName, inputId) {
75852      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's hasRecordForId method", isPresent(modelName));
75853      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75854      var typeClass = this.modelFor(modelName);
75855      var id = (0, _emberDataPrivateSystemCoerceId['default'])(inputId);
75856      var internalModel = this.typeMapFor(typeClass).idToRecord[id];
75857      return !!internalModel && internalModel.isLoaded();
75858    },
75859
75860    /**
75861      Returns id record for a given type and ID. If one isn't already loaded,
75862      it builds a new record and leaves it in the `empty` state.
75863       @method recordForId
75864      @private
75865      @param {String} modelName
75866      @param {(String|Integer)} id
75867      @return {DS.Model} record
75868    */
75869    recordForId: function recordForId(modelName, id) {
75870      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's recordForId method", isPresent(modelName));
75871      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75872      return this._internalModelForId(modelName, id).getRecord();
75873    },
75874
75875    _internalModelForId: function _internalModelForId(typeName, inputId) {
75876      var typeClass = this.modelFor(typeName);
75877      var id = (0, _emberDataPrivateSystemCoerceId['default'])(inputId);
75878      var idToRecord = this.typeMapFor(typeClass).idToRecord;
75879      var record = idToRecord[id];
75880
75881      if (!record || !idToRecord[id]) {
75882        record = this.buildInternalModel(typeClass, id);
75883      }
75884
75885      return record;
75886    },
75887
75888    /**
75889      @method findMany
75890      @private
75891      @param {Array} internalModels
75892      @return {Promise} promise
75893    */
75894    findMany: function findMany(internalModels) {
75895      var finds = new Array(internalModels.length);
75896
75897      for (var i = 0; i < internalModels.length; i++) {
75898        finds[i] = this._findByInternalModel(internalModels[i]);
75899      }
75900
75901      return Promise.all(finds);
75902    },
75903
75904    /**
75905      If a relationship was originally populated by the adapter as a link
75906      (as opposed to a list of IDs), this method is called when the
75907      relationship is fetched.
75908       The link (which is usually a URL) is passed through unchanged, so the
75909      adapter can make whatever request it wants.
75910       The usual use-case is for the server to register a URL as a link, and
75911      then use that URL in the future to make a request for the relationship.
75912       @method findHasMany
75913      @private
75914      @param {DS.Model} owner
75915      @param {any} link
75916      @param {(Relationship)} relationship
75917      @return {Promise} promise
75918    */
75919    findHasMany: function findHasMany(owner, link, relationship) {
75920      var adapter = this.adapterFor(owner.type.modelName);
75921
75922      (0, _emberDataPrivateDebug.assert)("You tried to load a hasMany relationship but you have no adapter (for " + owner.type + ")", adapter);
75923      (0, _emberDataPrivateDebug.assert)("You tried to load a hasMany relationship from a specified `link` in the original payload but your adapter does not implement `findHasMany`", typeof adapter.findHasMany === 'function');
75924
75925      return (0, _emberDataPrivateSystemStoreFinders._findHasMany)(adapter, this, owner, link, relationship
75925);
75926    },
75927
75928    /**
75929      @method findBelongsTo
75930      @private
75931      @param {DS.Model} owner
75932      @param {any} link
75933      @param {Relationship} relationship
75934      @return {Promise} promise
75935    */
75936    findBelongsTo: function findBelongsTo(owner, link, relationship) {
75937      var adapter = this.adapterFor(owner.type.modelName);
75938
75939      (0, _emberDataPrivateDebug.assert)("You tried to load a belongsTo relationship but you have no adapter (for " + owner.type + ")", adapter);
75940      (0, _emberDataPrivateDebug.assert)("You tried to load a belongsTo relationship from a specified `link` in the original payload but your adapter does not implement `findBelongsTo`", typeof adapter.findBelongsTo === 'function');
75941
75942      return (0, _emberDataPrivateSystemStoreFinders._findBelongsTo)(adapter, this, owner, link, relationship);
75943    },
75944
75945    /**
75946      This method delegates a query to the adapter. This is the one place where
75947      adapter-level semantics are exposed to the application.
75948       Exposing queries this way seems preferable to creating an abstract query
75949      language for all server-side queries, and then require all adapters to
75950      implement them.
75951       ---
75952       If you do something like this:
75953       ```javascript
75954      store.query('person', { page: 1 });
75955      ```
75956       The call made to the server, using a Rails backend, will look something like this:
75957       ```
75958      Started GET "/api/v1/person?page=1"
75959      Processing by Api::V1::PersonsController#index as HTML
75960      Parameters: { "page"=>"1" }
75961      ```
75962       ---
75963       If you do something like this:
75964       ```javascript
75965      store.query('person', { ids: [1, 2, 3] });
75966      ```
75967       The call to the server, using a Rails backend, will look something like this:
75968       ```
75969      Started GET "/api/v1/person?ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=3"
75970      Processing by Api::V1::PersonsController#index as HTML
75971      Parameters: { "ids" => ["1", "2", "3"] }
75972      ```
75973       This method returns a promise, which is resolved with a `RecordArray`
75974      once the server returns.
75975       @since 1.13.0
75976      @method query
75977      @param {String} modelName
75978      @param {any} query an opaque query to be used by the adapter
75979      @return {Promise} promise
75980    */
75981    query: function query(modelName, _query2) {
75982      return this._query(modelName, _query2);
75983    },
75984
75985    _query: function _query(modelName, query, array) {
75986      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's query method", isPresent(modelName));
75987      (0, _emberDataPrivateDebug.assert)("You need to pass a query hash to the store's query method", query);
75988      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
75989      var typeClass = this.modelFor(modelName);
75990      array = array || this.recordArrayManager.createAdapterPopulatedRecordArray(typeClass, query);
75991
75992      var adapter = this.adapterFor(modelName);
75993
75994      (0, _emberDataPrivateDebug.assert)("You tried to load a query but you have no adapter (for " + typeClass + ")", adapter);
75995      (0, _emberDataPrivateDebug.assert)("You tried to load a query but your adapter does not implement `query`", typeof adapter.query === 'function');
75996
75997      return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)((0, _emberDataPrivateSystemStoreFinders._query)(adapter, this, typeClass, query, array));
75998    },
75999
76000    /**
76001      This method makes a request for one record, where the `id` is not known
76002      beforehand (if the `id` is known, use `findRecord` instead).
76003       This method can be used when it is certain that the server will return a
76004      single object for the primary data.
76005       Let's assume our API provides an endpoint for the currently logged in user
76006      via:
76007       ```
76008      // GET /api/current_user
76009      {
76010        user: {
76011          id: 1234,
76012          username: 'admin'
76013        }
76014      }
76015      ```
76016       Since the specific `id` of the `user` is not known beforehand, we can use
76017      `queryRecord` to get the user:
76018       ```javascript
76019      store.queryRecord('user', {}).then(function(user) {
76020        let username = user.get('username');
76021        console.log(`Currently logged in as ${username}`);
76022      });
76023      ```
76024       The request is made through the adapters' `queryRecord`:
76025       ```javascript
76026      
76026// app/adapters/user.js
76027      import DS from "ember-data";
76028       export default DS.Adapter.extend({
76029        queryRecord(modelName, query) {
76030          return Ember.$.getJSON("/api/current_user");
76031        }
76032      });
76033      ```
76034       Note: the primary use case for `store.queryRecord` is when a single record
76035      is queried and the `id` is not known beforehand. In all other cases
76036      `store.query` and using the first item of the array is likely the preferred
76037      way:
76038       ```
76039      // GET /users?username=unique
76040      {
76041        data: [{
76042          id: 1234,
76043          type: 'user',
76044          attributes: {
76045            username: "unique"
76046          }
76047        }]
76048      }
76049      ```
76050       ```javascript
76051      store.query('user', { username: 'unique' }).then(function(users) {
76052        return users.get('firstObject');
76053      }).then(function(user) {
76054        let id = user.get('id');
76055      });
76056      ```
76057       This method returns a promise, which resolves with the found record.
76058       If the adapter returns no data for the primary data of the payload, then
76059      `queryRecord` resolves with `null`:
76060       ```
76061      // GET /users?username=unique
76062      {
76063        data: null
76064      }
76065      ```
76066       ```javascript
76067      store.queryRecord('user', { username: 'unique' }).then(function(user) {
76068        console.log(user); // null
76069      });
76070      ```
76071       @since 1.13.0
76072      @method queryRecord
76073      @param {String} modelName
76074      @param {any} query an opaque query to be used by the adapter
76075      @return {Promise} promise which resolves with the found record or `null`
76076    */
76077    queryRecord: function queryRecord(modelName, query) {
76078      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's queryRecord method", isPresent(modelName));
76079      (0, _emberDataPrivateDebug.assert)("You need to pass a query hash to the store's queryRecord method", query);
76080      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76081
76082      var typeClass = this.modelFor(modelName);
76083      var adapter = this.adapterFor(modelName);
76084
76085      (0, _emberDataPrivateDebug.assert)("You tried to make a query but you have no adapter (for " + typeClass + ")", adapter);
76086      (0, _emberDataPrivateDebug.assert)("You tried to make a query but your adapter does not implement `queryRecord`", typeof adapter.queryRecord === 'function');
76087
76088      return (0, _emberDataPrivateSystemPromiseProxies.promiseObject)((0, _emberDataPrivateSystemStoreFinders._queryRecord)(adapter, this, typeClass, query));
76089    },
76090
76091    /**
76092      `findAll` asks the adapter's `findAll` method to find the records for the
76093      given type, and returns a promise which will resolve with all records of
76094      this type present in the store, even if the adapter only returns a subset
76095      of them.
76096       ```app/routes/authors.js
76097      import Ember from 'ember';
76098       export default Ember.Route.extend({
76099        model: function(params) {
76100          return this.store.findAll('author');
76101        }
76102      });
76103      ```
76104       _When_ the returned promise resolves depends on the reload behavior,
76105      configured via the passed `options` hash and the result of the adapter's
76106      `shouldReloadAll` method.
76107       ### Reloading
76108       If `{ reload: true }` is passed or `adapter.shouldReloadAll` evaluates to
76109      `true`, then the returned promise resolves once the adapter returns data,
76110      regardless if there are already records in the store:
76111       ```js
76112      store.push({
76113        data: {
76114          id: 'first',
76115          type: 'author'
76116        }
76117      });
76118       // adapter#findAll resolves with
76119      // [
76120      //   {
76121      //     id: 'second',
76122      //     type: 'author'
76123      //   }
76124      // ]
76125      store.findAll('author', { reload: true }).then(function(authors) {
76126        authors.getEach("id"); // ['first', 'second']
76127      });
76128      ```
76129       If no reload is indicated via the abovementioned ways, then the promise
76130      immediately resolves with all the records currently loaded in the store.
76131       ### Background Reloading
76132       Optionally, if `adapter.shouldBackgroundReloadAll` evaluates to `true`,
76133      then a background reload is started. Once this resolves, the array with
76134      which the promise resolves, is updated automatically so it contains all the
76135      records in the store:
76136       ```js
76137      
76137// app/adapters/application.js
76138      export default DS.Adapter.extend({
76139        shouldReloadAll(store, snapshotsArray) {
76140          return false;
76141        },
76142         shouldBackgroundReloadAll(store, snapshotsArray) {
76143          return true;
76144        }
76145      });
76146       // ...
76147       store.push({
76148        data: {
76149          id: 'first',
76150          type: 'author'
76151        }
76152      });
76153       var allAuthors;
76154      store.findAll('author').then(function(authors) {
76155        authors.getEach('id'); // ['first']
76156         allAuthors = authors;
76157      });
76158       // later, once adapter#findAll resolved with
76159      // [
76160      //   {
76161      //     id: 'second',
76162      //     type: 'author'
76163      //   }
76164      // ]
76165       allAuthors.getEach('id'); // ['first', 'second']
76166      ```
76167       If you would like to force or prevent background reloading, you can set a
76168      boolean value for `backgroundReload` in the options object for
76169      `findAll`.
76170       ```app/routes/post/edit.js
76171      import Ember from 'ember';
76172       export default Ember.Route.extend({
76173        model: function() {
76174          return this.store.findAll('post', { backgroundReload: false });
76175        }
76176      });
76177      ```
76178       If you pass an object on the `adapterOptions` property of the options
76179      argument it will be passed to you adapter via the `snapshotRecordArray`
76180       ```app/routes/posts.js
76181      import Ember from 'ember';
76182       export default Ember.Route.extend({
76183        model: function(params) {
76184          return this.store.findAll('post', {
76185            adapterOptions: { subscribe: false }
76186          });
76187        }
76188      });
76189      ```
76190       ```app/adapters/post.js
76191      import MyCustomAdapter from './custom-adapter';
76192       export default MyCustomAdapter.extend({
76193        findAll: function(store, type, sinceToken, snapshotRecordArray) {
76194          if (snapshotRecordArray.adapterOptions.subscribe) {
76195            // ...
76196          }
76197          // ...
76198        }
76199      });
76200      ```
76201        See [peekAll](#method_peekAll) to get an array of current records in the
76202      store, without waiting until a reload is finished.
76203       See [query](#method_query) to only get a subset of records from the server.
76204       @since 1.13.0
76205      @method findAll
76206      @param {String} modelName
76207      @param {Object} options
76208      @return {Promise} promise
76209    */
76210    findAll: function findAll(modelName, options) {
76211      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's findAll method", isPresent(modelName));
76212      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76213      var typeClass = this.modelFor(modelName);
76214
76215      return this._fetchAll(typeClass, this.peekAll(modelName), options);
76216    },
76217
76218    /**
76219      @method _fetchAll
76220      @private
76221      @param {DS.Model} typeClass
76222      @param {DS.RecordArray} array
76223      @return {Promise} promise
76224    */
76225    _fetchAll: function _fetchAll(typeClass, array, options) {
76226      options = options || {};
76227      var adapter = this.adapterFor(typeClass.modelName);
76228      var sinceToken = this.typeMapFor(typeClass).metadata.since;
76229
76230      (0, _emberDataPrivateDebug.assert)("You tried to load all records but you have no adapter (for " + typeClass + ")", adapter);
76231      (0, _emberDataPrivateDebug.assert)("You tried to load all records but your adapter does not implement `findAll`", typeof adapter.findAll === 'function');
76232
76233      set(array, 'isUpdating', true);
76234
76235      if (options.reload) {
76236        return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)((0, _emberDataPrivateSystemStoreFinders._findAll)(adapter, this, typeClass, sinceToken, options));
76237      }
76238
76239      var snapshotArray = array.createSnapshot(options);
76240
76241      if (adapter.shouldReloadAll(this, snapshotArray)) {
76242        return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)((0, _emberDataPrivateSystemStoreFinders._findAll)(adapter, this, typeClass, sinceToken, options));
76243      }
76244
76245      if (options.backgroundReload === false) {
76246        return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(Promise.resolve(array));
76247      }
76248
76249      if (options.backgroundReload || adapter.shouldBackgroundReloadAll(this, snapshotArray)) {
76250        (0, _emberDataPrivateSystemStoreFinders._findAll)(adapter, this, typeClass, sinceToken, options);
76251      }
76252
76253      return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(Promise.resolve(array));
76254    },
76255
76256    /**
76257      @method didUpdateAll
76258      @param {DS.Model} typeClass
76259      @private
76260    */
76261    didUpdateAll: function didUpdateAll(typeClass) {
76262      var liveRecordArray = this.recordArrayManager.liveRecordArrayFor(typeClass);
76263      set(liveRecordArray, 'isUpdating', false);
76264    },
76265
76266    /**
76267      This method returns a filtered array that contains all of the
76268      known records for a given type in the store.
76269       Note that because it's just a filter, the result will contain any
76270      locally created records of the type, however, it will not make a
76271      request to the backend to retrieve additional records. If you
76272      would like to request all the records from the backend please use
76273      [store.findAll](#method_findAll).
76274       Also note that multiple calls to `peekAll` for a given type will always
76275      return the same `RecordArray`.
76276       Example
76277       ```javascript
76278      var localPosts = store.peekAll('post');
76279      ```
76280       @since 1.13.0
76281      @method peekAll
76282      @param {String} modelName
76283      @return {DS.RecordArray}
76284    */
76285    peekAll: function peekAll(modelName) {
76286      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's peekAll method", isPresent(modelName));
76287      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76288      var typeClass = this.modelFor(modelName);
76289
76290      var liveRecordArray = this.recordArrayManager.liveRecordArrayFor(typeClass);
76291      this.recordArrayManager.populateLiveRecordArray(liveRecordArray, typeClass);
76292
76293      return liveRecordArray;
76294    },
76295
76296    /**
76297     This method unloads all records in the store.
76298      Optionally you can pass a type which unload all records for a given type.
76299      ```javascript
76300     store.unloadAll();
76301     store.unloadAll('post');
76302     ```
76303      @method unloadAll
76304     @param {String=} modelName
76305    */
76306    unloadAll: function unloadAll(modelName) {
76307      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), !modelName || typeof modelName === 'string');
76308      if (arguments.length === 0) {
76309        var typeMaps = this.typeMaps;
76310        var keys = Object.keys(typeMaps);
76311        var types = new Array(keys.length);
76312
76313        for (var i = 0; i < keys.length; i++) {
76314          types[i] = typeMaps[keys[i]]['type'].modelName;
76315        }
76316
76317        types.forEach(this.unloadAll, this);
76318      } else {
76319        var typeClass = this.modelFor(modelName);
76320        var typeMap = this.typeMapFor(typeClass);
76321        var records = typeMap.records.slice();
76322        var record = undefined;
76323
76324        for (var i = 0; i < records.length; i++) {
76325          record = records[i];
76326          record.unloadRecord();
76327          record.destroy(); // maybe within unloadRecord
76328        }
76329
76330        typeMap.metadata = new _emberDataPrivateSystemEmptyObject['default']();
76331      }
76332    },
76333
76334    /**
76335      Takes a type and filter function, and returns a live RecordArray that
76336      remains up to date as new records are loaded into the store or created
76337      locally.
76338       The filter function takes a materialized record, and returns true
76339      if the record should be included in the filter and false if it should
76340      not.
76341       Example
76342       ```javascript
76343      store.filter('post', function(post) {
76344        return post.get('unread');
76345      });
76346      ```
76347       The filter function is called once on all records for the type when
76348      it is created, and then once on each newly loaded or created record.
76349       If any of a record's properties change, or if it changes state, the
76350      filter function will be invoked again to determine whether it should
76351      still be in the array.
76352       Optionally you can pass a query, which is the equivalent of calling
76353      [query](#method_query) with that same query, to fetch additional records
76354      from the server. The results returned by the server could then appear
76355      in the filter if they match the filter function.
76356       The query itself is not used to filter records, it's only sent to your
76357      server for you to be able to do server-side filtering. The filter
76358      function will be applied on the returned results regardless.
76359       Example
76360       ```javascript
76361      store.filter('post', { unread: true }, function(post) {
76362        return post.get('unread');
76363      }).then(function(unreadPosts) {
76364        unreadPosts.get('length'); // 5
76365        var unreadPost = unreadPosts.objectAt(0);
76366        unreadPost.set('unread', false);
76367        unreadPosts.get('length'); // 4
76368      });
76369      ```
76370       @method filter
76371      @private
76372      @param {String} modelName
76373      @param {Object} query optional query
76374      @param {Function} filter
76375      @return {DS.PromiseArray}
76376      @deprecated
76377    */
76378    filter: function filter(modelName, query, _filter) {
76379      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's filter method", isPresent(modelName));
76380      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76381
76382      if (!_ember['default'].ENV.ENABLE_DS_FILTER) {
76383        (0, _emberDataPrivateDebug.assert)('The filter API has been moved to a plugin. To enable store.filter using an environment flag, or to use an alternative, you can visit the ember-data-filter addon page. https://github.com/ember-data/ember-data-filter', false);
76384      }
76385
76386      var promise;
76387      var length = arguments.length;
76388      var array;
76389      var hasQuery = length === 3;
76390
76391      // allow an optional server query
76392      if (hasQuery) {
76393        promise = this.query(modelName, query);
76394      } else if (arguments.length === 2) {
76395        _filter = query;
76396      }
76397
76398      modelName = this.modelFor(modelName);
76399
76400      if (hasQuery) {
76401        array = this.recordArrayManager.createFilteredRecordArray(modelName, _filter, query);
76402      } else {
76403        array = this.recordArrayManager.createFilteredRecordArray(modelName, _filter);
76404      }
76405
76406      promise = promise || Promise.resolve(array);
76407
76408      return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(promise.then(function () {
76409        return array;
76410      }, null, 'DS: Store#filter of ' + modelName));
76411    },
76412
76413    /**
76414      This method returns if a certain record is already loaded
76415      in the store. Use this function to know beforehand if a findRecord()
76416      will result in a request or that it will be a cache hit.
76417        Example
76418       ```javascript
76419      store.recordIsLoaded('post', 1); // false
76420      store.findRecord('post', 1).then(function() {
76421        store.recordIsLoaded('post', 1); // true
76422      });
76423      ```
76424       @method recordIsLoaded
76425      @param {String} modelName
76426      @param {string} id
76427      @return {boolean}
76428    */
76429    recordIsLoaded: function recordIsLoaded(modelName, id) {
76430      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's recordIsLoaded method", isPresent(modelName));
76431      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76432      return this.hasRecordForId(modelName, id);
76433    },
76434
76435    // ............
76436    // . UPDATING .
76437    // ............
76438
76439    /**
76440      If the adapter updates attributes the record will notify
76441      the store to update its  membership in any filters.
76442      To avoid thrashing, this method is invoked only once per
76443      run loop per record.
76444       @method dataWasUpdated
76445      @private
76446      @param {Class} type
76447      @param {InternalModel} internalModel
76448    */
76449    dataWasUpdated: function dataWasUpdated(type, internalModel) {
76450      this.recordArrayManager.recordDidChange(internalModel);
76451    },
76452
76453    // ..............
76454    // . PERSISTING .
76455    // ..............
76456
76457    /**
76458      This method is called by `record.save`, and gets passed a
76459      resolver for the promise that `record.save` returns.
76460       It schedules saving to happen at the end of the run loop.
76461       @method scheduleSave
76462      @private
76463      @param {InternalModel} internalModel
76464      @param {Resolver} resolver
76465      @param {Object} options
76466    */
76467    scheduleSave: function scheduleSave(internalModel, resolver, options) {
76468      var snapshot = internalModel.createSnapshot(options);
76469      internalModel.flushChangedAttributes();
76470      internalModel.adapterWillCommit();
76471      this._pendingSave.push({
76472        snapshot: snapshot,
76473        resolver: resolver
76474      });
76475      once(this, 'flushPendingSave');
76476    },
76477
76478    /**
76479      This method is called at the end of the run loop, and
76480      flushes any records passed into `scheduleSave`
76481       @method flushPendingSave
76482      @private
76483    */
76484    flushPendingSave: function flushPendingSave() {
76485      var _this = this;
76486
76487      var pending = this._pendingSave.slice();
76488      this._pendingSave = [];
76489
76490      pending.forEach(function (pendingItem) {
76491        var snapshot = pendingItem.snapshot;
76492        var resolver = pendingItem.resolver;
76493        var record = snapshot._internalModel;
76494        var adapter = _this.adapterFor(record.type.modelName);
76495        var operation;
76496
76497        if (get(record, 'currentState.stateName') === 'root.deleted.saved') {
76498          return resolver.resolve();
76499        } else if (record.isNew()) {
76500          operation = 'createRecord';
76501        } else if (record.isDeleted()) {
76502          operation = 'deleteRecord';
76503        } else {
76504          operation = 'updateRecord';
76505        }
76506
76507        resolver.resolve(_commit(adapter, _this, operation, snapshot));
76508      });
76509    },
76510
76511    /**
76512      This method is called once the promise returned by an
76513      adapter's `createRecord`, `updateRecord` or `deleteRecord`
76514      is resolved.
76515       If the data provides a server-generated ID, it will
76516      update the record and the store's indexes.
76517       @method didSaveRecord
76518      @private
76519      @param {InternalModel} internalModel the in-flight internal model
76520      @param {Object} data optional data (see above)
76521    */
76522    didSaveRecord: function didSaveRecord(internalModel, dataArg) {
76523      var data;
76524      if (dataArg) {
76525        data = dataArg.data;
76526      }
76527      if (data) {
76528        // normalize relationship IDs into records
76529        this._backburner.schedule('normalizeRelationships', this, '_setupRelationships', internalModel, data);
76530        this.updateId(internalModel, data);
76531      }
76532
76533      //We first make sure the primary data has been updated
76534      //TODO try to move notification to the user to the end of the runloop
76535      internalModel.adapterDidCommit(data);
76536    },
76537
76538    /**
76539      This method is called once the promise returned by an
76540      adapter's `createRecord`, `updateRecord` or `deleteRecord`
76541      is rejected with a `DS.InvalidError`.
76542       @method recordWasInvalid
76543      @private
76544      @param {InternalModel} internalModel
76545      @param {Object} errors
76546    */
76547    recordWasInvalid: function recordWasInvalid(internalModel, errors) {
76548      internalModel.adapterDidInvalidate(errors);
76549    },
76550
76551    /**
76552      This method is called once the promise returned by an
76553      adapter's `createRecord`, `updateRecord` or `deleteRecord`
76554      is rejected (with anything other than a `DS.InvalidError`).
76555       @method recordWasError
76556      @private
76557      @param {InternalModel} internalModel
76558      @param {Error} error
76559    */
76560    recordWasError: function recordWasError(internalModel, error) {
76561      internalModel.adapterDidError(error);
76562    },
76563
76564    /**
76565      When an adapter's `createRecord`, `updateRecord` or `deleteRecord`
76566      resolves with data, this method extracts the ID from the supplied
76567      data.
76568       @method updateId
76569      @private
76570      @param {InternalModel} internalModel
76571      @param {Object} data
76572    */
76573    updateId: function updateId(internalModel, data) {
76574      var oldId = internalModel.id;
76575      var id = (0, _emberDataPrivateSystemCoerceId['default'])(data.id);
76576
76577      (0, _emberDataPrivateDebug.assert)("An adapter cannot assign a new id to a record that already has an id. " + internalModel + " had id: " + oldId + " and you tried to update it with " + id + ". This likely happened because your server returned data in response to a find or update that had a different id than the one you sent.", oldId === null || id === oldId);
76578
76579      this.typeMapFor(internalModel.type).idToRecord[id] = internalModel;
76580
76581      internalModel.setId(id);
76582    },
76583
76584    /**
76585      Returns a map of IDs to client IDs for a given type.
76586       @method typeMapFor
76587      @private
76588      @param {DS.Model} typeClass
76589      @return {Object} typeMap
76590    */
76591    typeMapFor: function typeMapFor(typeClass) {
76592      var typeMaps = get(this, 'typeMaps');
76593      var guid = _ember['default'].guidFor(typeClass);
76594      var typeMap = typeMaps[guid];
76595
76596      if (typeMap) {
76597        return typeMap;
76598      }
76599
76600      typeMap = {
76601        idToRecord: new _emberDataPrivateSystemEmptyObject['default'](),
76602        records: [],
76603        metadata: new _emberDataPrivateSystemEmptyObject['default'](),
76604        type: typeClass
76605      };
76606
76607      typeMaps[guid] = typeMap;
76608
76609      return typeMap;
76610    },
76611
76612    // ................
76613    // . LOADING DATA .
76614    // ................
76615
76616    /**
76617      This internal method is used by `push`.
76618       @method _load
76619      @private
76620      @param {(String|DS.Model)} type
76621      @param {Object} data
76622    */
76623    _load: function _load(data) {
76624      var internalModel = this._internalModelForId(data.type, data.id);
76625
76626      internalModel.setupData(data);
76627
76628      this.recordArrayManager.recordDidChange(internalModel);
76629
76630      return internalModel;
76631    },
76632
76633    /*
76634      In case someone defined a relationship to a mixin, for example:
76635      ```
76636        var Comment = DS.Model.extend({
76637          owner: belongsTo('commentable'. { polymorphic: true})
76638        });
76639        var Commentable = Ember.Mixin.create({
76640          comments: hasMany('comment')
76641        });
76642      ```
76643      we want to look up a Commentable class which has all the necessary
76644      relationship metadata. Thus, we look up the mixin and create a mock
76645      DS.Model, so we can access the relationship CPs of the mixin (`comments`)
76646      in this case
76647    */
76648
76649    _modelForMixin: function _modelForMixin(modelName) {
76650      var normalizedModelName = (0, _emberDataPrivateSystemNormalizeModelName['default'])(modelName);
76651      // container.registry = 2.1
76652      // container._registry = 1.11 - 2.0
76653      // container = < 1.11
76654      var owner = (0, _emberDataPrivateUtils.getOwner)(this);
76655
76656      var mixin = owner._lookupFactory('mixin:' + normalizedModelName);
76657      if (mixin) {
76658        //Cache the class as a model
76659        owner.register('model:' + normalizedModelName, _emberDataModel['default'].extend(mixin));
76660      }
76661      var factory = this.modelFactoryFor(normalizedModelName);
76662      if (factory) {
76663        factory.__isMixin = true;
76664        factory.__mixin = mixin;
76665      }
76666
76667      return factory;
76668    },
76669
76670    /**
76671      Returns a model class for a particular key. Used by
76672      methods that take a type key (like `find`, `createRecord`,
76673      etc.)
76674       @method modelFor
76675      @param {String} modelName
76676      @return {DS.Model}
76677    */
76678    modelFor: function modelFor(modelName) {
76679      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's modelFor method", isPresent(modelName));
76680      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76681
76682      var factory = this.modelFactoryFor(modelName);
76683      if (!factory) {
76684        //Support looking up mixins as base types for polymorphic relationships
76685        factory = this._modelForMixin(modelName);
76686      }
76687      if (!factory) {
76688        throw new _ember['default'].Error("No model was found for '" + modelName + "'");
76689      }
76690      factory.modelName = factory.modelName || (0, _emberDataPrivateSystemNormalizeModelName['default'])(modelName);
76691
76692      return factory;
76693    },
76694
76695    modelFactoryFor: function modelFactoryFor(modelName) {
76696      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's modelFactoryFor method", isPresent(modelName));
76697      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76698      var normalizedKey = (0, _emberDataPrivateSystemNormalizeModelName['default'])(modelName);
76699
76700      var owner = (0, _emberDataPrivateUtils.getOwner)(this);
76701
76702      return owner._lookupFactory('model:' + normalizedKey);
76703    },
76704
76705    /**
76706      Push some data for a given type into the store.
76707       This method expects normalized [JSON API](http://jsonapi.org/) document. This means you have to follow [JSON API specification](http://jsonapi.org/format/) with few minor adjustments:
76708      - record's `type` should always be in singular, dasherized form
76709      - members (properties) should be camelCased
76710       [Your primary data should be wrapped inside `data` property](http://jsonapi.org/format/#document-top-level):
76711       ```js
76712      store.push({
76713        data: {
76714          // primary data for single record of type `Person`
76715          id: '1',
76716          type: 'person',
76717          attributes: {
76718            firstName: 'Daniel',
76719            lastName: 'Kmak'
76720          }
76721        }
76722      });
76723      ```
76724       [Demo.](http://ember-twiddle.com/fb99f18cd3b4d3e2a4c7)
76725       `data` property can also hold an array (of records):
76726       ```js
76727      store.push({
76728        data: [
76729          // an array of records
76730          {
76731            id: '1',
76732            type: 'person',
76733            attributes: {
76734              firstName: 'Daniel',
76735              lastName: 'Kmak'
76736            }
76737          },
76738          {
76739            id: '2',
76740            type: 'person',
76741            attributes: {
76742              firstName: 'Tom',
76743              lastName: 'Dale'
76744            }
76745          }
76746        ]
76747      });
76748      ```
76749       [Demo.](http://ember-twiddle.com/69cdbeaa3702159dc355)
76750       There are some typical properties for `JSONAPI` payload:
76751      * `id` - mandatory, unique record's key
76752      * `type` - mandatory string which matches `model`'s dasherized name in singular form
76753      * `attributes` - object which holds data for record attributes - `DS.attr`'s declared in model
76754      * `relationships` - object which must contain any of the following properties under each relationships' respective key (example path is `relationships.achievements.data`):
76755        - [`links`](http://jsonapi.org/format/#document-links)
76756        - [`data`](http://jsonapi.org/format/#document-resource-object-linkage) - place for primary data
76757        - [`meta`](http://jsonapi.org/format/#document-meta) - object which contains meta-information about relationship
76758       For this model:
76759       ```app/models/person.js
76760      import DS from 'ember-data';
76761       export default DS.Model.extend({
76762        firstName: DS.attr('string'),
76763        lastName: DS.attr('string'),
76764         children: DS.hasMany('person')
76765      });
76766      ```
76767       To represent the children as IDs:
76768       ```js
76769      {
76770        data: {
76771          id: '1',
76772          type: 'person',
76773          attributes: {
76774            firstName: 'Tom',
76775            lastName: 'Dale'
76776          },
76777          relationships: {
76778            children: {
76779              data: [
76780                {
76781                  id: '2',
76782                  type: 'person'
76783                },
76784                {
76785                  id: '3',
76786                  type: 'person'
76787                },
76788                {
76789                  id: '4',
76790                  type: 'person'
76791                }
76792              ]
76793            }
76794          }
76795        }
76796      }
76797      ```
76798       [Demo.](http://ember-twiddle.com/343e1735e034091f5bde)
76799       To represent the children relationship as a URL:
76800       ```js
76801      {
76802        data: {
76803          id: '1',
76804          type: 'person',
76805          attributes: {
76806            firstName: 'Tom',
76807            lastName: 'Dale'
76808          },
76809          relationships: {
76810            children: {
76811              links: {
76812                related: '/people/1/children'
76813              }
76814            }
76815          }
76816        }
76817      }
76818      ```
76819       If you're streaming data or implementing an adapter, make sure
76820      that you have converted the incoming data into this form. The
76821      store's [normalize](#method_normalize) method is a convenience
76822      helper for converting a json payload into the form Ember Data
76823      expects.
76824       ```js
76825      store.push(store.normalize('person', data));
76826      ```
76827       This method can be used both to push in brand new
76828      records, as well as to update existing records.
76829       @method push
76830      @param {Object} data
76831      @return {DS.Model|Array} the record(s) that was created or
76832        updated.
76833    */
76834    push: function push(data) {
76835      var included = data.included;
76836      var i, length;
76837      if (included) {
76838        for (i = 0, length = included.length; i < length; i++) {
76839          this._pushInternalModel(included[i]);
76840        }
76841      }
76842
76843      if (Array.isArray(data.data)) {
76844        length = data.data.length;
76845        var internalModels = new Array(length);
76846        for (i = 0; i < length; i++) {
76847          internalModels[i] = this._pushInternalModel(data.data[i]).getRecord();
76848        }
76849        return internalModels;
76850      }
76851
76852      if (data.data === null) {
76853        return null;
76854      }
76855
76856      (0, _emberDataPrivateDebug.assert)('Expected an object in the \'data\' property in a call to \'push\' for ' + data.type + ', but was ' + _ember['default'].typeOf(data.data), _ember['default'].typeOf(data.data) === 'object');
76857
76858      var internalModel = this._pushInternalModel(data.data);
76859
76860      return internalModel.getRecord();
76861    },
76862
76863    _hasModelFor: function _hasModelFor(type) {
76864      return !!(0, _emberDataPrivateUtils.getOwner)(this)._lookupFactory('model:' + type);
76865    },
76866
76867    _pushInternalModel: function _pushInternalModel(data) {
76868      var _this2 = this;
76869
76870      var modelName = data.type;
76871      (0, _emberDataPrivateDebug.assert)('You must include an \'id\' for ' + modelName + ' in an object passed to \'push\'', data.id !== null && data.id !== undefined && data.id !== '');
76872      (0, _emberDataPrivateDebug.assert)('You tried to push data with a type \'' + modelName + '\' but no model could be found with that name.', this._hasModelFor(modelName));
76873
76874      (0, _emberDataPrivateDebug.runInDebug)(function () {
76875        // If Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS is set to true and the payload
76876        // contains unknown attributes or relationships, log a warning.
76877
76878        if (_ember['default'].ENV.DS_WARN_ON_UNKNOWN_KEYS) {
76879          (function () {
76880            var type = _this2.modelFor(modelName);
76881
76882            // Check unknown attributes
76883            var unknownAttributes = Object.keys(data.attributes || {}).filter(function (key) {
76884              return !get(type, 'fields').has(key);
76885            });
76886            var unknownAttributesMessage = 'The payload for \'' + type.modelName + '\' contains these unknown attributes: ' + unknownAttributes + '. Make sure they\'ve been defined in your model.';
76887            (0, _emberDataPrivateDebug.warn)(unknownAttributesMessage, unknownAttributes.length === 0, { id: 'ds.store.unknown-keys-in-payload' });
76888
76889            // Check unknown relationships
76890            var unknownRelationships = Object.keys(data.relationships || {}).filter(function (key) {
76891              return !get(type, 'fields').has(key);
76892            });
76893            var unknownRelationshipsMessage = 'The payload for \'' + type.modelName + '\' contains these unknown relationships: ' + unknownRelationships + '. Make sure they\'ve been defined in your model.';
76894            (0, _emberDataPrivateDebug.warn)(unknownRelationshipsMessage, unknownRelationships.length === 0, { id: 'ds.store.unknown-keys-in-payload' });
76895          })();
76896        }
76897      });
76898
76899      // Actually load the record into the store.
76900      var internalModel = this._load(data);
76901
76902      this._backburner.join(function () {
76903        _this2._backburner.schedule('normalizeRelationships', _this2, '_setupRelationships', internalModel, data);
76904      });
76905
76906      return internalModel;
76907    },
76908
76909    _setupRelationships: function _setupRelationships(record, data) {
76910      // This will convert relationships specified as IDs into DS.Model instances
76911      // (possibly unloaded) and also create the data structures used to track
76912      // relationships.
76913      setupRelationships(this, record, data);
76914    },
76915
76916    /**
76917      Push some raw data into the store.
76918       This method can be used both to push in brand new
76919      records, as well as to update existing records. You
76920      can push in more than one type of object at once.
76921      All objects should be in the format expected by the
76922      serializer.
76923       ```app/serializers/application.js
76924      import DS from 'ember-data';
76925       export default DS.ActiveModelSerializer;
76926      ```
76927       ```js
76928      var pushData = {
76929        posts: [
76930          { id: 1, post_title: "Great post", comment_ids: [2] }
76931        ],
76932        comments: [
76933          { id: 2, comment_body: "Insightful comment" }
76934        ]
76935      }
76936       store.pushPayload(pushData);
76937      ```
76938       By default, the data will be deserialized using a default
76939      serializer (the application serializer if it exists).
76940       Alternatively, `pushPayload` will accept a model type which
76941      will determine which serializer will process the payload.
76942       ```app/serializers/application.js
76943      import DS from 'ember-data';
76944       export default DS.ActiveModelSerializer;
76945      ```
76946       ```app/serializers/post.js
76947      import DS from 'ember-data';
76948       export default DS.JSONSerializer;
76949      ```
76950       ```js
76951      store.pushPayload('comment', pushData); // Will use the application serializer
76952      store.pushPayload('post', pushData); // Will use the post serializer
76953      ```
76954       @method pushPayload
76955      @param {String} modelName Optionally, a model type used to determine which serializer will be used
76956      @param {Object} inputPayload
76957    */
76958    pushPayload: function pushPayload(modelName, inputPayload) {
76959      var _this3 = this;
76960
76961      var serializer;
76962      var payload;
76963      if (!inputPayload) {
76964        payload = modelName;
76965        serializer = defaultSerializer(this);
76966        (0, _emberDataPrivateDebug.assert)("You cannot use `store#pushPayload` without a modelName unless your default serializer defines `pushPayload`", typeof serializer.pushPayload === 'function');
76967      } else {
76968        payload = inputPayload;
76969        (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
76970        serializer = this.serializerFor(modelName);
76971      }
76972      if (false) {
76973        return this._adapterRun(function () {
76974          return serializer.pushPayload(_this3, payload);
76975        });
76976      } else {
76977        this._adapterRun(function () {
76978          return serializer.pushPayload(_this3, payload);
76979        });
76980      }
76981    },
76982
76983    /**
76984      `normalize` converts a json payload into the normalized form that
76985      [push](#method_push) expects.
76986       Example
76987       ```js
76988      socket.on('message', function(message) {
76989        var modelName = message.model;
76990        var data = message.data;
76991        store.push(store.normalize(modelName, data));
76992      });
76993      ```
76994       @method normalize
76995      @param {String} modelName The name of the model type for this payload
76996      @param {Object} payload
76997      @return {Object} The normalized payload
76998    */
76999    normalize: function normalize(modelName, payload) {
77000      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's normalize method", isPresent(modelName));
77001      (0, _emberDataPrivateDebug.assert)('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
77002      var serializer = this.serializerFor(modelName);
77003      var model = this.modelFor(modelName);
77004      return serializer.normalize(model, payload);
77005    },
77006
77007    /**
77008      Build a brand new record for a given type, ID, and
77009      initial data.
77010       @method buildRecord
77011      @private
77012      @param {DS.Model} type
77013      @param {String} id
77014      @param {Object} data
77015      @return {InternalModel} internal model
77016    */
77017    buildInternalModel: function buildInternalModel(type, id, data) {
77018      var typeMap = this.typeMapFor(type);
77019      var idToRecord = typeMap.idToRecord;
77020
77021      (0, _emberDataPrivateDebug.assert)('The id ' + id + ' has already been used with another record of type ' + type.toString() + '.', !id || !idToRecord[id]);
77022      (0, _emberDataPrivateDebug.assert)('\'' + _ember['default'].inspect(type) + '\' does not appear to be an ember-data model', typeof type._create === 'function');
77023
77024      // lookupFactory should really return an object that creates
77025      // instances with the injections applied
77026      var internalModel = new _emberDataPrivateSystemModelInternalModel['default'](type, id, this, null, data);
77027
77028      // if we're creating an item, this process will be done
77029      // later, once the object has been persisted.
77030      if (id) {
77031        idToRecord[id] = internalModel;
77032      }
77033
77034      typeMap.records.push(internalModel);
77035
77036      return internalModel;
77037    },
77038
77039    //Called by the state machine to notify the store that the record 
77039is ready to be interacted with
77040    recordWasLoaded: function recordWasLoaded(record) {
77041      this.recordArrayManager.recordWasLoaded(record);
77042    },
77043
77044    // ...............
77045    // . DESTRUCTION .
77046    // ...............
77047
77048    /**
77049      When a record is destroyed, this un-indexes it and
77050      removes it from any record arrays so it can be GCed.
77051       @method _dematerializeRecord
77052      @private
77053      @param {InternalModel} internalModel
77054    */
77055    _dematerializeRecord: function _dematerializeRecord(internalModel) {
77056      var type = internalModel.type;
77057      var typeMap = this.typeMapFor(type);
77058      var id = internalModel.id;
77059
77060      internalModel.updateRecordArrays();
77061
77062      if (id) {
77063        delete typeMap.idToRecord[id];
77064      }
77065
77066      var loc = typeMap.records.indexOf(internalModel);
77067      typeMap.records.splice(loc, 1);
77068    },
77069
77070    // ......................
77071    // . PER-TYPE ADAPTERS
77072    // ......................
77073
77074    /**
77075      Returns an instance of the adapter for a given type. For
77076      example, `adapterFor('person')` will return an instance of
77077      `App.PersonAdapter`.
77078       If no `App.PersonAdapter` is found, this method will look
77079      for an `App.ApplicationAdapter` (the default adapter for
77080      your entire application).
77081       If no `App.ApplicationAdapter` is found, it will return
77082      the value of the `defaultAdapter`.
77083       @method adapterFor
77084      @public
77085      @param {String} modelName
77086      @return DS.Adapter
77087    */
77088    adapterFor: function adapterFor(modelName) {
77089      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's adapterFor method", isPresent(modelName));
77090      (0, _emberDataPrivateDebug.assert)('Passing classes to store.adapterFor has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
77091
77092      return this.lookupAdapter(modelName);
77093    },
77094
77095    _adapterRun: function _adapterRun(fn) {
77096      return this._backburner.run(fn);
77097    },
77098
77099    // ..............................
77100    // . RECORD CHANGE NOTIFICATION .
77101    // ..............................
77102
77103    /**
77104      Returns an instance of the serializer for a given type. For
77105      example, `serializerFor('person')` will return an instance of
77106      `App.PersonSerializer`.
77107       If no `App.PersonSerializer` is found, this method will look
77108      for an `App.ApplicationSerializer` (the default serializer for
77109      your entire application).
77110       if no `App.ApplicationSerializer` is found, it will attempt
77111      to get the `defaultSerializer` from the `PersonAdapter`
77112      (`adapterFor('person')`).
77113       If a serializer cannot be found on the adapter, it will fall back
77114      to an instance of `DS.JSONSerializer`.
77115       @method serializerFor
77116      @public
77117      @param {String} modelName the record to serialize
77118      @return {DS.Serializer}
77119    */
77120    serializerFor: function serializerFor(modelName) {
77121      (0, _emberDataPrivateDebug.assert)("You need to pass a model name to the store's serializerFor method", isPresent(modelName));
77122      (0, _emberDataPrivateDebug.assert)('Passing classes to store.serializerFor has been removed. Please pass a dasherized string instead of ' + _ember['default'].inspect(modelName), typeof modelName === 'string');
77123
77124      var fallbacks = ['application', this.adapterFor(modelName).get('defaultSerializer'), '-default'];
77125
77126      var serializer = this.lookupSerializer(modelName, fallbacks);
77127      return serializer;
77128    },
77129
77130    /**
77131      Retrieve a particular instance from the
77132      container cache. If not found, creates it and
77133      placing it in the cache.
77134       Enabled a store to manage local instances of
77135      adapters and serializers.
77136       @method retrieveManagedInstance
77137      @private
77138      @param {String} modelName the object modelName
77139      @param {String} name the object name
77140      @param {Array} fallbacks the fallback objects to lookup if the lookup for modelName or 'application' fails
77141      @return {Ember.Object}
77142    */
77143    retrieveManagedInstance: function retrieveManagedInstance(type, modelName, fallbacks) {
77144      var normalizedModelName = (0, _emberDataPrivateSystemNormalizeModelName['default'])(modelName);
77145
77146      var instance = this._instanceCache.get(type, normalizedModelName, fallbacks);
77147      set(instance, 'store', this);
77148      return instance;
77149    },
77150
77151    lookupAdapter: function lookupAdapter(name) {
77152      return this.retrieveManagedInstance('adapter', name, this.get('_adapterFallbacks'));
77153    },
77154
77155    _adapterFallbacks: _ember['default'].computed('adapter', function () {
77156      var adapter = this.get('adapter');
77157      return ['application', adapter, '-json-api'];
77158    }),
77159
77160    lookupSerializer: function lookupSerializer(name, fallbacks) {
77161      return this.retrieveManagedInstance('serializer', name, fallbacks);
77162    },
77163
77164    willDestroy: function willDestroy() {
77165      this._super.apply(this, arguments);
77166      this.recordArrayManager.destroy();
77167
77168      this.unloadAll();
77169    }
77170
77171  });
77172
77173  function deserializeRecordId(store, key, relationship, id) {
77174    if (isNone(id)) {
77175      return;
77176    }
77177
77178    (0, _emberDataPrivateDebug.assert)('A ' + relationship.parentType + ' record was pushed into the store with the value of ' + key + ' being ' + _ember['default'].inspect(id) + ', but ' + key + ' is a belongsTo relationship so the value must not be an array. You should probably check your data payload or serializer.', !Array.isArray(id));
77179
77180    //TODO:Better asserts
77181    return store._internalModelForId(id.type, id.id);
77182  }
77183
77184  function deserializeRecordIds(store, key, relationship, ids) {
77185    if (isNone(ids)) {
77186      return;
77187    }
77188
77189    (0, _emberDataPrivateDebug.assert)('A ' + relationship.parentType + ' record was pushed into the store with the value of ' + key + ' being \'' + _ember['default'].inspect(ids) + '\', but ' + key + ' is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer.', Array.isArray(ids));
77190    var _ids = new Array(ids.length);
77191
77192    for (var i = 0; i < ids.length; i++) {
77193      _ids[i] = deserializeRecordId(store, key, relationship, ids[i]);
77194    }
77195
77196    return _ids;
77197  }
77198
77199  // Delegation to the adapter and promise management
77200
77201  function defaultSerializer(store) {
77202    return store.serializerFor('application');
77203  }
77204
77205  function _commit(adapter, store, operation, snapshot) {
77206    var internalModel = snapshot._internalModel;
77207    var modelName = snapshot.modelName;
77208    var typeClass = store.modelFor(modelName);
77209    var promise = adapter[operation](store, typeClass, snapshot);
77210    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
77211    var label = 'DS: Extract and notify about ' + operation + ' completion of ' + internalModel;
77212
77213    (0, _emberDataPrivateDebug.assert)('Your adapter\'s \'' + operation + '\' method must return a value, but it returned \'undefined\'', promise !== undefined);
77214
77215    promise = Promise.resolve(promise, label);
77216    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77217    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, internalModel));
77218
77219    return promise.then(function (adapterPayload) {
77220      store._adapterRun(function () {
77221        var payload, data;
77222        if (adapterPayload) {
77223          payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, snapshot.id, operation);
77224          if (payload.included) {
77225            store.push({ data: payload.included });
77226          }
77227          data = payload.data;
77228        }
77229        store.didSaveRecord(internalModel, { data: data });
77230      });
77231
77232      return internalModel;
77233    }, function (error) {
77234      if (error instanceof _emberDataAdaptersErrors.InvalidError) {
77235        var errors = serializer.extractErrors(store, typeClass, error, snapshot.id);
77236        store.recordWasInvalid(internalModel, errors);
77237      } else {
77238        store.recordWasError(internalModel, error);
77239      }
77240
77241      throw error;
77242    }, label);
77243  }
77244
77245  function setupRelationships(store, record, data) {
77246    if (!data.relationships) {
77247      return;
77248    }
77249
77250    record.type.eachRelationship(function (key, descriptor) {
77251      var kind = descriptor.kind;
77252
77253      if (!data.relationships[key]) {
77254        return;
77255      }
77256
77257      var relationship;
77258
77259      if (data.relationships[key].links && data.relationships[key].links.related) {
77260        var relatedLink = (0, _emberDataPrivateSystemNormalizeLink['default'])(data.relationships[key].links.related);
77261        if (relatedLink && relatedLink.href) {
77262          relationship = record._relationships.get(key);
77263          relationship.updateLink(relatedLink.href);
77264        }
77265      }
77266
77267      if (data.relationships[key].meta) {
77268        relationship = record._relationships.get(key);
77269        relationship.updateMeta(data.relationships[key].meta);
77270      }
77271
77272      // If the data contains a relationship that is specified as an ID (or IDs),
77273      // normalizeRelationship will convert them into DS.Model instances
77274      // (possibly unloaded) before we push the payload into the store.
77275      normalizeRelationship(store, key, descriptor, data.relationships[key]);
77276
77277      var value = data.relationships[key].data;
77278
77279      if (value !== undefined) {
77280        if (kind === 'belongsTo') {
77281          relationship = record._relationships.get(key);
77282          relationship.setCanonicalRecord(value);
77283        } else if (kind === 'hasMany') {
77284          relationship = record._relationships.get(key);
77285          relationship.updateRecordsFromAdapter(value);
77286        }
77287      }
77288    });
77289  }
77290
77291  function normalizeRelationship(store, key, relationship, jsonPayload) {
77292    var data = jsonPayload.data;
77293    if (data) {
77294      var kind = relationship.kind;
77295      if (kind === 'belongsTo') {
77296        jsonPayload.data = deserializeRecordId(store, key, relationship, data);
77297      } else if (kind === 'hasMany') {
77298        jsonPayload.data = deserializeRecordIds(store, key, relationship, data);
77299      }
77300    }
77301  }
77302
77303  exports.Store = Store;
77304  exports['default'] = Store;
77305});
77306define('ember-data/-private/system/store/common', ['exports', 'ember'], function (exports, _ember) {
77307  'use strict';
77308
77309  exports._bind = _bind;
77310  exports._guard = _guard;
77311  exports._objectIsAlive = _objectIsAlive;
77312
77313  var get = _ember['default'].get;
77314
77315  function _bind(fn) {
77316    var args = Array.prototype.slice.call(arguments, 1);
77317
77318    return function () {
77319      return fn.apply(undefined, args);
77320    };
77321  }
77322
77323  function _guard(promise, test) {
77324    var guarded = promise['finally'](function () {
77325      if (!test()) {
77326        guarded._subscribers.length = 0;
77327      }
77328    });
77329
77330    return guarded;
77331  }
77332
77333  function _objectIsAlive(object) {
77334    return !(get(object, "isDestroyed") || get(object, "isDestroying"));
77335  }
77336});
77337define('ember-data/-private/system/store/container-instance-cache', ['exports', 'ember', 'ember-data/-private/system/empty-object'], function (exports, _ember, _emberDataPrivateSystemEmptyObject) {
77338  'use strict';
77339
77340  exports['default'] = ContainerInstanceCache;
77341
77342  var assign = _ember['default'].assign || _ember['default'].merge;
77343
77344  /**
77345   * The `ContainerInstanceCache` serves as a lazy cache for looking up
77346   * instances of serializers and adapters. It has some additional logic for
77347   * finding the 'fallback' adapter or serializer.
77348   *
77349   * The 'fallback' adapter or serializer is an adapter or serializer that is looked up
77350   * when the preferred lookup fails. For example, say you try to look up `adapter:post`,
77351   * but there is no entry (app/adapters/post.js in EmberCLI) for `adapter:post` in the registry.
77352   *
77353   * The `fallbacks` array passed will then be used; the first entry in the fallbacks array
77354   * that exists in the container will then be cached for `adapter:post`. So, the next time you
77355   * look up `adapter:post`, you'll get the `adapter:application` instance (or whatever the fallback
77356   * was if `adapter:application` doesn't exist).
77357   *
77358   * @private
77359   * @class ContainerInstanceCache
77360   *
77361  */
77362  function ContainerInstanceCache(owner) {
77363    this._owner = owner;
77364    this._cache = new _emberDataPrivateSystemEmptyObject['default']();
77365  }
77366
77367  ContainerInstanceCache.prototype = new _emberDataPrivateSystemEmptyObject['default']();
77368
77369  assign(ContainerInstanceCache.prototype, {
77370    get: function get(type, preferredKey, fallbacks) {
77371      var cache = this._cache;
77372      var preferredLookupKey = type + ':' + preferredKey;
77373
77374      if (!(preferredLookupKey in cache)) {
77375        var instance = this.instanceFor(preferredLookupKey) || this._findInstance(type, fallbacks);
77376        if (instance) {
77377          cache[preferredLookupKey] = instance;
77378        }
77379      }
77380      return cache[preferredLookupKey];
77381    },
77382
77383    _findInstance: function _findInstance(type, fallbacks) {
77384      for (var i = 0, _length = fallbacks.length; i < _length; i++) {
77385        var fallback = fallbacks[i];
77386        var lookupKey = type + ':' + fallback;
77387        var instance = this.instanceFor(lookupKey);
77388
77389        if (instance) {
77390          return instance;
77391        }
77392      }
77393    },
77394
77395    instanceFor: function instanceFor(key) {
77396      var cache = this._cache;
77397      if (!cache[key]) {
77398        var instance = this._owner.lookup(key);
77399        if (instance) {
77400          cache[key] = instance;
77401        }
77402      }
77403      return cache[key];
77404    },
77405
77406    destroy: function destroy() {
77407      var cache = this._cache;
77408      var cacheEntries = Object.keys(cache);
77409
77410      for (var i = 0, _length2 = cacheEntries.length; i < _length2; i++) {
77411        var cacheKey = cacheEntries[i];
77412        var cacheEntry = cache[cacheKey];
77413        if (cacheEntry) {
77414          cacheEntry.destroy();
77415        }
77416      }
77417      this._owner = null;
77418    },
77419
77420    constructor: ContainerInstanceCache,
77421
77422    toString: function toString() {
77423      return 'ContainerInstanceCache';
77424    }
77425  });
77426});
77427define("ember-data/-private/system/store/finders", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/store/common", "ember-data/-private/system/store/serializer-response", "ember-data/-private/system/store/serializers"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemStoreCommon, _emberDataPrivateSystemStoreSerializerResponse, _emberDataPrivateSystemStoreSerializers) {
77428  "use strict";
77429
77430  exports._find = _find;
77431  exports._findMany = _findMany;
77432  exports._findHasMany = _findHasMany;
77433  exports._findBelongsTo = _findBelongsTo;
77434  exports._findAll = _findAll;
77435  exports._query = _query;
77436  exports._queryRecord = _queryRecord;
77437
77438  var Promise = _ember["default"].RSVP.Promise;
77439
77440  function payloadIsNotBlank(adapterPayload) {
77441    if (Array.isArray(adapterPayload)) {
77442      return true;
77443    } else {
77444      return Object.keys(adapterPayload || {}).length;
77445    }
77446  }
77447
77448  function _find(adapter, store, typeClass, id, internalModel, options) {
77449    var snapshot = internalModel.createSnapshot(options);
77450    var promise = adapter.findRecord(store, typeClass, id, snapshot);
77451    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, internalModel.type.modelName);
77452    var label = "DS: Handle Adapter#findRecord of " + typeClass + " with id: " + id;
77453
77454    promise = Promise.resolve(promise, label);
77455    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77456
77457    return promise.then(function (adapterPayload) {
77458      (0, _emberDataPrivateDebug.assert)("You made a `findRecord` request for a " + typeClass.modelName + " with id " + id + ", but the adapter's response did not have any data", payloadIsNotBlank(adapterPayload));
77459      return store._adapterRun(function () {
77460        var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, id, 'findRecord');
77461        (0, _emberDataPrivateDebug.assert)('Ember Data expected the primary data returned from a `findRecord` response to be an object but instead it found an array.', !Array.isArray(payload.data));
77462        //TODO Optimize
77463        var record = store.push(payload);
77464        return record._internalModel;
77465      });
77466    }, function (error) {
77467      internalModel.notFound();
77468      if (internalModel.isEmpty()) {
77469        internalModel.unloadRecord();
77470      }
77471
77472      throw error;
77473    }, "DS: Extract payload of '" + typeClass + "'");
77474  }
77475
77476  function _findMany(adapter, store, typeClass, ids, internalModels) {
77477    var snapshots = _ember["default"].A(internalModels).invoke('createSnapshot');
77478    var promise = adapter.findMany(store, typeClass, ids, snapshots);
77479    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, typeClass.modelName);
77480    var label = "DS: Handle Adapter#findMany of " + typeClass;
77481
77482    if (promise === undefined) {
77483      throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
77484    }
77485
77486    promise = Promise.resolve(promise, label);
77487    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77488
77489    return promise.then(function (adapterPayload) {
77490      (0, _emberDataPrivateDebug.assert)("You made a `findMany` request for " + typeClass.modelName + " records with ids " + ids + ", but the adapter's response did not have any data", payloadIsNotBlank(adapterPayload));
77491      return store._adapterRun(function () {
77492        var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findMany');
77493        //TODO Optimize, no need to materialize here
77494        var records = store.push(payload);
77495        var internalModels = new Array(records.length);
77496
77497        for (var i = 0; i < records.length; i++) {
77498          internalModels[i] = records[i]._internalModel;
77499        }
77500
77501        return internalModels;
77502      });
77503    }, null, "DS: Extract payload of " + typeClass);
77504  }
77505
77506  function _findHasMany(adapter, store, internalModel, link, relationship) {
77507    var snapshot = internalModel.createSnapshot();
77508    var typeClass = store.modelFor(relationship.type);
77509    var promise = adapter.findHasMany(store, snapshot, link, relationship);
77510    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, relationship.type);
77511    var label = "DS: Handle Adapter#findHasMany of " + internalModel + " : " + relationship.type;
77512
77513    promise = Promise.resolve(promise, label);
77514    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77515    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, internalModel));
77516
77517    return promise.then(function (adapterPayload) {
77518      (0, _emberDataPrivateDebug.assert)("You made a `findHasMany` request for a " + internalModel.modelName + "'s `" + relationship.key + "` relationship, using link " + link + ", but the adapter's response did not have any data", payloadIsNotBlank(adapterPayload));
77519      return store._adapterRun(function () {
77520        var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findHasMany');
77521        //TODO Use a non record creating push
77522        var records = store.push(payload);
77523        var recordArray = records.map(function (record) {
77524          return record._internalModel;
77525        });
77526        recordArray.meta = payload.meta;
77527        return recordArray;
77528      });
77529    }, null, "DS: Extract payload of " + internalModel + " : hasMany " + relationship.type);
77530  }
77531
77532  function _findBelongsTo(adapter, store, internalModel, link, relationship
77532) {
77533    var snapshot = internalModel.createSnapshot();
77534    var typeClass = store.modelFor(relationship.type);
77535    var promise = adapter.findBelongsTo(store, snapshot, link, relationship);
77536    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, relationship.type);
77537    var label = "DS: Handle Adapter#findBelongsTo of " + internalModel + " : " + relationship.type;
77538
77539    promise = Promise.resolve(promise, label);
77540    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77541    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, internalModel));
77542
77543    return promise.then(function (adapterPayload) {
77544      return store._adapterRun(function () {
77545        var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findBelongsTo');
77546
77547        if (!payload.data) {
77548          return null;
77549        }
77550
77551        //TODO Optimize
77552        var record = store.push(payload);
77553        return record._internalModel;
77554      });
77555    }, null, "DS: Extract payload of " + internalModel + " : " + relationship.type);
77556  }
77557
77558  function _findAll(adapter, store, typeClass, sinceToken, options) {
77559    var modelName = typeClass.modelName;
77560    var recordArray = store.peekAll(modelName);
77561    var snapshotArray = recordArray.createSnapshot(options);
77562    var promise = adapter.findAll(store, typeClass, sinceToken, snapshotArray);
77563    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
77564    var label = "DS: Handle Adapter#findAll of " + typeClass;
77565
77566    promise = Promise.resolve(promise, label);
77567    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77568
77569    return promise.then(function (adapterPayload) {
77570      (0, _emberDataPrivateDebug.assert)("You made a `findAll` request for " + typeClass.modelName + " records, but the adapter's response did not have any data", payloadIsNotBlank(adapterPayload));
77571      store._adapterRun(function () {
77572        var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findAll');
77573        //TODO Optimize
77574        store.push(payload);
77575      });
77576
77577      store.didUpdateAll(typeClass);
77578      return store.peekAll(modelName);
77579    }, null, "DS: Extract payload of findAll " + typeClass);
77580  }
77581
77582  function _query(adapter, store, typeClass, query, recordArray) {
77583    var modelName = typeClass.modelName;
77584    var promise = adapter.query(store, typeClass, query, recordArray);
77585
77586    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
77587    var label = "DS: Handle Adapter#query of " + typeClass;
77588
77589    promise = Promise.resolve(promise, label);
77590    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77591
77592    return promise.then(function (adapterPayload) {
77593      var records, payload;
77594      store._adapterRun(function () {
77595        payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'query');
77596        //TODO Optimize
77597        records = store.push(payload);
77598      });
77599
77600      (0, _emberDataPrivateDebug.assert)('The response to store.query is expected to be an array but it was a single record. Please wrap your response in an array or use `store.queryRecord` to query for a single record.', Array.isArray(records));
77601      recordArray.loadRecords(records, payload);
77602      return recordArray;
77603    }, null, "DS: Extract payload of query " + typeClass);
77604  }
77605
77606  function _queryRecord(adapter, store, typeClass, query) {
77607    var modelName = typeClass.modelName;
77608    var promise = adapter.queryRecord(store, typeClass, query);
77609    var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
77610    var label = "DS: Handle Adapter#queryRecord of " + typeClass;
77611
77612    promise = Promise.resolve(promise, label);
77613    promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
77614
77615    return promise.then(function (adapterPayload) {
77616      var record;
77617      store._adapterRun(function () {
77618        var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'queryRecord');
77619
77620        (0, _emberDataPrivateDebug.assert)("Expected the primary data returned by the serializer for a `queryRecord` response to be a single object or null but instead it was an array.", !Array.isArray(payload.data), {
77621          id: 'ds.store.queryRecord-array-response'
77622        });
77623
77624        //TODO Optimize
77625        record = store.push(payload);
77626      });
77627
77628      return record;
77629    }, null, "DS: Extract payload of queryRecord " + typeClass);
77630  }
77631});
77632define('ember-data/-private/system/store/serializer-response', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
77633  'use strict';
77634
77635  exports.validateDocumentStructure = validateDocumentStructure;
77636  exports.normalizeResponseHelper = normalizeResponseHelper;
77637
77638  /*
77639    This is a helper method that validates a JSON API top-level document
77640  
77641    The format of a document is described here:
77642    http://jsonapi.org/format/#document-top-level
77643  
77644    @method validateDocumentStructure
77645    @param {Object} doc JSON API document
77646    @return {array} An array of errors found in the document structure
77647  */
77648
77649  function validateDocumentStructure(doc) {
77650    var errors = [];
77651    if (!doc || typeof doc !== 'object') {
77652      errors.push('Top level of a JSON API document must be an object');
77653    } else {
77654      if (!('data' in doc) && !('errors' in doc) && !('meta' in doc)) {
77655        errors.push('One or more of the following keys must be present: "data", "errors", "meta".');
77656      } else {
77657        if ('data' in doc && 'errors' in doc) {
77658          errors.push('Top level keys "errors" and "data" cannot both be present in a JSON API document');
77659        }
77660      }
77661      if ('data' in doc) {
77662        if (!(doc.data === null || Array.isArray(doc.data) || typeof doc.data === 'object')) {
77663          errors.push('data must be null, an object, or an array');
77664        }
77665      }
77666      if ('meta' in doc) {
77667        if (typeof doc.meta !== 'object') {
77668          errors.push('meta must be an object');
77669        }
77670      }
77671      if ('errors' in doc) {
77672        if (!Array.isArray(doc.errors)) {
77673          errors.push('errors must be an array');
77674        }
77675      }
77676      if ('links' in doc) {
77677        if (typeof doc.links !== 'object') {
77678          errors.push('links must be an object');
77679        }
77680      }
77681      if ('jsonapi' in doc) {
77682        if (typeof doc.jsonapi !== 'object') {
77683          errors.push('jsonapi must be an object');
77684        }
77685      }
77686      if ('included' in doc) {
77687        if (typeof doc.included !== 'object') {
77688          errors.push('included must be an array');
77689        }
77690      }
77691    }
77692
77693    return errors;
77694  }
77695
77696  /*
77697    This is a helper method that always returns a JSON-API Document.
77698  
77699    @method normalizeResponseHelper
77700    @param {DS.Serializer} serializer
77701    @param {DS.Store} store
77702    @param {subclass of DS.Model} modelClass
77703    @param {Object} payload
77704    @param {String|Number} id
77705    @param {String} requestType
77706    @return {Object} JSON-API Document
77707  */
77708
77709  function normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
77710    var normalizedResponse = serializer.normalizeResponse(store, modelClass, payload, id, requestType);
77711    var validationErrors = [];
77712    (0, _emberDataPrivateDebug.runInDebug)(function () {
77713      validationErrors = validateDocumentStructure(normalizedResponse);
77714    });
77715    (0, _emberDataPrivateDebug.assert)('normalizeResponse must return a valid JSON API document:\n\t* ' + validationErrors.join('\n\t* '), _ember['default'].isEmpty(validationErrors));
77716
77717    return normalizedResponse;
77718  }
77719});
77720define("ember-data/-private/system/store/serializers", ["exports"], function (exports) {
77721  "use strict";
77722
77723  exports.serializerForAdapter = serializerForAdapter;
77724
77725  function serializerForAdapter(store, adapter, type) {
77726    var serializer = adapter.serializer;
77727
77728    if (serializer === undefined) {
77729      serializer = store.serializerFor(type);
77730    }
77731
77732    if (serializer === null || serializer === undefined) {
77733      serializer = {
77734        extract: function extract(store, type, payload) {
77735          return payload;
77736        }
77737      };
77738    }
77739
77740    return serializer;
77741  }
77742});
77743define("ember-data/-private/transforms", ["exports", "ember-data/transform", "ember-data/-private/transforms/number", "ember-data/-private/transforms/date", "ember-data/-private/transforms/string", "ember-data/-private/transforms/boolean"], function (exports, _emberDataTransform, _emberDataPrivateTransformsNumber, _emberDataPrivateTransformsDate, _emberDataPrivateTransformsString, _emberDataPrivateTransformsBoolean) {
77744  "use strict";
77745
77746  exports.Transform = _emberDataTransform["default"];
77747  exports.NumberTransform = _emberDataPrivateTransformsNumber["default"];
77748  exports.DateTransform = _emberDataPrivateTransformsDate["default"];
77749  exports.StringTransform = _emberDataPrivateTransformsString["default"];
77750  exports.BooleanTransform = _emberDataPrivateTransformsBoolean["default"];
77751});
77752define('ember-data/-private/transforms/boolean', ['exports', 'ember', 'ember-data/transform', 'ember-data/-private/features'], function (exports, _ember, _emberDataTransform, _emberDataPrivateFeatures) {
77753  'use strict';
77754
77755  var isNone = _ember['default'].isNone;
77756
77757  /**
77758    The `DS.BooleanTransform` class is used to serialize and deserialize
77759    boolean attributes on Ember Data record objects. This transform is
77760    used when `boolean` is passed as the type parameter to the
77761    [DS.attr](../../data#method_attr) function.
77762  
77763    Usage
77764  
77765    ```app/models/user.js
77766    import DS from 'ember-data';
77767  
77768    export default DS.Model.extend({
77769      isAdmin: DS.attr('boolean'),
77770      name: DS.attr('string'),
77771      email: DS.attr('string')
77772    });
77773    ```
77774  
77775    @class BooleanTransform
77776    @extends DS.Transform
77777    @namespace DS
77778   */
77779  exports['default'] = _emberDataTransform['default'].extend({
77780    deserialize: function deserialize(serialized, options) {
77781      var type = typeof serialized;
77782
77783      if (true) {
77784        if (isNone(serialized) && options.allowNull === true) {
77785          return null;
77786        }
77787      }
77788
77789      if (type === "boolean") {
77790        return serialized;
77791      } else if (type === "string") {
77792        return serialized.match(/^true$|^t$|^1$/i) !== null;
77793      } else if (type === "number") {
77794        return serialized === 1;
77795      } else {
77796        return false;
77797      }
77798    },
77799
77800    serialize: function serialize(deserialized, options) {
77801      if (true) {
77802        if (isNone(deserialized) && options.allowNull === true) {
77803          return null;
77804        }
77805      }
77806
77807      return Boolean(deserialized);
77808    }
77809  });
77810});
77811define("ember-data/-private/transforms/date", ["exports", "ember-data/-private/ext/date", "ember-data/transform"], function (exports, _emberDataPrivateExtDate, _emberDataTransform) {
77812  "use strict";
77813
77814  exports["default"] = _emberDataTransform["default"].extend({
77815    deserialize: function deserialize(serialized) {
77816      var type = typeof serialized;
77817
77818      if (type === "string") {
77819        return new Date((0, _emberDataPrivateExtDate.parseDate)(serialized));
77820      } else if (type === "number") {
77821        return new Date(serialized);
77822      } else if (serialized === null || serialized === undefined) {
77823        // if the value is null return null
77824        // if the value is not present in the data return undefined
77825        return serialized;
77826      } else {
77827        return null;
77828      }
77829    },
77830
77831    serialize: function serialize(date) {
77832      if (date instanceof Date) {
77833        return date.toISOString();
77834      } else {
77835        return null;
77836      }
77837    }
77838  });
77839});
77840
77841/**
77842  The `DS.DateTransform` class is used to serialize and deserialize
77843  date attributes on Ember Data record objects. This transform is used
77844  when `date` is passed as the type parameter to the
77845  [DS.attr](../../data#method_attr) function.
77846
77847  ```app/models/score.js
77848  import DS from 'ember-data';
77849
77850  export default DS.Model.extend({
77851    value: DS.attr('number'),
77852    player: DS.belongsTo('player'),
77853    date: DS.attr('date')
77854  });
77855  ```
77856
77857  @class DateTransform
77858  @extends DS.Transform
77859  @namespace DS
77860 */
77861define("ember-data/-private/transforms/number", ["exports", "ember", "ember-data/transform"], function (exports, _ember, _emberDataTransform) {
77862  "use strict";
77863
77864  var empty = _ember["default"].isEmpty;
77865
77866  function isNumber(value) {
77867    return value === value && value !== Infinity && value !== -Infinity;
77868  }
77869
77870  /**
77871    The `DS.NumberTransform` class is used to serialize and deserialize
77872    numeric attributes on Ember Data record objects. This transform is
77873    used when `number` is passed as the type parameter to the
77874    [DS.attr](../../data#method_attr) function.
77875  
77876    Usage
77877  
77878    ```app/models/score.js
77879    import DS from 'ember-data';
77880  
77881    export default DS.Model.extend({
77882      value: DS.attr('number'),
77883      player: DS.belongsTo('player'),
77884      date: DS.attr('date')
77885    });
77886    ```
77887  
77888    @class NumberTransform
77889    @extends DS.Transform
77890    @namespace DS
77891   */
77892  exports["default"] = _emberDataTransform["default"].extend({
77893    deserialize: function deserialize(serialized) {
77894      var transformed;
77895
77896      if (empty(serialized)) {
77897        return null;
77898      } else {
77899        transformed = Number(serialized);
77900
77901        return isNumber(transformed) ? transformed : null;
77902      }
77903    },
77904
77905    serialize: function serialize(deserialized) {
77906      var transformed;
77907
77908      if (empty(deserialized)) {
77909        return null;
77910      } else {
77911        transformed = Number(deserialized);
77912
77913        return isNumber(transformed) ? transformed : null;
77914      }
77915    }
77916  });
77917});
77918define("ember-data/-private/transforms/string", ["exports", "ember", "ember-data/transform"], function (exports, _ember, _emberDataTransform) {
77919  "use strict";
77920
77921  var none = _ember["default"].isNone;
77922
77923  /**
77924    The `DS.StringTransform` class is used to serialize and deserialize
77925    string attributes on Ember Data record objects. This transform is
77926    used when `string` is passed as the type parameter to the
77927    [DS.attr](../../data#method_attr) function.
77928  
77929    Usage
77930  
77931    ```app/models/user.js
77932    import DS from 'ember-data';
77933  
77934    export default DS.Model.extend({
77935      isAdmin: DS.attr('boolean'),
77936      name: DS.attr('string'),
77937      email: DS.attr('string')
77938    });
77939    ```
77940  
77941    @class StringTransform
77942    @extends DS.Transform
77943    @namespace DS
77944   */
77945  exports["default"] = _emberDataTransform["default"].extend({
77946    deserialize: function deserialize(serialized) {
77947      return none(serialized) ? null : String(serialized);
77948    },
77949    serialize: function serialize(deserialized) {
77950      return none(deserialized) ? null : String(deserialized);
77951    }
77952  });
77953});
77954define('ember-data/-private/utils', ['exports', 'ember'], function (exports, _ember) {
77955  'use strict';
77956
77957  var get = _ember['default'].get;
77958
77959  /**
77960    Check if the passed model has a `type` attribute or a relationship named `type`.
77961  
77962    @method modelHasAttributeOrRelationshipNamedType
77963    @param modelClass
77964   */
77965  function modelHasAttributeOrRelationshipNamedType(modelClass) {
77966    return get(modelClass, 'attributes').has('type') || get(modelClass, 'relationshipsByName').has('type');
77967  }
77968
77969  /*
77970    ember-container-inject-owner is a new feature in Ember 2.3 that finally provides a public
77971    API for looking items up.  This function serves as a super simple polyfill to avoid
77972    triggering deprecations.
77973  */
77974  function getOwner(context) {
77975    var owner;
77976
77977    if (_ember['default'].getOwner) {
77978      owner = _ember['default'].getOwner(context);
77979    }
77980
77981    if (!owner && context.container) {
77982      owner = context.container;
77983    }
77984
77985    if (owner && owner.lookupFactory && !owner._lookupFactory) {
77986      // `owner` is a container, we are just making this work
77987      owner._lookupFactory = owner.lookupFactory;
77988      owner.register = function () {
77989        var registry = owner.registry || owner._registry || owner;
77990
77991        return registry.register.apply(registry, arguments);
77992      };
77993    }
77994
77995    return owner;
77996  }
77997
77998  exports.modelHasAttributeOrRelationshipNamedType = modelHasAttributeOrRelationshipNamedType;
77999  exports.getOwner = getOwner;
78000});
78001define('ember-data/-private/utils/parse-response-headers', ['exports', 'ember-data/-private/system/empty-object'], function (exports, _emberDataPrivateSystemEmptyObject) {
78002  'use strict';
78003
78004  exports['default'] = parseResponseHeaders;
78005
78006  function _toArray(arr) {
78007    return Array.isArray(arr) ? arr : Array.from(arr);
78008  }
78009
78010  var CLRF = '\r\n';
78011  function parseResponseHeaders(headersString) {
78012    var headers = new _emberDataPrivateSystemEmptyObject['default']();
78013
78014    if (!headersString) {
78015      return headers;
78016    }
78017
78018    var headerPairs = headersString.split(CLRF);
78019
78020    headerPairs.forEach(function (header) {
78021      var _header$split = header.split(':');
78022
78023      var _header$split2 = _toArray(_header$split);
78024
78025      var field = _header$split2[0];
78026
78027      var value = _header$split2.slice(1);
78028
78029      field = field.trim();
78030      value = value.join(':').trim();
78031
78032      if (value) {
78033        headers[field] = value;
78034      }
78035    });
78036
78037    return headers;
78038  }
78039});
78040define('ember-data/adapter', ['exports', 'ember'], function (exports, _ember) {
78041  /**
78042    @module ember-data
78043  */
78044
78045  'use strict';
78046
78047  var get = _ember['default'].get;
78048
78049  /**
78050    An adapter is an object that receives requests from a store and
78051    translates them into the appropriate action to take against your
78052    persistence layer. The persistence layer is usually an HTTP API, but
78053    may be anything, such as the browser's local storage. Typically the
78054    adapter is not invoked directly instead its functionality is accessed
78055    through the `store`.
78056  
78057    ### Creating an Adapter
78058  
78059    Create a new subclass of `DS.Adapter` in the `app/adapters` folder:
78060  
78061    ```app/adapters/application.js
78062    import DS from 'ember-data';
78063  
78064    export default DS.Adapter.extend({
78065      // ...your code here
78066    });
78067    ```
78068  
78069    Model-specific adapters can be created by putting your adapter
78070    class in an `app/adapters/` + `model-name` + `.js` file of the application.
78071  
78072    ```app/adapters/post.js
78073    import DS from 'ember-data';
78074  
78075    export default DS.Adapter.extend({
78076      // ...Post-specific adapter code goes here
78077    });
78078    ```
78079  
78080    `DS.Adapter` is an abstract base class that you should override in your
78081    application to customize it for your backend. The minimum set of methods
78082    that you should implement is:
78083  
78084      * `findRecord()`
78085      * `createRecord()`
78086      * `updateRecord()`
78087      * `deleteRecord()`
78088      * `findAll()`
78089      * `query()`
78090  
78091    To improve the network performance of your application, you can optimize
78092    your adapter by overriding these lower-level methods:
78093  
78094      * `findMany()`
78095  
78096  
78097    For an example implementation, see `DS.RESTAdapter`, the
78098    included REST adapter.
78099  
78100    @class Adapter
78101    @namespace DS
78102    @extends Ember.Object
78103  */
78104
78105  exports['default'] = _ember['default'].Object.extend({
78106
78107    /**
78108      If you would like your adapter to use a custom serializer you can
78109      set the `defaultSerializer` property to be the name of the custom
78110      serializer.
78111       Note the `defaultSerializer` serializer has a lower priority than
78112      a model specific serializer (i.e. `PostSerializer`) or the
78113      `application` serializer.
78114       ```app/adapters/django.js
78115      import DS from 'ember-data';
78116       export default DS.Adapter.extend({
78117        defaultSerializer: 'django'
78118      });
78119      ```
78120       @property defaultSerializer
78121      @type {String}
78122    */
78123    defaultSerializer: '-default',
78124
78125    /**
78126      The `findRecord()` method is invoked when the store is asked for a record that
78127      has not previously been loaded. In response to `findRecord()` being called, you
78128      should query your persistence layer for a record with the given ID. The `findRecord`
78129      method should return a promise that will resolve to a JavaScript object that will be
78130      normalized by the serializer.
78131       Here is an example `findRecord` implementation:
78132       ```app/adapters/application.js
78133      import DS from 'ember-data';
78134       export default DS.Adapter.extend({
78135        findRecord: function(store, type, id, snapshot) {
78136          var url = [type.modelName, id].join('/');
78137           return new Ember.RSVP.Promise(function(resolve, reject) {
78138            Ember.$.getJSON(url).then(function(data) {
78139              Ember.run(null, resolve, data);
78140            }, function(jqXHR) {
78141              jqXHR.then = null; // tame jQuery's ill mannered promises
78142              Ember.run(null, reject, jqXHR);
78143            });
78144          });
78145        }
78146      });
78147      ```
78148       @method findRecord
78149      @param {DS.Store} store
78150      @param {DS.Model} type
78151      @param {String} id
78152      @param {DS.Snapshot} snapshot
78153      @return {Promise} promise
78154    */
78155    findRecord: null,
78156
78157    /**
78158      The `findAll()` method is used to retrieve all records for a given type.
78159       Example
78160       ```app/adapters/application.js
78161      import DS from 'ember-data';
78162       export default DS.Adapter.extend({
78163        findAll: function(store, type, sinceToken) {
78164          var url = type;
78165          var query = { since: sinceToken };
78166          return new Ember.RSVP.Promise(function(resolve, reject) {
78167            Ember.$.getJSON(url, query).then(function(data) {
78168              Ember.run(null, resolve, data);
78169            }, function(jqXHR) {
78170              jqXHR.then = null; // tame jQuery's ill mannered promises
78171              Ember.run(null, reject, jqXHR);
78172            });
78173          });
78174        }
78175      });
78176      ```
78177       @method findAll
78178      @param {DS.Store} store
78179      @param {DS.Model} type
78180      @param {String} sinceToken
78181      @param {DS.SnapshotRecordArray} snapshotRecordArray
78182      @return {Promise} promise
78183    */
78184    findAll: null,
78185
78186    /**
78187      This method is called when you call `query` on the store.
78188       Example
78189       ```app/adapters/application.js
78190      import DS from 'ember-data';
78191       export default DS.Adapter.extend({
78192        query: function(store, type, query) {
78193          var url = type;
78194          return new Ember.RSVP.Promise(function(resolve, reject) {
78195            Ember.$.getJSON(url, query).then(function(data) {
78196              Ember.run(null, resolve, data);
78197            }, function(jqXHR) {
78198              jqXHR.then = null; // tame jQuery's ill mannered promises
78199              Ember.run(null, reject, jqXHR);
78200            });
78201          });
78202        }
78203      });
78204      ```
78205       @method query
78206      @param {DS.Store} store
78207      @param {DS.Model} type
78208      @param {Object} query
78209      @param {DS.AdapterPopulatedRecordArray} recordArray
78210      @return {Promise} promise
78211    */
78212    query: null,
78213
78214    /**
78215      The `queryRecord()` method is invoked when the store is asked for a single
78216      record through a query object.
78217       In response to `queryRecord()` being called, you should always fetch fresh
78218      data. Once found, you can asynchronously call the store's `push()` method
78219      to push the record into the store.
78220       Here is an example `queryRecord` implementation:
78221       Example
78222       ```app/adapters/application.js
78223      import DS from 'ember-data';
78224      import Ember from 'ember';
78225       export default DS.Adapter.extend(DS.BuildURLMixin, {
78226        queryRecord: function(store, type, query) {
78227          var urlForQueryRecord = this.buildURL(type.modelName, null, null, 'queryRecord', query);
78228           return new Ember.RSVP.Promise(function(resolve, reject) {
78229            Ember.$.getJSON(urlForQueryRecord, query).then(function(data) {
78230              Ember.run(null, resolve, data);
78231            }, function(jqXHR) {
78232              jqXHR.then = null; // tame jQuery's ill mannered promises
78233              Ember.run(null, reject, jqXHR);
78234            });
78235          });
78236        }
78237      });
78238      ```
78239       @method queryRecord
78240      @param {DS.Store} store
78241      @param {subclass of DS.Model} type
78242      @param {Object} query
78243      @return {Promise} promise
78244    */
78245    queryRecord: null,
78246
78247    /**
78248      If the globally unique IDs for your records should be generated on the client,
78249      implement the `generateIdForRecord()` method. This method will be invoked
78250      each time you create a new record, and the value returned from it will be
78251      assigned to the record's `primaryKey`.
78252       Most traditional REST-like HTTP APIs will not use this method. Instead, the ID
78253      of the record will be set by the server, and your adapter will update the store
78254      with the new ID when it calls `didCreateRecord()`. Only implement this method if
78255      you intend to generate record IDs on the client-side.
78256       The `generateIdForRecord()` method will be invoked with the requesting store as
78257      the first parameter and the newly created record as the second parameter:
78258       ```javascript
78259      generateIdForRecord: function(store, inputProperties) {
78260        var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
78261        return uuid;
78262      }
78263      ```
78264       @method generateIdForRecord
78265      @param {DS.Store} store
78266      @param {DS.Model} type   the DS.Model class of the record
78267      @param {Object} inputProperties a hash of properties to set on the
78268        newly created record.
78269      @return {(String|Number)} id
78270    */
78271    generateIdForRecord: null,
78272
78273    /**
78274      Proxies to the serializer's `serialize` method.
78275       Example
78276       ```app/adapters/application.js
78277      import DS from 'ember-data';
78278       export default DS.Adapter.extend({
78279        createRecord: function(store, type, snapshot) {
78280          var data = this.serialize(snapshot, { includeId: true });
78281          var url = type;
78282           // ...
78283        }
78284      });
78285      ```
78286       @method serialize
78287      @param {DS.Snapshot} snapshot
78288      @param {Object}   options
78289      @return {Object} serialized snapshot
78290    */
78291    serialize: function serialize(snapshot, options) {
78292      return get(snapshot.record, 'store').serializerFor(snapshot.modelName).serialize(snapshot, options);
78293    },
78294
78295    /**
78296      Implement this method in a subclass to handle the creation of
78297      new records.
78298       Serializes the record and sends it to the server.
78299       Example
78300       ```app/adapters/application.js
78301      import DS from 'ember-data';
78302       export default DS.Adapter.extend({
78303        createRecord: function(store, type, snapshot) {
78304          var data = this.serialize(snapshot, { includeId: true });
78305          var url = type;
78306           return new Ember.RSVP.Promise(function(resolve, reject) {
78307            Ember.$.ajax({
78308              type: 'POST',
78309              url: url,
78310              dataType: 'json',
78311              data: data
78312            }).then(function(data) {
78313              Ember.run(null, resolve, data);
78314            }, function(jqXHR) {
78315              jqXHR.then = null; // tame jQuery's ill mannered promises
78316              Ember.run(null, reject, jqXHR);
78317            });
78318          });
78319        }
78320      });
78321      ```
78322       @method createRecord
78323      @param {DS.Store} store
78324      @param {DS.Model} type   the DS.Model class of the record
78325      @param {DS.Snapshot} snapshot
78326      @return {Promise} promise
78327    */
78328    createRecord: null,
78329
78330    /**
78331      Implement this method in a subclass to handle the updating of
78332      a record.
78333       Serializes the record update and sends it to the server.
78334       The updateRecord method is expected to return a promise that will
78335      resolve with the serialized record. This allows the backend to
78336      inform the Ember Data store the current state of this record after
78337      the update. If it is not possible to return a serialized record
78338      the updateRecord promise can also resolve with `undefined` and the
78339      Ember Data store will assume all of the updates were successfully
78340      applied on the backend.
78341       Example
78342       ```app/adapters/application.js
78343      import DS from 'ember-data';
78344       export default DS.Adapter.extend({
78345        updateRecord: function(store, type, snapshot) {
78346          var data = this.serialize(snapshot, { includeId: true });
78347          var id = snapshot.id;
78348          var url = [type, id].join('/');
78349           return new Ember.RSVP.Promise(function(resolve, reject) {
78350            Ember.$.ajax({
78351              type: 'PUT',
78352              url: url,
78353              dataType: 'json',
78354              data: data
78355            }).then(function(data) {
78356              Ember.run(null, resolve, data);
78357            }, function(jqXHR) {
78358              jqXHR.then = null; // tame jQuery's ill mannered promises
78359              Ember.run(null, reject, jqXHR);
78360            });
78361          });
78362        }
78363      });
78364      ```
78365       @method updateRecord
78366      @param {DS.Store} store
78367      @param {DS.Model} type   the DS.Model class of the record
78368      @param {DS.Snapshot} snapshot
78369      @return {Promise} promise
78370    */
78371    updateRecord: null,
78372
78373    /**
78374      Implement this method in a subclass to handle the deletion of
78375      a record.
78376       Sends a delete request for the record to the server.
78377       Example
78378       ```app/adapters/application.js
78379      import DS from 'ember-data';
78380       export default DS.Adapter.extend({
78381        deleteRecord: function(store, type, snapshot) {
78382          var data = this.serialize(snapshot, { includeId: true });
78383          var id = snapshot.id;
78384          var url = [type, id].join('/');
78385           return new Ember.RSVP.Promise(function(resolve, reject) {
78386            Ember.$.ajax({
78387              type: 'DELETE',
78388              url: url,
78389              dataType: 'json',
78390              data: data
78391            }).then(function(data) {
78392              Ember.run(null, resolve, data);
78393            }, function(jqXHR) {
78394              jqXHR.then = null; // tame jQuery's ill mannered promises
78395              Ember.run(null, reject, jqXHR);
78396            });
78397          });
78398        }
78399      });
78400      ```
78401       @method deleteRecord
78402      @param {DS.Store} store
78403      @param {DS.Model} type   the DS.Model class of the record
78404      @param {DS.Snapshot} snapshot
78405      @return {Promise} promise
78406    */
78407    deleteRecord: null,
78408
78409    /**
78410      By default the store will try to coalesce all `fetchRecord` calls within the same runloop
78411      into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call.
78412      You can opt out of this behaviour by either not implementing the findMany hook or by setting
78413      coalesceFindRequests to false.
78414       @property coalesceFindRequests
78415      @type {boolean}
78416    */
78417    coalesceFindRequests: true,
78418
78419    /**
78420      Find multiple records at once if coalesceFindRequests is true.
78421       @method findMany
78422      @param {DS.Store} store
78423      @param {DS.Model} type   the DS.Model class of the records
78424      @param {Array}    ids
78425      @param {Array} snapshots
78426      @return {Promise} promise
78427    */
78428    findMany: null,
78429
78430    /**
78431      Organize records into groups, each of which is to be passed to separate
78432      calls to `findMany`.
78433       For example, if your api has nested URLs that depend on the parent, you will
78434      want to group records by their parent.
78435       The default implementation returns the records as a single group.
78436       @method groupRecordsForFindMany
78437      @param {DS.Store} store
78438      @param {Array} snapshots
78439      @return {Array}  an array of arrays of records, each of which is to be
78440                        loaded separately by `findMany`.
78441    */
78442    groupRecordsForFindMany: function groupRecordsForFindMany(store, snapshots) {
78443      return [snapshots];
78444    },
78445
78446    /**
78447      This method is used by the store to determine if the store should
78448      reload a record from the adapter when a record is requested by
78449      `store.findRecord`.
78450       If this method returns `true`, the store will re-fetch a record from
78451      the adapter. If this method returns `false`, the store will resolve
78452      immediately using the cached record.
78453       For example, if you are building an events ticketing system, in which users
78454      can only reserve tickets for 20 minutes at a time, and want to ensure that
78455      in each route you have data that is no more than 20 minutes old you could
78456      write:
78457       ```javascript
78458      shouldReloadRecord: function(store, ticketSnapshot) {
78459        var timeDiff = moment().diff(ticketSnapshot.attr('lastAccessedAt')).minutes();
78460        if (timeDiff > 20) {
78461          return true;
78462        } else {
78463          return false;
78464        }
78465      }
78466      ```
78467       This method would ensure that whenever you do `store.findRecord('ticket',
78468      id)` you will always get a ticket that is no more than 20 minutes old. In
78469      case the cached version is more than 20 minutes old, `findRecord` will not
78470      resolve until you fetched the latest version.
78471       By default this hook returns `false`, as most UIs should not block user
78472      interactions while waiting on data update.
78473       @since 1.13.0
78474      @method shouldReloadRecord
78475      @param {DS.Store} store
78476      @param {DS.Snapshot} snapshot
78477      @return {Boolean}
78478    */
78479    shouldReloadRecord: function shouldReloadRecord(store, snapshot) {
78480      return false;
78481    },
78482
78483    /**
78484      This method is used by the store to determine if the store should
78485      reload all records from the adapter when records are requested by
78486      `store.findAll`.
78487       If this method returns `true`, the store will re-fetch all records from
78488      the adapter. If this method returns `false`, the store will resolve
78489      immediately using the cached records.
78490       For example, if you are building an events ticketing system, in which users
78491      can only reserve tickets for 20 minutes at a time, and want to ensure that
78492      in each route you have data that is no more than 20 minutes old you could
78493      write:
78494       ```javascript
78495      shouldReloadAll: function(store, snapshotArray) {
78496        var snapshots = snapshotArray.snapshots();
78497         return snapshots.any(function(ticketSnapshot) {
78498          var timeDiff = moment().diff(ticketSnapshot.attr('lastAccessedAt')).minutes();
78499          if (timeDiff > 20) {
78500            return true;
78501          } else {
78502            return false;
78503          }
78504        });
78505      }
78506      ```
78507       This method would ensure that whenever you do `store.findAll('ticket')` you
78508      will always get a list of tickets that are no more than 20 minutes old. In
78509      case a cached version is more than 20 minutes old, `findAll` will not
78510      resolve until you fetched the latest versions.
78511       By default this methods returns `true` if the passed `snapshotRecordArray`
78512      is empty (meaning that there are no records locally available yet),
78513      otherwise it returns `false`.
78514       @since 1.13.0
78515      @method shouldReloadAll
78516      @param {DS.Store} store
78517      @param {DS.SnapshotRecordArray} snapshotRecordArray
78518      @return {Boolean}
78519    */
78520    shouldReloadAll: function shouldReloadAll(store, snapshotRecordArray) {
78521      return !snapshotRecordArray.length;
78522    },
78523
78524    /**
78525      This method is used by the store to determine if the store should
78526      reload a record after the `store.findRecord` method resolves a
78527      cached record.
78528       This method is *only* checked by the store when the store is
78529      returning a cached record.
78530       If this method returns `true` the store will re-fetch a record from
78531      the adapter.
78532       For example, if you do not want to fetch complex data over a mobile
78533      connection, or if the network is down, you can implement
78534      `shouldBackgroundReloadRecord` as follows:
78535       ```javascript
78536      shouldBackgroundReloadRecord: function(store, snapshot) {
78537        var connection = window.navigator.connection;
78538        if (connection === 'cellular' || connection === 'none') {
78539          return false;
78540        } else {
78541          return true;
78542        }
78543      }
78544      ```
78545       By default this hook returns `true` so the data for the record is updated
78546      in the background.
78547       @since 1.13.0
78548      @method shouldBackgroundReloadRecord
78549      @param {DS.Store} store
78550      @param {DS.Snapshot} snapshot
78551      @return {Boolean}
78552    */
78553    shouldBackgroundReloadRecord: function shouldBackgroundReloadRecord(store, snapshot) {
78554      return true;
78555    },
78556
78557    /**
78558      This method is used by the store to determine if the store should
78559      reload a record array after the `store.findAll` method resolves
78560      with a cached record array.
78561       This method is *only* checked by the store when the store is
78562      returning a cached record array.
78563       If this method returns `true` the store will re-fetch all records
78564      from the adapter.
78565       For example, if you do not want to fetch complex data over a mobile
78566      connection, or if the network is down, you can implement
78567      `shouldBackgroundReloadAll` as follows:
78568       ```javascript
78569      shouldBackgroundReloadAll: function(store, snapshotArray) {
78570        var connection = window.navigator.connection;
78571        if (connection === 'cellular' || connection === 'none') {
78572          return false;
78573        } else {
78574          return true;
78575        }
78576      }
78577      ```
78578       By default this method returns `true`, indicating that a background reload
78579      should always be triggered.
78580       @since 1.13.0
78581      @method shouldBackgroundReloadAll
78582      @param {DS.Store} store
78583      @param {DS.SnapshotRecordArray} snapshotRecordArray
78584      @return {Boolean}
78585    */
78586    shouldBackgroundReloadAll: function shouldBackgroundReloadAll(store, snapshotRecordArray) {
78587      return true;
78588    }
78589  });
78590});
78591define('ember-data/adapters/errors', ['exports', 'ember', 'ember-data/-private/debug', 'ember-data/-private/features'], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateFeatures) {
78592  'use strict';
78593
78594  exports.AdapterError = AdapterError;
78595  exports.errorsHashToArray = errorsHashToArray;
78596  exports.errorsArrayToHash = errorsArrayToHash;
78597
78598  var EmberError = _ember['default'].Error;
78599
78600  var SOURCE_POINTER_REGEXP = /^\/?data\/(attributes|relationships)\/(.*)/;
78601  var SOURCE_POINTER_PRIMARY_REGEXP = /^\/?data/;
78602  var PRIMARY_ATTRIBUTE_KEY = 'base';
78603
78604  /**
78605    @class AdapterError
78606    @namespace DS
78607  */
78608
78609  function AdapterError(errors) {
78610    var message = arguments.length <= 1 || arguments[1] === undefined ? 'Adapter operation failed' : arguments[1];
78611
78612    this.isAdapterError = true;
78613    EmberError.call(this, message);
78614
78615    this.errors = errors || [{
78616      title: 'Adapter Error',
78617      detail: message
78618    }];
78619  }
78620
78621  var extendedErrorsEnabled = false;
78622  if (false) {
78623    extendedErrorsEnabled = true;
78624  }
78625
78626  function extendFn(ErrorClass) {
78627    return function () {
78628      var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
78629
78630      var defaultMessage = _ref.message;
78631
78632      return extend(ErrorClass, defaultMessage);
78633    };
78634  }
78635
78636  function extend(ParentErrorClass, defaultMessage) {
78637    var ErrorClass = function ErrorClass(errors, message) {
78638      (0, _emberDataPrivateDebug.assert)('`AdapterError` expects json-api formatted errors array.', Array.isArray(errors || []));
78639      ParentErrorClass.call(this, errors, message || defaultMessage);
78640    };
78641    ErrorClass.prototype = Object.create(ParentErrorClass.prototype);
78642
78643    if (extendedErrorsEnabled) {
78644      ErrorClass.extend = extendFn(ErrorClass);
78645    }
78646
78647    return ErrorClass;
78648  }
78649
78650  AdapterError.prototype = Object.create(EmberError.prototype);
78651
78652  if (extendedErrorsEnabled) {
78653    AdapterError.extend = extendFn(AdapterError);
78654  }
78655
78656  /**
78657    A `DS.InvalidError` is used by an adapter to signal the external API
78658    was unable to process a request because the content was not
78659    semantically correct or meaningful per the API. Usually this means a
78660    record failed some form of server side validation. When a promise
78661    from an adapter is rejected with a `DS.InvalidError` the record will
78662    transition to the `invalid` state and the errors will be set to the
78663    `errors` property on the record.
78664  
78665    For Ember Data to correctly map errors to their corresponding
78666    properties on the model, Ember Data expects each error to be
78667    a valid json-api error object with a `source/pointer` that matches
78668    the property name. For example if you had a Post model that
78669    looked like this.
78670  
78671    ```app/models/post.js
78672    import DS from 'ember-data';
78673  
78674    export default DS.Model.extend({
78675      title: DS.attr('string'),
78676      content: DS.attr('string')
78677    });
78678    ```
78679  
78680    To show an error from the server related to the `title` and
78681    `content` properties your adapter could return a promise that
78682    rejects with a `DS.InvalidError` object that looks like this:
78683  
78684    ```app/adapters/post.js
78685    import Ember from 'ember';
78686    import DS from 'ember-data';
78687  
78688    export default DS.RESTAdapter.extend({
78689      updateRecord: function() {
78690        // Fictional adapter that always rejects
78691        return Ember.RSVP.reject(new DS.InvalidError([
78692          {
78693            detail: 'Must be unique',
78694            source: { pointer: '/data/attributes/title' }
78695          },
78696          {
78697            detail: 'Must not be blank',
78698            source: { pointer: '/data/attributes/content'}
78699          }
78700        ]));
78701      }
78702    });
78703    ```
78704  
78705    Your backend may use different property names for your records the
78706    store will attempt extract and normalize the errors using the
78707    serializer's `extractErrors` method before the errors get added to
78708    the the model. As a result, it is safe for the `InvalidError` to
78709    wrap the error payload unaltered.
78710  
78711    @class InvalidError
78712    @namespace DS
78713  */
78714  var InvalidError = extend(AdapterError, 'The adapter rejected the commit because it was invalid');
78715
78716  exports.InvalidError = InvalidError;
78717
78718  /**
78719    @class TimeoutError
78720    @namespace DS
78721  */
78722  var TimeoutError = extend(AdapterError, 'The adapter operation timed out');
78723
78724  exports.TimeoutError = TimeoutError;
78725
78726  /**
78727    @class AbortError
78728    @namespace DS
78729  */
78730  var AbortError = extend(AdapterError, 'The adapter operation was aborted');
78731
78732  exports.AbortError = AbortError;
78733
78734  /**
78735    @class UnauthorizedError
78736    @namespace DS
78737  */
78738  var UnauthorizedError = extendedErrorsEnabled ? extend(AdapterError, 'The adapter operation is unauthorized') : null;
78739
78740  exports.UnauthorizedError = UnauthorizedError;
78741
78742  /**
78743    @class ForbiddenError
78744    @namespace DS
78745  */
78746  var ForbiddenError = extendedErrorsEnabled ? extend(AdapterError, 'The adapter operation is forbidden') : null;
78747
78748  exports.ForbiddenError = ForbiddenError;
78749
78750  /**
78751    @class NotFoundError
78752    @namespace DS
78753  */
78754  var NotFoundError = extendedErrorsEnabled ? extend(AdapterError, 'The adapter could not find the resource') : null;
78755
78756  exports.NotFoundError = NotFoundError;
78757
78758  /**
78759    @class ConflictError
78760    @namespace DS
78761  */
78762  var ConflictError = extendedErrorsEnabled ? extend(AdapterError, 'The adapter operation failed due to a conflict') : null;
78763
78764  exports.ConflictError = ConflictError;
78765
78766  /**
78767    @class ServerError
78768    @namespace DS
78769  */
78770  var ServerError = extendedErrorsEnabled ? extend(AdapterError, 'The adapter operation failed due to a server error') : null;
78771
78772  exports.ServerError = ServerError;
78773
78774  /**
78775    @method errorsHashToArray
78776    @private
78777  */
78778
78779  function errorsHashToArray(errors) {
78780    var out = [];
78781
78782    if (_ember['default'].isPresent(errors)) {
78783      Object.keys(errors).forEach(function (key) {
78784        var messages = _ember['default'].makeArray(errors[key]);
78785        for (var i = 0; i < messages.length; i++) {
78786          var title = 'Invalid Attribute';
78787          var pointer = '/data/attributes/' + key;
78788          if (key === PRIMARY_ATTRIBUTE_KEY) {
78789            title = 'Invalid Document';
78790            pointer = '/data';
78791          }
78792          out.push({
78793            title: title,
78794            detail: messages[i],
78795            source: {
78796              pointer: pointer
78797            }
78798          });
78799        }
78800      });
78801    }
78802
78803    return out;
78804  }
78805
78806  /**
78807    @method errorsArrayToHash
78808    @private
78809  */
78810
78811  function errorsArrayToHash(errors) {
78812    var out = {};
78813
78814    if (_ember['default'].isPresent(errors)) {
78815      errors.forEach(function (error) {
78816        if (error.source && error.source.pointer) {
78817          var key = error.source.pointer.match(SOURCE_POINTER_REGEXP);
78818
78819          if (key) {
78820            key = key[2];
78821          } else if (error.source.pointer.search(SOURCE_POINTER_PRIMARY_REGEXP) !== -1) {
78822            key = PRIMARY_ATTRIBUTE_KEY;
78823          }
78824
78825          if (key) {
78826            out[key] = out[key] || [];
78827            out[key].push(error.detail || error.title);
78828          }
78829        }
78830      });
78831    }
78832
78833    return out;
78834  }
78835});
78836define('ember-data/adapters/json-api', ['exports', 'ember', 'ember-data/adapters/rest', 'ember-data/-private/features', 'ember-data/-private/debug'], function (exports, _ember, _emberDataAdaptersRest, _emberDataPrivateFeatures, _emberDataPrivateDebug) {
78837  /**
78838    @module ember-data
78839  */
78840
78841  'use strict';
78842
78843  /**
78844    @since 1.13.0
78845    @class JSONAPIAdapter
78846    @constructor
78847    @namespace DS
78848    @extends DS.RESTAdapter
78849  */
78850  var JSONAPIAdapter = _emberDataAdaptersRest['default'].extend({
78851    defaultSerializer: '-json-api',
78852
78853    /**
78854      @method ajaxOptions
78855      @private
78856      @param {String} url
78857      @param {String} type The request type GET, POST, PUT, DELETE etc.
78858      @param {Object} options
78859      @return {Object}
78860    */
78861    ajaxOptions: function ajaxOptions(url, type, options) {
78862      var hash = this._super.apply(this, arguments);
78863
78864      if (hash.contentType) {
78865        hash.contentType = 'application/vnd.api+json';
78866      }
78867
78868      var beforeSend = hash.beforeSend;
78869      hash.beforeSend = function (xhr) {
78870        xhr.setRequestHeader('Accept', 'application/vnd.api+json');
78871        if (beforeSend) {
78872          beforeSend(xhr);
78873        }
78874      };
78875
78876      return hash;
78877    },
78878
78879    /**
78880      By default the JSONAPIAdapter will send each find request coming from a `store.find`
78881      or from accessing a relationship separately to the server. If your server supports passing
78882      ids as a query string, you can set coalesceFindRequests to true to co
78882alesce all find requests
78883      within a single runloop.
78884       For example, if you have an initial payload of:
78885       ```javascript
78886      {
78887        post: {
78888          id: 1,
78889          comments: [1, 2]
78890        }
78891      }
78892      ```
78893       By default calling `post.get('comments')` will trigger the following requests(assuming the
78894      comments haven't been loaded before):
78895       ```
78896      GET /comments/1
78897      GET /comments/2
78898      ```
78899       If you set coalesceFindRequests to `true` it will instead trigger the following request:
78900       ```
78901      GET /comments?filter[id]=1,2
78902      ```
78903       Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo`
78904      relationships accessed within the same runloop. If you set `coalesceFindRequests: true`
78905       ```javascript
78906      store.findRecord('comment', 1);
78907      store.findRecord('comment', 2);
78908      ```
78909       will also send a request to: `GET /comments?filter[id]=1,2`
78910       Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app
78911      `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work.
78912       @property coalesceFindRequests
78913      @type {boolean}
78914    */
78915    coalesceFindRequests: false,
78916
78917    /**
78918      @method findMany
78919      @param {DS.Store} store
78920      @param {DS.Model} type
78921      @param {Array} ids
78922      @param {Array} snapshots
78923      @return {Promise} promise
78924    */
78925    findMany: function findMany(store, type, ids, snapshots) {
78926      if (false && !this._hasCustomizedAjax()) {
78927        return this._super.apply(this, arguments);
78928      } else {
78929        var url = this.buildURL(type.modelName, ids, snapshots, 'findMany');
78930        return this.ajax(url, 'GET', { data: { filter: { id: ids.join(',') } } });
78931      }
78932    },
78933
78934    /**
78935      @method pathForType
78936      @param {String} modelName
78937      @return {String} path
78938    **/
78939    pathForType: function pathForType(modelName) {
78940      var dasherized = _ember['default'].String.dasherize(modelName);
78941      return _ember['default'].String.pluralize(dasherized);
78942    },
78943
78944    // TODO: Remove this once we have a better way to override HTTP verbs.
78945    /**
78946      @method updateRecord
78947      @param {DS.Store} store
78948      @param {DS.Model} type
78949      @param {DS.Snapshot} snapshot
78950      @return {Promise} promise
78951    */
78952    updateRecord: function updateRecord(store, type, snapshot) {
78953      if (false && !this._hasCustomizedAjax()) {
78954        return this._super.apply(this, arguments);
78955      } else {
78956        var data = {};
78957        var serializer = store.serializerFor(type.modelName);
78958
78959        serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
78960
78961        var id = snapshot.id;
78962        var url = this.buildURL(type.modelName, id, snapshot, 'updateRecord');
78963
78964        return this.ajax(url, 'PATCH', { data: data });
78965      }
78966    },
78967
78968    _hasCustomizedAjax: function _hasCustomizedAjax() {
78969      if (this.ajax !== JSONAPIAdapter.prototype.ajax) {
78970        (0, _emberDataPrivateDebug.deprecate)('JSONAPIAdapter#ajax has been deprecated please use. `methodForRequest`, `urlForRequest`, `headersForRequest` or `dataForRequest` instead.', false, {
78971          id: 'ds.json-api-adapter.ajax',
78972          until: '3.0.0'
78973        });
78974        return true;
78975      }
78976
78977      if (this.ajaxOptions !== JSONAPIAdapter.prototype.ajaxOptions) {
78978        (0, _emberDataPrivateDebug.deprecate)('JSONAPIAdapterr#ajaxOptions has been deprecated please use. `methodForRequest`, `urlForRequest`, `headersForRequest` or `dataForRequest` instead.', false, {
78979          id: 'ds.json-api-adapter.ajax-options',
78980          until: '3.0.0'
78981        });
78982        return true;
78983      }
78984
78985      return false;
78986    }
78987  });
78988
78989  if (false) {
78990
78991    JSONAPIAdapter.reopen({
78992
78993      methodForRequest: function methodForRequest(params) {
78994        if (params.requestType === 'updateRecord') {
78995          return 'PATCH';
78996        }
78997
78998        return this._super.apply(this, arguments);
78999      },
79000
79001      dataForRequest: function dataForRequest(params) {
79002        var requestType = params.requestType;
79003        var ids = params.ids;
79004
79005        if (requestType === 'findMany') {
79006          return {
79007            filter: { id: ids.join(',') }
79008          };
79009        }
79010
79011        if (requestType === 'updateRecord') {
79012          var store = params.store;
79013          var type = params.type;
79014          var snapshot = params.snapshot;
79015
79016          var data = {};
79017          var serializer = store.serializerFor(type.modelName);
79018
79019          serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
79020
79021          return data;
79022        }
79023
79024        return this._super.apply(this, arguments);
79025      },
79026
79027      headersForRequest: function headersForRequest() {
79028        var headers = this._super.apply(this, arguments) || {};
79029
79030        headers['Accept'] = 'application/vnd.api+json';
79031
79032        return headers;
79033      },
79034
79035      _requestToJQueryAjaxHash: function _requestToJQueryAjaxHash() {
79036        var hash = this._super.apply(this, arguments);
79037
79038        if (hash.contentType) {
79039          hash.contentType = 'application/vnd.api+json';
79040        }
79041
79042        return hash;
79043      }
79044
79045    });
79046  }
79047
79048  exports['default'] = JSONAPIAdapter;
79049});
79050define('ember-data/adapters/rest', ['exports', 'ember', 'ember-data/adapter', 'ember-data/adapters/errors', 'ember-data/-private/adapters/build-url-mixin', 'ember-data/-private/features', 'ember-data/-private/debug', 'ember-data/-private/utils/parse-response-headers'], function (exports, _ember, _emberDataAdapter, _emberDataAdaptersErrors, _emberDataPrivateAdaptersBuildUrlMixin, _emberDataPrivateFeatures, _emberDataPrivateDebug, _emberDataPrivateUtilsParseResponseHeaders) {
79051  /**
79052    @module ember-data
79053  */
79054
79055  'use strict';
79056
79057  var MapWithDefault = _ember['default'].MapWithDefault;
79058  var get = _ember['default'].get;
79059
79060  /**
79061    The REST adapter allows your store to communicate with an HTTP server by
79062    transmitting JSON via XHR. Most Ember.js apps that consume a JSON API
79063    should use the REST adapter.
79064  
79065    This adapter is designed around the idea that the JSON exchanged with
79066    the server should be conventional.
79067  
79068    ## Success and failure
79069  
79070    The REST adapter will consider a success any response with a status code
79071    of the 2xx family ("Success"), as well as 304 ("Not Modified"). Any other
79072    status code will be considered a failure.
79073  
79074    On success, the request promise will be resolved with the full response
79075    payload.
79076  
79077    Failed responses with status code 422 ("Unprocessable Entity") will be
79078    considered "invalid". The response will be discarded, except for the
79079    `errors` key. The request promise will be rejected with a `DS.InvalidError`.
79080    This error object will encapsulate the saved `errors` value.
79081  
79082    Any other status codes will be treated as an "adapter error". The request
79083    promise will be rejected, similarly to the "invalid" case, but with
79084    an instance of `DS.AdapterError` instead.
79085  
79086    ## JSON Structure
79087  
79088    The REST adapter expects the JSON returned from your server to follow
79089    these conventions.
79090  
79091    ### Object Root
79092  
79093    The JSON payload should be an object that contains the record inside a
79094    root property. For example, in response to a `GET` request for
79095    `/posts/1`, the JSON should look like this:
79096  
79097    ```js
79098    {
79099      "post": {
79100        "id": 1,
79101        "title": "I'm Running to Reform the W3C's Tag",
79102        "author": "Yehuda Katz"
79103      }
79104    }
79105    ```
79106  
79107    Similarly, in response to a `GET` request for `/posts`, the JSON should
79108    look like this:
79109  
79110    ```js
79111    {
79112      "posts": [
79113        {
79114          "id": 1,
79115          "title": "I'm Running to Reform the W3C's Tag",
79116          "author": "Yehuda Katz"
79117        },
79118        {
79119          "id": 2,
79120          "title": "Rails is omakase",
79121          "author": "D2H"
79122        }
79123      ]
79124    }
79125    ```
79126  
79127    Note that the object root can be pluralized for both a single-object response
79128    and an array response: the REST adapter is not strict on this. Further, if the
79129    HTTP server responds to a `GET` request to `/posts/1` (e.g. the response to a
79130    `findRecord` query) with more than one object in the array, Ember Data will
79131    only display the object with the matching ID.
79132  
79133    ### Conventional Names
79134  
79135    Attribute names in your JSON payload should be the camelCased versions of
79136    the attributes in your Ember.js models.
79137  
79138    For example, if you have a `Person` model:
79139  
79140    ```app/models/person.js
79141    import DS from 'ember-data';
79142  
79143    export default DS.Model.extend({
79144      firstName: DS.attr('string'),
79145      lastName: DS.attr('string'),
79146      occupation: DS.attr('string')
79147    });
79148    ```
79149  
79150    The JSON returned should look like this:
79151  
79152    ```js
79153    {
79154      "person": {
79155        "id": 5,
79156        "firstName": "Barack",
79157        "lastName": "Obama",
79158        "occupation": "President"
79159      }
79160    }
79161    ```
79162  
79163    ### Errors
79164  
79165    If a response is considered a failure, the JSON payload is expected to include
79166    a top-level key `errors`, detailing any specific issues. For example:
79167  
79168    ```js
79169    {
79170      "errors": {
79171        "msg": "Something went wrong"
79172      }
79173    }
79174    ```
79175  
79176    This adapter does not make any assumptions as to the format of the `errors`
79177    object. It will simply be passed along as is, wrapped in an instance
79178    of `DS.InvalidError` or `DS.AdapterError`. The serializer can interpret it
79179    afterwards.
79180  
79181    ## Customization
79182  
79183    ### Endpoint path customization
79184  
79185    Endpoint paths can be prefixed with a `namespace` by setting the namespace
79186    property on the adapter:
79187  
79188    ```app/adapters/application.js
79189    import DS from 'ember-data';
79190  
79191    export default DS.RESTAdapter.extend({
79192      namespace: 'api/1'
79193    });
79194    ```
79195    Requests for the `Person` model would now target `/api/1/people/1`.
79196  
79197    ### Host customization
79198  
79199    An adapter can target other hosts by setting the `host` property.
79200  
79201    ```app/adapters/application.js
79202    import DS from 'ember-data';
79203  
79204    export default DS.RESTAdapter.extend({
79205      host: 'https://api.example.com'
79206    });
79207    ```
79208  
79209    ### Headers customization
79210  
79211    Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary
79212    headers can be set as key/value pairs on the `RESTAdapter`'s `headers`
79213    object and Ember Data will send them along with each ajax request.
79214  
79215  
79216    ```app/adapters/application.js
79217    import DS from 'ember-data';
79218  
79219    export default DS.RESTAdapter.extend({
79220      headers: {
79221        "API_KEY": "secret key",
79222        "ANOTHER_HEADER": "Some header value"
79223      }
79224    });
79225    ```
79226  
79227    `headers` can also be used as a computed property to support dynamic
79228    headers. In the example below, the `session` object has been
79229    injected into an adapter by Ember's container.
79230  
79231    ```app/adapters/application.js
79232    import DS from 'ember-data';
79233  
79234    export default DS.RESTAdapter.extend({
79235      headers: Ember.computed('session.authToken', function() {
79236        return {
79237          "API_KEY": this.get("session.authToken"),
79238          "ANOTHER_HEADER": "Some header value"
79239        };
79240      })
79241    });
79242    ```
79243  
79244    In some cases, your dynamic headers may require data from some
79245    object outside of Ember's observer system (for example
79246    `document.cookie`). You can use the
79247    [volatile](/api/classes/Ember.ComputedProperty.html#method_volatile)
79248    function to set the property into a non-cached mode causing the headers to
79249    be recomputed with every request.
79250  
79251    ```app/adapters/application.js
79252    import DS from 'ember-data';
79253  
79254    export default DS.RESTAdapter.extend({
79255      headers: Ember.computed(function() {
79256        return {
79257          "API_KEY": Ember.get(document.cookie.match(/apiKey\=([^;]*)/), "1"),
79258          "ANOTHER_HEADER": "Some header value"
79259        };
79260      }).volatile()
79261    });
79262    ```
79263  
79264    @class RESTAdapter
79265    @constructor
79266    @namespace DS
79267    @extends DS.Adapter
79268    @uses DS.BuildURLMixin
79269  */
79270  var RESTAdapter = _emberDataAdapter['default'].extend(_emberDataPrivateAdaptersBuildUrlMixin['default'], {
79271    defaultSerializer: '-rest',
79272
79273    /**
79274      By default, the RESTAdapter will send the query params sorted alphabetically to the
79275      server.
79276       For example:
79277       ```js
79278        store.query('posts', { sort: 'price', category: 'pets' });
79279      ```
79280       will generate a requests like this `/posts?category=pets&sort=price`, even if the
79281      parameters were specified in a different order.
79282       That way the generated URL will be deterministic and that simplifies caching mechanisms
79283      in the backend.
79284       Setting `sortQueryParams` to a falsey value will respect the original order.
79285       In case you want to sort the query parameters with a different criteria, set
79286      `sortQueryParams` to your custom sort function.
79287       ```app/adapters/application.js
79288      import DS from 'ember-data';
79289       export default DS.RESTAdapter.extend({
79290        sortQueryParams: function(params) {
79291          var sortedKeys = Object.keys(params).sort().reverse();
79292          var len = sortedKeys.length, newParams = {};
79293           for (var i = 0; i < len; i++) {
79294            newParams[sortedKeys[i]] = params[sortedKeys[i]];
79295          }
79296          return newParams;
79297        }
79298      });
79299      ```
79300       @method sortQueryParams
79301      @param {Object} obj
79302      @return {Object}
79303    */
79304    sortQueryParams: function sortQueryParams(obj) {
79305      var keys = Object.keys(obj);
79306      var len = keys.length;
79307      if (len < 2) {
79308        return obj;
79309      }
79310      var newQueryParams = {};
79311      var sortedKeys = keys.sort();
79312
79313      for (var i = 0; i < len; i++) {
79314        newQueryParams[sortedKeys[i]] = obj[sortedKeys[i]];
79315      }
79316      return newQueryParams;
79317    },
79318
79319    /**
79320      By default the RESTAdapter will send each find request coming from a `store.find`
79321      or from accessing a relationship separately to the server. If your server supports passing
79322      ids as a query string, you can set coalesceFindRequests to true to co
79322alesce all find requests
79323      within a single runloop.
79324       For example, if you have an initial payload of:
79325       ```javascript
79326      {
79327        post: {
79328          id: 1,
79329          comments: [1, 2]
79330        }
79331      }
79332      ```
79333       By default calling `post.get('comments')` will trigger the following requests(assuming the
79334      comments haven't been loaded before):
79335       ```
79336      GET /comments/1
79337      GET /comments/2
79338      ```
79339       If you set coalesceFindRequests to `true` it will instead trigger the following request:
79340       ```
79341      GET /comments?ids[]=1&ids[]=2
79342      ```
79343       Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo`
79344      relationships accessed within the same runloop. If you set `coalesceFindRequests: true`
79345       ```javascript
79346      store.findRecord('comment', 1);
79347      store.findRecord('comment', 2);
79348      ```
79349       will also send a request to: `GET /comments?ids[]=1&ids[]=2`
79350       Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app
79351      `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work.
79352       @property coalesceFindRequests
79353      @type {boolean}
79354    */
79355    coalesceFindRequests: false,
79356
79357    /**
79358      Endpoint paths can be prefixed with a `namespace` by setting the namespace
79359      property on the adapter:
79360       ```app/adapters/application.js
79361      import DS from 'ember-data';
79362       export default DS.RESTAdapter.extend({
79363        namespace: 'api/1'
79364      });
79365      ```
79366       Requests for the `Post` model would now target `/api/1/post/`.
79367       @property namespace
79368      @type {String}
79369    */
79370
79371    /**
79372      An adapter can target other hosts by setting the `host` property.
79373       ```app/adapters/application.js
79374      import DS from 'ember-data';
79375       export default DS.RESTAdapter.extend({
79376        host: 'https://api.example.com'
79377      });
79378      ```
79379       Requests for the `Post` model would now target `https://api.example.com/post/`.
79380       @property host
79381      @type {String}
79382    */
79383
79384    /**
79385      Some APIs require HTTP headers, e.g. to provide an API
79386      key. Arbitrary headers can be set as key/value pairs on the
79387      `RESTAdapter`'s `headers` object and Ember Data will send them
79388      along with each ajax request. For dynamic headers see [headers
79389      customization](/api/data/classes/DS.RESTAdapter.html#toc_headers-customization).
79390       ```app/adapters/application.js
79391      import DS from 'ember-data';
79392       export default DS.RESTAdapter.extend({
79393        headers: {
79394          "API_KEY": "secret key",
79395          "ANOTHER_HEADER": "Some header value"
79396        }
79397      });
79398      ```
79399       @property headers
79400      @type {Object}
79401     */
79402
79403    /**
79404      Called by the store in order to fetch the JSON for a given
79405      type and ID.
79406       The `findRecord` method makes an Ajax request to a URL computed by
79407      `buildURL`, and returns a promise for the resulting payload.
79408       This method performs an HTTP `GET` request with the id provided as part of the query string.
79409       @since 1.13.0
79410      @method findRecord
79411      @param {DS.Store} store
79412      @param {DS.Model} type
79413      @param {String} id
79414      @param {DS.Snapshot} snapshot
79415      @return {Promise} promise
79416    */
79417    findRecord: function findRecord(store, type, id, snapshot) {
79418      if (false && !this._hasCustomizedAjax()) {
79419        var request = this._requestFor({
79420          store: store, type: type, id: id, snapshot: snapshot,
79421          requestType: 'findRecord'
79422        });
79423
79424        return this._makeRequest(request);
79425      } else {
79426        var url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
79427        var query = this.buildQuery(snapshot);
79428
79429        return this.ajax(url, 'GET', { data: query });
79430      }
79431    },
79432
79433    /**
79434      Called by the store in order to fetch a JSON array for all
79435      of the records for a given type.
79436       The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
79437      promise for the resulting payload.
79438       @method findAll
79439      @param {DS.Store} store
79440      @param {DS.Model} type
79441      @param {String} sinceToken
79442      @param {DS.SnapshotRecordArray} snapshotRecordArray
79443      @return {Promise} promise
79444    */
79445    findAll: function findAll(store, type, sinceToken, snapshotRecordArray) {
79446      var query = this.buildQuery(snapshotRecordArray);
79447
79448      if (false && !this._hasCustomizedAjax()) {
79449        var request = this._requestFor({
79450          store: store, type: type, sinceToken: sinceToken, query: query,
79451          snapshots: snapshotRecordArray,
79452          requestType: 'findAll'
79453        });
79454
79455        return this._makeRequest(request);
79456      } else {
79457        var url = this.buildURL(type.modelName, null, snapshotRecordArray, 'findAll');
79458
79459        if (sinceToken) {
79460          query.since = sinceToken;
79461        }
79462
79463        return this.ajax(url, 'GET', { data: query });
79464      }
79465    },
79466
79467    /**
79468      Called by the store in order to fetch a JSON array for
79469      the records that match a particular query.
79470       The `query` method makes an Ajax (HTTP GET) request to a URL
79471      computed by `buildURL`, and returns a promise for the resulting
79472      payload.
79473       The `query` argument is a simple JavaScript object that will be passed directly
79474      to the server as parameters.
79475       @method query
79476      @param {DS.Store} store
79477      @param {DS.Model} type
79478      @param {Object} query
79479      @return {Promise} promise
79480    */
79481    query: function query(store, type, _query) {
79482      if (false && !this._hasCustomizedAjax()) {
79483        var request = this._requestFor({
79484          store: store, type: type, query: _query,
79485          requestType: 'query'
79486        });
79487
79488        return this._makeRequest(request);
79489      } else {
79490        var url = this.buildURL(type.modelName, null, null, 'query', _query);
79491
79492        if (this.sortQueryParams) {
79493          _query = this.sortQueryParams(_query);
79494        }
79495
79496        return this.ajax(url, 'GET', { data: _query });
79497      }
79498    },
79499
79500    /**
79501      Called by the store in order to fetch a JSON object for
79502      the record that matches a particular query.
79503       The `queryRecord` method makes an Ajax (HTTP GET) request to a URL
79504      computed by `buildURL`, and returns a promise for the resulting
79505      payload.
79506       The `query` argument is a simple JavaScript object that will be passed directly
79507      to the server as parameters.
79508       @since 1.13.0
79509      @method queryRecord
79510      @param {DS.Store} store
79511      @param {DS.Model} type
79512      @param {Object} query
79513      @return {Promise} promise
79514    */
79515    queryRecord: function queryRecord(store, type, query) {
79516      if (false && !this._hasCustomizedAjax()) {
79517        var request = this._requestFor({
79518          store: store, type: type, query: query,
79519          requestType: 'queryRecord'
79520        });
79521
79522        return this._makeRequest(request);
79523      } else {
79524        var url = this.buildURL(type.modelName, null, null, 'queryRecord', query);
79525
79526        if (this.sortQueryParams) {
79527          query = this.sortQueryParams(query);
79528        }
79529
79530        return this.ajax(url, 'GET', { data: query });
79531      }
79532    },
79533
79534    /**
79535      Called by the store in order to fetch several records together if `coalesceFindRequests` is true
79536       For example, if the original payload looks like:
79537       ```js
79538      {
79539        "id": 1,
79540        "title": "Rails is omakase",
79541        "comments": [ 1, 2, 3 ]
79542      }
79543      ```
79544       The IDs will be passed as a URL-encoded Array of IDs, in this form:
79545       ```
79546      ids[]=1&ids[]=2&ids[]=3
79547      ```
79548       Many servers, such as Rails and PHP, will automatically convert this URL-encoded array
79549      into an Array for you on the server-side. If you want to encode the
79550      IDs, differently, just override this (one-line) method.
79551       The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
79552      promise for the resulting payload.
79553       @method findMany
79554      @param {DS.Store} store
79555      @param {DS.Model} type
79556      @param {Array} ids
79557      @param {Array} snapshots
79558      @return {Promise} promise
79559    */
79560    findMany: function findMany(store, type, ids, snapshots) {
79561      if (false && !this._hasCustomizedAjax()) {
79562        var request = this._requestFor({
79563          store: store, type: type, ids: ids, snapshots: snapshots,
79564          requestType: 'findMany'
79565        });
79566
79567        return this._makeRequest(request);
79568      } else {
79569        var url = this.buildURL(type.modelName, ids, snapshots, 'findMany');
79570        return this.ajax(url, 'GET', { data: { ids: ids } });
79571      }
79572    },
79573
79574    /**
79575      Called by the store in order to fetch a JSON array for
79576      the unloaded records in a has-many relationship that were originally
79577      specified as a URL (inside of `links`).
79578       For example, if your original payload looks like this:
79579       ```js
79580      {
79581        "post": {
79582          "id": 1,
79583          "title": "Rails is omakase",
79584          "links": { "comments": "/posts/1/comments" }
79585        }
79586      }
79587      ```
79588       This method will be called with the parent record and `/posts/1/comments`.
79589       The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL.
79590       The format of your `links` value will influence the final request URL via the `urlPrefix` method:
79591       * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation.
79592       * Links beginning with a single `/` will have the current adapter's `host` value prepended to it.
79593       * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`.
79594       @method findHasMany
79595      @param {DS.Store} store
79596      @param {DS.Snapshot} snapshot
79597      @param {String} url
79598      @return {Promise} promise
79599    */
79600    findHasMany: function findHasMany(store, snapshot, url, relationship) {
79601      if (false && !this._hasCustomizedAjax()) {
79602        var request = this._requestFor({
79603          store: store, snapshot: snapshot, url: url, relationship: relationship,
79604          requestType: 'findHasMany'
79605        });
79606
79607        return this._makeRequest(request);
79608      } else {
79609        var id = snapshot.id;
79610        var type = snapshot.modelName;
79611
79612        url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findHasMany'));
79613
79614        return this.ajax(url, 'GET');
79615      }
79616    },
79617
79618    /**
79619      Called by the store in order to fetch the JSON for the unloaded record in a
79620      belongs-to relationship that was originally specified as a URL (inside of
79621      `links`).
79622       For example, if your original payload looks like this:
79623       ```js
79624      {
79625        "person": {
79626          "id": 1,
79627          "name": "Tom Dale",
79628          "links": { "group": "/people/1/group" }
79629        }
79630      }
79631      ```
79632       This method will be called with the parent record and `/people/1/group`.
79633       The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
79634       The format of your `links` value will influence the final request URL via the `urlPrefix` method:
79635       * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation.
79636       * Links beginning with a single `/` will have the current adapter's `host` value prepended to it.
79637       * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`.
79638       @method findBelongsTo
79639      @param {DS.Store} store
79640      @param {DS.Snapshot} snapshot
79641      @param {String} url
79642      @return {Promise} promise
79643    */
79644    findBelongsTo: function findBelongsTo(store, snapshot, url, relationship) {
79645      if (false && !this._hasCustomizedAjax()) {
79646        var request = this._requestFor({
79647          store: store, snapshot: snapshot, url: url, relationship: relationship,
79648          requestType: 'findBelongsTo'
79649        });
79650
79651        return this._makeRequest(request);
79652      } else {
79653        var id = snapshot.id;
79654        var type = snapshot.modelName;
79655
79656        url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findBelongsTo'));
79657        return this.ajax(url, 'GET');
79658      }
79659    },
79660
79661    /**
79662      Called by the store when a newly created record is
79663      saved via the `save` method on a model record instance.
79664       The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request
79665      to a URL computed by `buildURL`.
79666       See `serialize` for information on how to customize the serialized form
79667      of a record.
79668       @method createRecord
79669      @param {DS.Store} store
79670      @param {DS.Model} type
79671      @param {DS.Snapshot} snapshot
79672      @return {Promise} promise
79673    */
79674    createRecord: function createRecord(store, type, snapshot) {
79675      if (false && !this._hasCustomizedAjax()) {
79676        var request = this._requestFor({
79677          store: store, type: type, snapshot: snapshot,
79678          requestType: 'createRecord'
79679        });
79680
79681        return this._makeRequest(request);
79682      } else {
79683        var data = {};
79684        var serializer = store.serializerFor(type.modelName);
79685        var url = this.buildURL(type.modelName, null, snapshot, 'createRecord');
79686
79687        serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
79688
79689        return this.ajax(url, "POST", { data: data });
79690      }
79691    },
79692
79693    /**
79694      Called by the store when an existing record is saved
79695      via the `save` method on a model record instance.
79696       The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request
79697      to a URL computed by `buildURL`.
79698       See `serialize` for information on how to customize the serialized form
79699      of a record.
79700       @method updateRecord
79701      @param {DS.Store} store
79702      @param {DS.Model} type
79703      @param {DS.Snapshot} snapshot
79704      @return {Promise} promise
79705    */
79706    updateRecord: function updateRecord(store, type, snapshot) {
79707      if (false && !this._hasCustomizedAjax()) {
79708        var request = this._requestFor({
79709          store: store, type: type, snapshot: snapshot,
79710          requestType: 'updateRecord'
79711        });
79712
79713        return this._makeRequest(request);
79714      } else {
79715        var data = {};
79716        var serializer = store.serializerFor(type.modelName);
79717
79718        serializer.serializeIntoHash(data, type, snapshot);
79719
79720        var id = snapshot.id;
79721        var url = this.buildURL(type.modelName, id, snapshot, 'updateRecord');
79722
79723        return this.ajax(url, "PUT", { data: data });
79724      }
79725    },
79726
79727    /**
79728      Called by the store when a record is deleted.
79729       The `deleteRecord` method  makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
79730       @method deleteRecord
79731      @param {DS.Store} store
79732      @param {DS.Model} type
79733      @param {DS.Snapshot} snapshot
79734      @return {Promise} promise
79735    */
79736    deleteRecord: function deleteRecord(store, type, snapshot) {
79737      if (false && !this._hasCustomizedAjax()) {
79738        var request = this._requestFor({
79739          store: store, type: type, snapshot: snapshot,
79740          requestType: 'deleteRecord'
79741        });
79742
79743        return this._makeRequest(request);
79744      } else {
79745        var id = snapshot.id;
79746
79747        return this.ajax(this.buildURL(type.modelName, id, snapshot, 'deleteRecord'), "DELETE");
79748      }
79749    },
79750
79751    _stripIDFromURL: function _stripIDFromURL(store, snapshot) {
79752      var url = this.buildURL(snapshot.modelName, snapshot.id, snapshot);
79753
79754      var expandedURL = url.split('/');
79755      // Case when the url is of the format ...something/:id
79756      // We are decodeURIComponent-ing the lastSegment because if it represents
79757      // the id, it has been encodeURIComponent-ified within `buildURL`. If we
79758      // don't do this, then records with id having special characters are not
79759      // coalesced correctly (see GH #4190 for the reported bug)
79760      var lastSegment = expandedURL[expandedURL.length - 1];
79761      var id = snapshot.id;
79762      if (decodeURIComponent(lastSegment) === id) {
79763        expandedURL[expandedURL.length - 1] = "";
79764      } else if (endsWith(lastSegment, '?id=' + id)) {
79765        //Case when the url is of the format ...something?id=:id
79766        expandedURL[expandedURL.length - 1] = lastSegment.substring(0, lastSegment.length - id.length - 1);
79767      }
79768
79769      return expandedURL.join('/');
79770    },
79771
79772    // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
79773    maxURLLength: 2048,
79774
79775    /**
79776      Organize records into groups, each of which is to be passed to separate
79777      calls to `findMany`.
79778       This implementation groups together records that have the same base URL but
79779      differing ids. For example `/comments/1` and `/comments/2` will be grouped together
79780      because we know findMany can coalesce them together as `/comments?ids[]=1&ids[]=2`
79781       It also supports urls where ids are passed as a query param, such as `/comments?id=1`
79782      but not those where there is more than 1 query param such as `/comments?id=2&name=David`
79783      Currently only the query param of `id` is supported. If you need to support others, please
79784      override this or the `_stripIDFromURL` method.
79785       It does not group records that have differing base urls, such as for example: `/posts/1/comments/2`
79786      and `/posts/2/comments/3`
79787       @method groupRecordsForFindMany
79788      @param {DS.Store} store
79789      @param {Array} snapshots
79790      @return {Array}  an array of arrays of records, each of which is to be
79791                        loaded separately by `findMany`.
79792    */
79793    groupRecordsForFindMany: function groupRecordsForFindMany(store, snapshots) {
79794      var groups = MapWithDefault.create({ defaultValue: function defaultValue() {
79795          return [];
79796        } });
79797      var adapter = this;
79798      var maxURLLength = this.maxURLLength;
79799
79800      snapshots.forEach(function (snapshot) {
79801        var baseUrl = adapter._stripIDFromURL(store, snapshot);
79802        groups.get(baseUrl).push(snapshot);
79803      });
79804
79805      function splitGroupToFitInUrl(group, maxURLLength, paramNameLength) {
79806        var baseUrl = adapter._stripIDFromURL(store, group[0]);
79807        var idsSize = 0;
79808        var splitGroups = [[]];
79809
79810        group.forEach(function (snapshot) {
79811          var additionalLength = encodeURIComponent(snapshot.id).length + paramNameLength;
79812          if (baseUrl.length + idsSize + additionalLength >= maxURLLength) {
79813            idsSize = 0;
79814            splitGroups.push([]);
79815          }
79816
79817          idsSize += additionalLength;
79818
79819          var lastGroupIndex = splitGroups.length - 1;
79820          splitGroups[lastGroupIndex].push(snapshot);
79821        });
79822
79823        return splitGroups;
79824      }
79825
79826      var groupsArray = [];
79827      groups.forEach(function (group, key) {
79828        var paramNameLength = '&ids%5B%5D='.length;
79829        var splitGroups = splitGroupToFitInUrl(group, maxURLLength, paramNameLength);
79830
79831        splitGroups.forEach(function (splitGroup) {
79832          return groupsArray.push(splitGroup);
79833        });
79834      });
79835
79836      return groupsArray;
79837    },
79838
79839    /**
79840      Takes an ajax response, and returns the json payload or an error.
79841       By default this hook just returns the json payload passed to it.
79842      You might want to override it in two cases:
79843       1. Your API might return useful results in the response headers.
79844      Response headers are passed in as the second argument.
79845       2. Your API might return errors as successful responses with status code
79846      200 and an Errors text or object. You can return a `DS.InvalidError` or a
79847      `DS.AdapterError` (or a sub class) from this hook and it will automatically
79848      reject the promise and put your record into the invalid or error state.
79849       Returning a `DS.InvalidError` from this method will cause the
79850      record to transition into the `invalid` state and make the
79851      `errors` object available on the record. When returning an
79852      `DS.InvalidError` the store will attempt to normalize the error data
79853      returned from the server using the serializer's `extractErrors`
79854      method.
79855       @since 1.13.0
79856      @method handleResponse
79857      @param  {Number} status
79858      @param  {Object} headers
79859      @param  {Object} payload
79860      @param  {Object} requestData - the original request information
79861      @return {Object | DS.AdapterError} response
79862    */
79863    handleResponse: function handleResponse(status, headers, payload, requestData) {
79864      if (this.isSuccess(status, headers, payload)) {
79865        return payload;
79866      } else if (this.isInvalid(status, headers, payload)) {
79867        return new _emberDataAdaptersErrors.InvalidError(payload.errors);
79868      }
79869
79870      var errors = this.normalizeErrorResponse(status, headers, payload);
79871      var detailedMessage = this.generatedDetailedMessage(status, headers, payload, requestData);
79872
79873      if (false) {
79874        switch (status) {
79875          case 401:
79876            return new _emberDataAdaptersErrors.UnauthorizedError(errors, detailedMessage);
79877          case 403:
79878            return new _emberDataAdaptersErrors.ForbiddenError(errors, detailedMessage);
79879          case 404:
79880            return new _emberDataAdaptersErrors.NotFoundError(errors, detailedMessage);
79881          case 409:
79882            return new _emberDataAdaptersErrors.ConflictError(errors, detailedMessage);
79883          default:
79884            if (status >= 500) {
79885              return new _emberDataAdaptersErrors.ServerError(errors, detailedMessage);
79886            }
79887        }
79888      }
79889
79890      return new _emberDataAdaptersErrors.AdapterError(errors, detailedMessage);
79891    },
79892
79893    /**
79894      Default `handleResponse` implementation uses this hook to decide if the
79895      response is a success.
79896       @since 1.13.0
79897      @method isSuccess
79898      @param  {Number} status
79899      @param  {Object} headers
79900      @param  {Object} payload
79901      @return {Boolean}
79902    */
79903    isSuccess: function isSuccess(status, headers, payload) {
79904      return status >= 200 && status < 300 || status === 304;
79905    },
79906
79907    /**
79908      Default `handleResponse` implementation uses this hook to decide if the
79909      response is a an invalid error.
79910       @since 1.13.0
79911      @method isInvalid
79912      @param  {Number} status
79913      @param  {Object} headers
79914      @param  {Object} payload
79915      @return {Boolean}
79916    */
79917    isInvalid: function isInvalid(status, headers, payload) {
79918      return status === 422;
79919    },
79920
79921    /**
79922      Takes a URL, an HTTP method and a hash of data, and makes an
79923      HTTP request.
79924       When the server responds with a payload, Ember Data will call into `extractSingle`
79925      or `extractArray` (depending on whether the original query was for one record or
79926      many records).
79927       By default, `ajax` method has the following behavior:
79928       * It sets the response `dataType` to `"json"`
79929      * If the HTTP method is not `"GET"`, it sets the `Content-Type` to be
79930        `application/json; charset=utf-8`
79931      * If the HTTP method is not `"GET"`, it stringifies the data passed in. The
79932        data is the serialized record in the case of a save.
79933      * Registers success and failure handlers.
79934       @method ajax
79935      @private
79936      @param {String} url
79937      @param {String} type The request type GET, POST, PUT, DELETE etc.
79938      @param {Object} options
79939      @return {Promise} promise
79940    */
79941    ajax: function ajax(url, type, options) {
79942      var adapter = this;
79943
79944      var requestData = {
79945        url: url,
79946        method: type
79947      };
79948
79949      return new _ember['default'].RSVP.Promise(function (resolve, reject) {
79950        var hash = adapter.ajaxOptions(url, type, options);
79951
79952        hash.success = function (payload, textStatus, jqXHR) {
79953
79954          var response = adapter.handleResponse(jqXHR.status, (0, _emberDataPrivateUtilsParseResponseHeaders['default'])(jqXHR.getAllResponseHeaders()), payload, requestData);
79955
79956          if (response && response.isAdapterError) {
79957            _ember['default'].run.join(null, reject, response);
79958          } else {
79959            _ember['default'].run.join(null, resolve, response);
79960          }
79961        };
79962
79963        hash.error = function (jqXHR, textStatus, errorThrown) {
79964          (0, _emberDataPrivateDebug.runInDebug)(function () {
79965            var message = 'The server returned an empty string for ' + type + ' ' + url + ', which cannot be parsed into a valid JSON. Return either null or {}.';
79966            var validJSONString = !(textStatus === "parsererror" && jqXHR.responseText === "");
79967            (0, _emberDataPrivateDebug.warn)(message, validJSONString, {
79968              id: 'ds.adapter.returned-empty-string-as-JSON'
79969            });
79970          });
79971
79972          var error = undefined;
79973
79974          if (errorThrown instanceof Error) {
79975            error = errorThrown;
79976          } else if (textStatus === 'timeout') {
79977            error = new _emberDataAdaptersErrors.TimeoutError();
79978          } else if (textStatus === 'abort') {
79979            error = new _emberDataAdaptersErrors.AbortError();
79980          } else {
79981            error = adapter.handleResponse(jqXHR.status, (0, _emberDataPrivateUtilsParseResponseHeaders['default'])(jqXHR.getAllResponseHeaders()), adapter.parseErrorResponse(jqXHR.responseText) || errorThrown, requestData);
79982          }
79983
79984          _ember['default'].run.join(null, reject, error);
79985        };
79986
79987        adapter._ajaxRequest(hash);
79988      }, 'DS: RESTAdapter#ajax ' + type + ' to ' + url);
79989    },
79990
79991    /**
79992      @method _ajaxRequest
79993      @private
79994      @param {Object} options jQuery ajax options to be used for the ajax request
79995    */
79996    _ajaxRequest: function _ajaxRequest(options) {
79997      _ember['default'].$.ajax(options);
79998    },
79999
80000    /**
80001      @method ajaxOptions
80002      @private
80003      @param {String} url
80004      @param {String} type The request type GET, POST, PUT, DELETE etc.
80005      @param {Object} options
80006      @return {Object}
80007    */
80008    ajaxOptions: function ajaxOptions(url, type, options) {
80009      var hash = options || {};
80010      hash.url = url;
80011      hash.type = type;
80012      hash.dataType = 'json';
80013      hash.context = this;
80014
80015      if (hash.data && type !== 'GET') {
80016        hash.contentType = 'application/json; charset=utf-8';
80017        hash.data = JSON.stringify(hash.data);
80018      }
80019
80020      var headers = get(this, 'headers');
80021      if (headers !== undefined) {
80022        hash.beforeSend = function (xhr) {
80023          Object.keys(headers).forEach(function (key) {
80024            return xhr.setRequestHeader(key, headers[key]);
80025          });
80026        };
80027      }
80028
80029      return hash;
80030    },
80031
80032    /**
80033      @method parseErrorResponse
80034      @private
80035      @param {String} responseText
80036      @return {Object}
80037    */
80038    parseErrorResponse: function parseErrorResponse(responseText) {
80039      var json = responseText;
80040
80041      try {
80042        json = _ember['default'].$.parseJSON(responseText);
80043      } catch (e) {
80044        // ignored
80045      }
80046
80047      return json;
80048    },
80049
80050    /**
80051      @method normalizeErrorResponse
80052      @private
80053      @param  {Number} status
80054      @param  {Object} headers
80055      @param  {Object} payload
80056      @return {Array} errors payload
80057    */
80058    normalizeErrorResponse: function normalizeErrorResponse(status, headers, payload) {
80059      if (payload && typeof payload === 'object' && payload.errors) {
80060        return payload.errors;
80061      } else {
80062        return [{
80063          status: '' + status,
80064          title: "The backend responded with an error",
80065          detail: '' + payload
80066        }];
80067      }
80068    },
80069
80070    /**
80071      Generates a detailed ("friendly") error message, with plenty
80072      of information for debugging (good luck!)
80073       @method generatedDetailedMessage
80074      @private
80075      @param  {Number} status
80076      @param  {Object} headers
80077      @param  {Object} payload
80078      @param  {Object} requestData
80079      @return {String} detailed error message
80080    */
80081    generatedDetailedMessage: function generatedDetailedMessage(status, headers, payload, requestData) {
80082      var shortenedPayload;
80083      var payloadContentType = headers["Content-Type"] || "Empty Content-Type";
80084
80085      if (payloadContentType === "text/html" && payload.length > 250) {
80086        shortenedPayload = "[Omitted Lengthy HTML]";
80087      } else {
80088        shortenedPayload = payload;
80089      }
80090
80091      var requestDescription = requestData.method + ' ' + requestData.url;
80092      var payloadDescription = 'Payload (' + payloadContentType + ')';
80093
80094      return ['Ember Data Request ' + requestDescription + ' returned a ' + status, payloadDescription, shortenedPayload].join('\n');
80095    },
80096
80097    // @since 2.5.0
80098    buildQuery: function buildQuery(snapshot) {
80099      var query = {};
80100
80101      if (snapshot) {
80102        var include = snapshot.include;
80103
80104        if (include) {
80105          query.include = include;
80106        }
80107      }
80108
80109      return query;
80110    },
80111
80112    _hasCustomizedAjax: function _hasCustomizedAjax() {
80113      if (this.ajax !== RESTAdapter.prototype.ajax) {
80114        (0, _emberDataPrivateDebug.deprecate)('RESTAdapter#ajax has been deprecated please use. `methodForRequest`, `urlForRequest`, `headersForRequest` or `dataForRequest` instead.', false, {
80115          id: 'ds.rest-adapter.ajax',
80116          until: '3.0.0'
80117        });
80118        return true;
80119      }
80120
80121      if (this.ajaxOptions !== RESTAdapter.prototype.ajaxOptions) {
80122        (0, _emberDataPrivateDebug.deprecate)('RESTAdapter#ajaxOptions has been deprecated please use. `methodForRequest`, `urlForRequest`, `headersForRequest` or `dataForRequest` instead.', false, {
80123          id: 'ds.rest-adapter.ajax-options',
80124          until: '3.0.0'
80125        });
80126        return true;
80127      }
80128
80129      return false;
80130    }
80131  });
80132
80133  if (false) {
80134
80135    RESTAdapter.reopen({
80136
80137      /**
80138       * Get the data (body or query params) for a request.
80139       *
80140       * @public
80141       * @method dataForRequest
80142       * @param {Object} params
80143       * @return {Object} data
80144       */
80145      dataForRequest: function dataForRequest(params) {
80146        var store = params.store;
80147        var type = params.type;
80148        var snapshot = params.snapshot;
80149        var requestType = params.requestType;
80150        var query = params.query;
80151
80152        // type is not passed to findBelongsTo and findHasMany
80153        type = type || snapshot && snapshot.type;
80154
80155        var serializer = store.serializerFor(type.modelName);
80156        var data = {};
80157
80158        switch (requestType) {
80159          case 'createRecord':
80160            serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
80161            break;
80162
80163          case 'updateRecord':
80164            serializer.serializeIntoHash(data, type, snapshot);
80165            break;
80166
80167          case 'findRecord':
80168            data = this.buildQuery(snapshot);
80169            break;
80170
80171          case 'findAll':
80172            if (params.sinceToken) {
80173              query = query || {};
80174              query.since = params.sinceToken;
80175            }
80176            data = query;
80177            break;
80178
80179          case 'query':
80180          case 'queryRecord':
80181            if (this.sortQueryParams) {
80182              query = this.sortQueryParams(query);
80183            }
80184            data = query;
80185            break;
80186
80187          case 'findMany':
80188            data = { ids: params.ids };
80189            break;
80190
80191          default:
80192            data = undefined;
80193            break;
80194        }
80195
80196        return data;
80197      },
80198
80199      /**
80200       * Get the HTTP method for a request.
80201       *
80202       * @public
80203       * @method methodForRequest
80204       * @param {Object} params
80205       * @return {String} HTTP method
80206       */
80207      methodForRequest: function methodForRequest(params) {
80208        var requestType = params.requestType;
80209
80210        switch (requestType) {
80211          case 'createRecord':
80212            return 'POST';
80213          case 'updateRecord':
80214            return 'PUT';
80215          case 'deleteRecord':
80216            return 'DELETE';
80217        }
80218
80219        return 'GET';
80220      },
80221
80222      /**
80223       * Get the URL for a request.
80224       *
80225       * @public
80226       * @method urlForRequest
80227       * @param {Object} params
80228       * @return {String} URL
80229       */
80230      urlForRequest: function urlForRequest(params) {
80231        var type = params.type;
80232        var id = params.id;
80233        var ids = params.ids;
80234        var snapshot = params.snapshot;
80235        var snapshots = params.snapshots;
80236        var requestType = params.requestType;
80237        var query = params.query;
80238
80239        // type and id are not passed from updateRecord and deleteRecord, hence they
80240        // are defined if not set
80241        type = type || snapshot && snapshot.type;
80242        id = id || snapshot && snapshot.id;
80243
80244        switch (requestType) {
80245          case 'findAll':
80246            return this.buildURL(type.modelName, null, snapshots, requestType);
80247
80248          case 'query':
80249          case 'queryRecord':
80250            return this.buildURL(type.modelName, null, null, requestType, query);
80251
80252          case 'findMany':
80253            return this.buildURL(type.modelName, ids, snapshots, requestType);
80254
80255          case 'findHasMany':
80256          case 'findBelongsTo':
80257            {
80258              var url = this.buildURL(type.modelName, id, snapshot, requestType);
80259              return this.urlPrefix(params.url, url);
80260            }
80261        }
80262
80263        return this.buildURL(type.modelName, id, snapshot, requestType, query);
80264      },
80265
80266      /**
80267       * Get the headers for a request.
80268       *
80269       * By default the value of the `headers` property of the adapter is
80270       * returned.
80271       *
80272       * @public
80273       * @method headersForRequest
80274       * @param {Object} params
80275       * @return {Object} headers
80276       */
80277      headersForRequest: function headersForRequest(params) {
80278        return this.get('headers');
80279      },
80280
80281      /**
80282       * Get an object which contains all properties for a request which should
80283       * be made.
80284       *
80285       * @private
80286       * @method _requestFor
80287       * @param {Object} params
80288       * @return {Object} request object
80289       */
80290      _requestFor: function _requestFor(params) {
80291        var method = this.methodForRequest(params);
80292        var url = this.urlForRequest(params);
80293        var headers = this.headersForRequest(params);
80294        var data = this.dataForRequest(params);
80295
80296        return { method: method, url: url, headers: headers, data: data };
80297      },
80298
80299      /**
80300       * Convert a request object into a hash which can be passed to `jQuery.ajax`.
80301       *
80302       * @private
80303       * @method _requestToJQueryAjaxHash
80304       * @param {Object} request
80305       * @return {Object} jQuery ajax hash
80306       */
80307      _requestToJQueryAjaxHash: function _requestToJQueryAjaxHash(request) {
80308        var hash = {};
80309
80310        hash.type = request.method;
80311        hash.url = request.url;
80312        hash.dataType = 'json';
80313        hash.context = this;
80314
80315        if (request.data) {
80316          if (request.method !== 'GET') {
80317            hash.contentType = 'application/json; charset=utf-8';
80318            hash.data = JSON.stringify(request.data);
80319          } else {
80320            hash.data = request.data;
80321          }
80322        }
80323
80324        var headers = request.headers;
80325        if (headers !== undefined) {
80326          hash.beforeSend = function (xhr) {
80327            Object.keys(headers).forEach(function (key) {
80328              return xhr.setRequestHeader(key, headers[key]);
80329            });
80330          };
80331        }
80332
80333        return hash;
80334      },
80335
80336      /**
80337       * Make a request using `jQuery.ajax`.
80338       *
80339       * @private
80340       * @method _makeRequest
80341       * @param {Object} request
80342       * @return {Promise} promise
80343       */
80344      _makeRequest: function _makeRequest(request) {
80345        var adapter = this;
80346        var hash = this._requestToJQueryAjaxHash(request);
80347
80348        var method = request.method;
80349        var url = request.url;
80350
80351        var requestData = { method: method, url: url };
80352
80353        return new _ember['default'].RSVP.Promise(function (resolve, reject) {
80354
80355          hash.success = function (payload, textStatus, jqXHR) {
80356            var response = adapter.handleResponse(jqXHR.status, (0, _emberDataPrivateUtilsParseResponseHeaders['default'])(jqXHR.getAllResponseHeaders()), payload, requestData);
80357
80358            if (response instanceof _emberDataAdaptersErrors.AdapterError) {
80359              _ember['default'].run.join(null, reject, response);
80360            } else {
80361              _ember['default'].run.join(null, resolve, response);
80362            }
80363          };
80364
80365          hash.error = function (jqXHR, textStatus, errorThrown) {
80366            (0, _emberDataPrivateDebug.runInDebug)(function () {
80367              var message = 'The server returned an empty string for ' + method + ' ' + url + ', which cannot be parsed into a valid JSON. Return either null or {}.';
80368              var validJSONString = !(textStatus === "parsererror" && jqXHR.responseText === "");
80369              (0, _emberDataPrivateDebug.warn)(message, validJSONString, {
80370                id: 'ds.adapter.returned-empty-string-as-JSON'
80371              });
80372            });
80373
80374            var error = undefined;
80375
80376            if (errorThrown instanceof Error) {
80377              error = errorThrown;
80378            } else if (textStatus === 'timeout') {
80379              error = new _emberDataAdaptersErrors.TimeoutError();
80380            } else if (textStatus === 'abort') {
80381              error = new _emberDataAdaptersErrors.AbortError();
80382            } else {
80383              error = adapter.handleResponse(jqXHR.status, (0, _emberDataPrivateUtilsParseResponseHeaders['default'])(jqXHR.getAllResponseHeaders()), adapter.parseErrorResponse(jqXHR.responseText) || errorThrown, requestData);
80384            }
80385
80386            _ember['default'].run.join(null, reject, error);
80387          };
80388
80389          adapter._ajaxRequest(hash);
80390        }, 'DS: RESTAdapter#makeRequest: ' + method + ' ' + url);
80391      }
80392    });
80393  }
80394
80395  //From http://stackoverflow.com/questions/280634/endswith-in-javascript
80396  function endsWith(string, suffix) {
80397    if (typeof String.prototype.endsWith !== 'function') {
80398      return string.indexOf(suffix, string.length - suffix.length) !== -1;
80399    } else {
80400      return string.endsWith(suffix);
80401    }
80402  }
80403
80404  exports['default'] = RESTAdapter;
80405});
80406define('ember-data/attr', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
80407  'use strict';
80408
80409  exports['default'] = attr;
80410
80411  /**
80412    @module ember-data
80413  */
80414
80415  function getDefaultValue(record, options, key) {
80416    if (typeof options.defaultValue === 'function') {
80417      return options.defaultValue.apply(null, arguments);
80418    } else {
80419      var defaultValue = options.defaultValue;
80420      (0, _emberDataPrivateDebug.deprecate)('Non primitive defaultValues are deprecated because they are shared between all instances. If you would like to use a complex object as a default value please provide a function that returns the complex object.', typeof defaultValue !== 'object' || defaultValue === null, {
80421        id: 'ds.defaultValue.complex-object',
80422        until: '3.0.0'
80423      });
80424      return defaultValue;
80425    }
80426  }
80427
80428  function hasValue(record, key) {
80429    return key in record._attributes || key in record._inFlightAttributes || key in record._data;
80430  }
80431
80432  function getValue(record, key) {
80433    if (key in record._attributes) {
80434      return record._attributes[key];
80435    } else if (key in record._inFlightAttributes) {
80436      return record._inFlightAttributes[key];
80437    } else {
80438      return record._data[key];
80439    }
80440  }
80441
80442  /**
80443    `DS.attr` defines an attribute on a [DS.Model](/api/data/classes/DS.Model.html).
80444    By default, attributes are passed through as-is, however you can specify an
80445    optional type to have the value automatically transformed.
80446    Ember Data ships with four basic transform types: `string`, `number`,
80447    `boolean` and `date`. You can define your own transforms by subclassing
80448    [DS.Transform](/api/data/classes/DS.Transform.html).
80449  
80450    Note that you cannot use `attr` to define an attribute of `id`.
80451  
80452    `DS.attr` takes an optional hash as a second parameter, currently
80453    supported options are:
80454  
80455    - `defaultValue`: Pass a string or a function to be called to set the attribute
80456                      to a default value if none is supplied.
80457  
80458    Example
80459  
80460    ```app/models/user.js
80461    import DS from 'ember-data';
80462  
80463    export default DS.Model.extend({
80464      username: DS.attr('string'),
80465      email: DS.attr('string'),
80466      verified: DS.attr('boolean', { defaultValue: false })
80467    });
80468    ```
80469  
80470    Default value can also be a function. This is useful it you want to return
80471    a new object for each attribute.
80472  
80473    ```app/models/user.js
80474    import DS from 'ember-data';
80475  
80476    export default DS.Model.extend({
80477      username: attr('string'),
80478      email: attr('string'),
80479      settings: attr({defaultValue: function() {
80480        return {};
80481      }})
80482    });
80483    ```
80484  
80485    The `options` hash is passed as second argument to a transforms'
80486    `serialize` and `deserialize` method. This allows to configure a
80487    transformation and adapt the corresponding value, based on the config:
80488  
80489    ```app/models/post.js
80490    export default DS.Model.extend({
80491      text: DS.attr('text', {
80492        uppercase: true
80493      })
80494    });
80495    ```
80496  
80497    ```app/transforms/text.js
80498    export default DS.Transform.extend({
80499      serialize: function(value, options) {
80500        if (options.uppercase) {
80501          return value.toUpperCase();
80502        }
80503  
80504        return value;
80505      },
80506  
80507      deserialize: function(value) {
80508        return value;
80509      }
80510    })
80511    ```
80512  
80513    @namespace
80514    @method attr
80515    @for DS
80516    @param {String} type the attribute type
80517    @param {Object} options a hash of options
80518    @return {Attribute}
80519  */
80520  function attr(type, options) {
80521    if (typeof type === 'object') {
80522      options = type;
80523      type = undefined;
80524    } else {
80525      options = options || {};
80526    }
80527
80528    var meta = {
80529      type: type,
80530      isAttribute: true,
80531      options: options
80532    };
80533
80534    return _ember['default'].computed({
80535      get: function get(key) {
80536        var internalModel = this._internalModel;
80537        if (hasValue(internalModel, key)) {
80538          return getValue(internalModel, key);
80539        } else {
80540          return getDefaultValue(this, options, key);
80541        }
80542      },
80543      set: function set(key, value) {
80544        var internalModel = this._internalModel;
80545        var oldValue = getValue(internalModel, key);
80546        var originalValue;
80547
80548        if (value !== oldValue) {
80549          // Add the new value to the changed attributes hash; it will get deleted by
80550          // the 'didSetProperty' handler if it is no different from the original value
80551          internalModel._attributes[key] = value;
80552
80553          if (key in internalModel._inFlightAttributes) {
80554            originalValue = internalModel._inFlightAttributes[key];
80555          } else {
80556            originalValue = internalModel._data[key];
80557          }
80558
80559          this._internalModel.send('didSetProperty', {
80560            name: key,
80561            oldValue: oldValue,
80562            originalValue: originalValue,
80563            value: value
80564          });
80565        }
80566
80567        return value;
80568      }
80569    }).meta(meta);
80570  }
80571});
80572define("ember-data/index", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/features", "ember-data/-private/global", "ember-data/-private/core", "ember-data/-private/system/normalize-model-name", "ember-data/-private/system/model/internal-model", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/store", "ember-data/-private/system/model", "ember-data/model", "ember-data/-private/system/snapshot", "ember-data/adapter", "ember-data/serializer", "ember-data/-private/system/debug", "ember-data/adapters/errors", "ember-data/-private/system/record-arrays", "ember-data/-private/system/many-array", "ember-data/-private/system/record-array-manager", "ember-data/-private/adapters", "ember-data/-private/adapters/build-url-mixin", "ember-data/-private/serializers", "ember-inflector", "ember-data/serializers/embedded-records-mixin", "ember-data/-private/transforms", "ember-data/relationships", "ember-data/setup-container", "ember-data/-private/instance-initializer
80572s/initialize-store-service", "ember-data/-private/system/container-proxy", "ember-data/-private/system/relationships/state/relationship"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateFeatures, _emberDataPrivateGlobal, _emberDataPrivateCore, _emberDataPrivateSystemNormalizeModelName, _emberDataPrivateSystemModelInternalModel, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemStore, _emberDataPrivateSystemModel, _emberDataModel, _emberDataPrivateSystemSnapshot, _emberDataAdapter, _emberDataSerializer, _emberDataPrivateSystemDebug, _emberDataAdaptersErrors, _emberDataPrivateSystemRecordArrays, _emberDataPrivateSystemManyArray, _emberDataPrivateSystemRecordArrayManager, _emberDataPrivateAdapters, _emberDataPrivateAdaptersBuildUrlMixin, _emberDataPrivateSerializers, _emberInflector, _emberDataSerializersEmbeddedRecordsMixin, _emberDataPrivateTransforms, _emberDataRelationships, _emberDataSetupContainer, _emberDataPrivateInstanceInitializersInitializeStoreService, _emberDataPrivateSystemContainerProxy, _emberDataPrivateSystemRelationshipsStateRelationship) {
80573  "use strict";
80574
80575  if (_ember["default"].VERSION.match(/^1\.([0-9]|1[0-2])\./)) {
80576    throw new _ember["default"].Error("Ember Data requires at least Ember 1.13.0, but you have " + _ember["default"].VERSION + ". Please upgrade your version of Ember, then upgrade Ember Data.");
80577  }_emberDataPrivateCore["default"].Store = _emberDataPrivateSystemStore.Store;
80578  _emberDataPrivateCore["default"].PromiseArray = _emberDataPrivateSystemPromiseProxies.PromiseArray;
80579  _emberDataPrivateCore["default"].PromiseObject = _emberDataPrivateSystemPromiseProxies.PromiseObject;
80580
80581  _emberDataPrivateCore["default"].PromiseManyArray = _emberDataPrivateSystemPromiseProxies.PromiseManyArray;
80582
80583  _emberDataPrivateCore["default"].Model = _emberDataModel["default"];
80584  _emberDataPrivateCore["default"].RootState = _emberDataPrivateSystemModel.RootState;
80585  _emberDataPrivateCore["default"].attr = _emberDataPrivateSystemModel.attr;
80586  _emberDataPrivateCore["default"].Errors = _emberDataPrivateSystemModel.Errors;
80587
80588  _emberDataPrivateCore["default"].InternalModel = _emberDataPrivateSystemModelInternalModel["default"];
80589  _emberDataPrivateCore["default"].Snapshot = _emberDataPrivateSystemSnapshot["default"];
80590
80591  _emberDataPrivateCore["default"].Adapter = _emberDataAdapter["default"];
80592
80593  _emberDataPrivateCore["default"].AdapterError = _emberDataAdaptersErrors.AdapterError;
80594  _emberDataPrivateCore["default"].InvalidError = _emberDataAdaptersErrors.InvalidError;
80595  _emberDataPrivateCore["default"].TimeoutError = _emberDataAdaptersErrors.TimeoutError;
80596  _emberDataPrivateCore["default"].AbortError = _emberDataAdaptersErrors.AbortError;
80597
80598  if (false) {
80599    _emberDataPrivateCore["default"].UnauthorizedError = _emberDataAdaptersErrors.UnauthorizedError;
80600    _emberDataPrivateCore["default"].ForbiddenError = _emberDataAdaptersErrors.ForbiddenError;
80601    _emberDataPrivateCore["default"].NotFoundError = _emberDataAdaptersErrors.NotFoundError;
80602    _emberDataPrivateCore["default"].ConflictError = _emberDataAdaptersErrors.ConflictError;
80603    _emberDataPrivateCore["default"].ServerError = _emberDataAdaptersErrors.ServerError;
80604  }
80605
80606  _emberDataPrivateCore["default"].errorsHashToArray = _emberDataAdaptersErrors.errorsHashToArray;
80607  _emberDataPrivateCore["default"].errorsArrayToHash = _emberDataAdaptersErrors.errorsArrayToHash;
80608
80609  _emberDataPrivateCore["default"].Serializer = _emberDataSerializer["default"];
80610
80611  _emberDataPrivateCore["default"].DebugAdapter = _emberDataPrivateSystemDebug["default"];
80612
80613  _emberDataPrivateCore["default"].RecordArray = _emberDataPrivateSystemRecordArrays.RecordArray;
80614  _emberDataPrivateCore["default"].FilteredRecordArray = _emberDataPrivateSystemRecordArrays.FilteredRecordArray;
80615  _emberDataPrivateCore["default"].AdapterPopulatedRecordArray = _emberDataPrivateSystemRecordArrays.AdapterPopulatedRecordArray;
80616  _emberDataPrivateCore["default"].ManyArray = _emberDataPrivateSystemManyArray["default"];
80617
80618  _emberDataPrivateCore["default"].RecordArrayManager = _emberDataPrivateSystemRecordArrayManager["default"];
80619
80620  _emberDataPrivateCore["default"].RESTAdapter = _emberDataPrivateAdapters.RESTAdapter;
80621  _emberDataPrivateCore["default"].BuildURLMixin = _emberDataPrivateAdaptersBuildUrlMixin["default"];
80622
80623  _emberDataPrivateCore["default"].RESTSerializer = _emberDataPrivateSerializers.RESTSerializer;
80624  _emberDataPrivateCore["default"].JSONSerializer = _emberDataPrivateSerializers.JSONSerializer;
80625
80626  _emberDataPrivateCore["default"].JSONAPIAdapter = _emberDataPrivateAdapters.JSONAPIAdapter;
80627  _emberDataPrivateCore["default"].JSONAPISerializer = _emberDataPrivateSerializers.JSONAPISerializer;
80628
80629  _emberDataPrivateCore["default"].Transform = _emberDataPrivateTransforms.Transform;
80630  _emberDataPrivateCore["default"].DateTransform = _emberDataPrivateTransforms.DateTransform;
80631  _emberDataPrivateCore["default"].StringTransform = _emberDataPrivateTransforms.StringTransform;
80632  _emberDataPrivateCore["default"].NumberTransform = _emberDataPrivateTransforms.NumberTransform;
80633  _emberDataPrivateCore["default"].BooleanTransform = _emberDataPrivateTransforms.BooleanTransform;
80634
80635  _emberDataPrivateCore["default"].EmbeddedRecordsMixin = _emberDataSerializersEmbeddedRecordsMixin["default"];
80636
80637  _emberDataPrivateCore["default"].belongsTo = _emberDataRelationships.belongsTo;
80638  _emberDataPrivateCore["default"].hasMany = _emberDataRelationships.hasMany;
80639
80640  _emberDataPrivateCore["default"].Relationship = _emberDataPrivateSystemRelationshipsStateRelationship["default"];
80641
80642  _emberDataPrivateCore["default"].ContainerProxy = _emberDataPrivateSystemContainerProxy["default"];
80643
80644  _emberDataPrivateCore["default"]._setupContainer = _emberDataSetupContainer["default"];
80645  _emberDataPrivateCore["default"]._initializeStoreService = _emberDataPrivateInstanceInitializer
80645sInitializeStoreService["default"];
80646
80647  Object.defineProperty(_emberDataPrivateCore["default"], 'normalizeModelName', {
80648    enumerable: true,
80649    writable: false,
80650    configurable: false,
80651    value: _emberDataPrivateSystemNormalizeModelName["default"]
80652  });
80653
80654  Object.defineProperty(_emberDataPrivateGlobal["default"], 'DS', {
80655    configurable: true,
80656    get: function get() {
80657      (0, _emberDataPrivateDebug.deprecate)('Using the global version of DS is deprecated. Please either import ' + 'the specific modules needed or `import DS from \'ember-data\';`.', false, { id: 'ember-data.global-ds', until: '3.0.0' });
80658
80659      return _emberDataPrivateCore["default"];
80660    }
80661  });
80662
80663  exports["default"] = _emberDataPrivateCore["default"];
80664});
80665
80666/**
80667  Ember Data
80668  @module ember-data
80669  @main ember-data
80670*/
80671define("ember-data/model", ["exports", "ember-data/-private/system/model"], function (exports, _emberDataPrivateSystemModel) {
80672  "use strict";
80673
80674  exports["default"] = _emberDataPrivateSystemModel["default"];
80675});
80676define("ember-data/relationships", ["exports", "ember-data/-private/system/relationships/belongs-to", "ember-data/-private/system/relationships/has-many"], function (exports, _emberDataPrivateSystemRelationshipsBelongsTo, _emberDataPrivateSystemRelationshipsHasMany) {
80677  /**
80678    @module ember-data
80679  */
80680
80681  "use strict";
80682
80683  exports.belongsTo = _emberDataPrivateSystemRelationshipsBelongsTo["default"];
80684  exports.hasMany = _emberDataPrivateSystemRelationshipsHasMany["default"];
80685});
80686define('ember-data/serializer', ['exports', 'ember'], function (exports, _ember) {
80687  /**
80688    @module ember-data
80689  */
80690
80691  'use strict';
80692
80693  /**
80694    `DS.Serializer` is an abstract base class that you should override in your
80695    application to customize it for your backend. The minimum set of methods
80696    that you should implement is:
80697  
80698      * `normalizeResponse()`
80699      * `serialize()`
80700  
80701    And you can optionally override the following methods:
80702  
80703      * `normalize()`
80704  
80705    For an example implementation, see
80706    [DS.JSONSerializer](DS.JSONSerializer.html), the included JSON serializer.
80707  
80708    @class Serializer
80709    @namespace DS
80710    @extends Ember.Object
80711  */
80712
80713  exports['default'] = _ember['default'].Object.extend({
80714
80715    /**
80716      The `store` property is the application's `store` that contains all records.
80717      It's injected as a service.
80718      It can be used to push records from a non flat data structure server
80719      response.
80720       @property store
80721      @type {DS.Store}
80722      @public
80723    */
80724
80725    /**
80726      The `normalizeResponse` method is used to normalize a payload from the
80727      server to a JSON-API Document.
80728       http://jsonapi.org/format/#document-structure
80729       @since 1.13.0
80730      @method normalizeResponse
80731      @param {DS.Store} store
80732      @param {DS.Model} primaryModelClass
80733      @param {Object} payload
80734      @param {String|Number} id
80735      @param {String} requestType
80736      @return {Object} JSON-API Document
80737    */
80738    normalizeResponse: null,
80739
80740    /**
80741      The `serialize` method is used when a record is saved in order to convert
80742      the record into the form that your external data source expects.
80743       `serialize` takes an optional `options` hash with a single option:
80744       - `includeId`: If this is `true`, `serialize` should include the ID
80745        in the serialized object it builds.
80746       @method serialize
80747      @param {DS.Model} record
80748      @param {Object} [options]
80749      @return {Object}
80750    */
80751    serialize: null,
80752
80753    /**
80754      The `normalize` method is used to convert a payload received from your
80755      external data source into the normalized form `store.push()` expects. You
80756      should override this method, munge the hash and return the normalized
80757      payload.
80758       @method normalize
80759      @param {DS.Model} typeClass
80760      @param {Object} hash
80761      @return {Object}
80762    */
80763    normalize: function normalize(typeClass, hash) {
80764      return hash;
80765    }
80766
80767  });
80768});
80769define('ember-data/serializers/embedded-records-mixin', ['exports', 'ember', 'ember-data/-private/debug', 'ember-data/-private/features'], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateFeatures) {
80770  'use strict';
80771
80772  function _toConsumableArray(arr) {
80773    if (Array.isArray(arr)) {
80774      for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];return arr2;
80775    } else {
80776      return Array.from(arr);
80777    }
80778  }
80779
80780  var get = _ember['default'].get;
80781  var set = _ember['default'].set;
80782  var camelize = _ember['default'].String.camelize;
80783
80784  /**
80785    ## Using Embedded Records
80786  
80787    `DS.EmbeddedRecordsMixin` supports serializing embedded records.
80788  
80789    To set up embedded records, include the mixin when extending a serializer,
80790    then define and configure embedded (model) relationships.
80791  
80792    Below is an example of a per-type serializer (`post` type).
80793  
80794    ```app/serializers/post.js
80795    import DS from 'ember-data';
80796  
80797    export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
80798      attrs: {
80799        author: { embedded: 'always' },
80800        comments: { serialize: 'ids' }
80801      }
80802    });
80803    ```
80804    Note that this use of `{ embedded: 'always' }` is unrelated to
80805    the `{ embedded: 'always' }` that is defined as an option on `DS.attr` as part of
80806    defining a model while working with the `ActiveModelSerializer`.  Nevertheless,
80807    using `{ embedded: 'always' }` as an option to `DS.attr` is not a valid way to setup
80808    embedded records.
80809  
80810    The `attrs` option for a resource `{ embedded: 'always' }` is shorthand for:
80811  
80812    ```js
80813    {
80814      serialize: 'records',
80815      deserialize: 'records'
80816    }
80817    ```
80818  
80819    ### Configuring Attrs
80820  
80821    A resource's `attrs` option may be set to use `ids`, `records` or false for the
80822    `serialize`  and `deserialize` settings.
80823  
80824    The `attrs` property can be set on the `ApplicationSerializer` or a per-type
80825    serializer.
80826  
80827    In the case where embedded JSON is expected while extracting a payload (reading)
80828    the setting is `deserialize: 'records'`, there is no need to use `ids` when
80829    extracting as that is the default behavior without this mixin if you are using
80830    the vanilla `EmbeddedRecordsMixin`. Likewise, to embed JSON in the payload while
80831    serializing `serialize: 'records'` is the setting to use. There is an option of
80832    not embedding JSON in the serialized payload by using `serialize: 'ids'`. If you
80833    do not want the relationship sent at all, you can use `serialize: false`.
80834  
80835  
80836    ### EmbeddedRecordsMixin defaults
80837    If you do not overwrite `attrs` for a specific relationship, the `EmbeddedRecordsMixin`
80838    will behave in the following way:
80839  
80840    BelongsTo: `{ serialize: 'id', deserialize: 'id' }`
80841    HasMany:   `{ serialize: false, deserialize: 'ids' }`
80842  
80843    ### Model Relationships
80844  
80845    Embedded records must have a model defined to be extracted and serialized. Note that
80846    when defining any relationships on your model such as `belongsTo` and `hasMany`, you
80847    should not both specify `async: true` and also indicate through the serializer's
80848    `attrs` attribute that the related model should be embedded for deserialization.
80849    If a model is declared embedded for deserialization (`embedded: 'always'` or `deserialize: 'records'`),
80850    then do not use `async: true`.
80851  
80852    To successfully extract and serialize embedded records the model relationships
80853    must be setup correcty. See the
80854    [defining relationships](/guides/models/defining-models/#toc_defining-relationships)
80855    section of the **Defining Models** guide page.
80856  
80857    Records without an `id` property are not considered embedded records, model
80858    instances must have an `id` property to be used with Ember Data.
80859  
80860    ### Example JSON payloads, Models and Serializers
80861  
80862    **When customizing a serializer it is important to grok what the customizations
80863    are. Please read the docs for the methods this mixin provides, in case you need
80864    to modify it to fit your specific needs.**
80865  
80866    For example review the docs for each method of this mixin:
80867    * [normalize](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_normalize)
80868    * [serializeBelongsTo](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeBelongsTo)
80869    * [serializeHasMany](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeHasMany)
80870  
80871    @class EmbeddedRecordsMixin
80872    @namespace DS
80873  */
80874  exports['default'] = _ember['default'].Mixin.create({
80875
80876    /**
80877      Normalize the record and recursively normalize/extract all the embedded records
80878      while pushing them into the store as they are encountered
80879       A payload with an attr configured for embedded records needs to be extracted:
80880       ```js
80881      {
80882        "post": {
80883          "id": "1"
80884          "title": "Rails is omakase",
80885          "comments": [{
80886            "id": "1",
80887            "body": "Rails is unagi"
80888          }, {
80889            "id": "2",
80890            "body": "Omakase O_o"
80891          }]
80892        }
80893      }
80894      ```
80895     @method normalize
80896     @param {DS.Model} typeClass
80897     @param {Object} hash to be normalized
80898     @param {String} prop the hash has been referenced by
80899     @return {Object} the normalized hash
80900    **/
80901    normalize: function normalize(typeClass, hash, prop) {
80902      var normalizedHash = this._super(typeClass, hash, prop);
80903      return this._extractEmbeddedRecords(this, this.store, typeClass, normalizedHash);
80904    },
80905
80906    keyForRelationship: function keyForRelationship(key, typeClass, method) {
80907      if (method === 'serialize' && this.hasSerializeRecordsOption(key) || method === 'deserialize' && this.hasDeserializeRecordsOption(key)) {
80908        return this.keyForAttribute(key, method);
80909      } else {
80910        return this._super(key, typeClass, method) || key;
80911      }
80912    },
80913
80914    /**
80915      Serialize `belongsTo` relationship when it is configured as an embedded object.
80916       This example of an author model belongs to a post model:
80917       ```js
80918      Post = DS.Model.extend({
80919        title:    DS.attr('string'),
80920        body:     DS.attr('string'),
80921        author:   DS.belongsTo('author')
80922      });
80923       Author = DS.Model.extend({
80924        name:     DS.attr('string'),
80925        post:     DS.belongsTo('post')
80926      });
80927      ```
80928       Use a custom (type) serializer for the post model to configure embedded author
80929       ```app/serializers/post.js
80930      import DS from 'ember-data';
80931       export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
80932        attrs: {
80933          author: { embedded: 'always' }
80934        }
80935      })
80936      ```
80937       A payload with an attribute configured for embedded records can serialize
80938      the records together under the root attribute's payload:
80939       ```js
80940      {
80941        "post": {
80942          "id": "1"
80943          "title": "Rails is omakase",
80944          "author": {
80945            "id": "2"
80946            "name": "dhh"
80947          }
80948        }
80949      }
80950      ```
80951       @method serializeBelongsTo
80952      @param {DS.Snapshot} snapshot
80953      @param {Object} json
80954      @param {Object} relationship
80955    */
80956    serializeBelongsTo: function serializeBelongsTo(snapshot, json, relationship) {
80957      var attr = relationship.key;
80958      if (this.noSerializeOptionSpecified(attr)) {
80959        this._super(snapshot, json, relationship);
80960        return;
80961      }
80962      var includeIds = this.hasSerializeIdsOption(attr);
80963      var includeRecords = this.hasSerializeRecordsOption(attr);
80964      var embeddedSnapshot = snapshot.belongsTo(attr);
80965      var key;
80966      if (includeIds) {
80967        key = this.keyForRelationship(attr, relationship.kind, 'serialize');
80968        if (!embeddedSnapshot) {
80969          json[key] = null;
80970        } else {
80971          json[key] = embeddedSnapshot.id;
80972
80973          if (relationship.options.polymorphic) {
80974            this.serializePolymorphicType(snapshot, json, relationship);
80975          }
80976        }
80977      } else if (includeRecords) {
80978        this._serializeEmbeddedBelongsTo(snapshot, json, relationship);
80979      }
80980    },
80981
80982    _serializeEmbeddedBelongsTo: function _serializeEmbeddedBelongsTo(snapshot, json, relationship) {
80983      var embeddedSnapshot = snapshot.belongsTo(relationship.key);
80984      var serializedKey = this._getMappedKey(relationship.key, snapshot.type);
80985      if (serializedKey === relationship.key && this.keyForRelationship) {
80986        serializedKey = this.keyForRelationship(relationship.key, relationship.kind, "serialize");
80987      }
80988
80989      if (!embeddedSnapshot) {
80990        json[serializedKey] = null;
80991      } else {
80992        json[serializedKey] = embeddedSnapshot.serialize({ includeId: true });
80993        this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, json[serializedKey]);
80994
80995        if (relationship.options.polymorphic) {
80996          this.serializePolymorphicType(snapshot, json, relationship);
80997        }
80998      }
80999    },
81000
81001    /**
81002      Serializes `hasMany` relationships when it is configured as embedded objects.
81003       This example of a post model has many comments:
81004       ```js
81005      Post = DS.Model.extend({
81006        title:    DS.attr('string'),
81007        body:     DS.attr('string'),
81008        comments: DS.hasMany('comment')
81009      });
81010       Comment = DS.Model.extend({
81011        body:     DS.attr('string'),
81012        post:     DS.belongsTo('post')
81013      });
81014      ```
81015       Use a custom (type) serializer for the post model to configure embedded comments
81016       ```app/serializers/post.js
81017      import DS from 'ember-data;
81018       export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
81019        attrs: {
81020          comments: { embedded: 'always' }
81021        }
81022      })
81023      ```
81024       A payload with an attribute configured for embedded records can serialize
81025      the records together under the root attribute's payload:
81026       ```js
81027      {
81028        "post": {
81029          "id": "1"
81030          "title": "Rails is omakase",
81031          "body": "I want this for my ORM, I want that for my template language..."
81032          "comments": [{
81033            "id": "1",
81034            "body": "Rails is unagi"
81035          }, {
81036            "id": "2",
81037            "body": "Omakase O_o"
81038          }]
81039        }
81040      }
81041      ```
81042       The attrs options object can use more specific instruction for extracting and
81043      serializing. When serializing, an option to embed `ids`, `ids-and-types` or `records` can be set.
81044      When extracting the only option is `records`.
81045       So `{ embedded: 'always' }` is shorthand for:
81046      `{ serialize: 'records', deserialize: 'records' }`
81047       To embed the `ids` for a related object (using a hasMany relationship):
81048       ```app/serializers/post.js
81049      import DS from 'ember-data;
81050       export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
81051        attrs: {
81052          comments: { serialize: 'ids', deserialize: 'records' }
81053        }
81054      })
81055      ```
81056       ```js
81057      {
81058        "post": {
81059          "id": "1"
81060          "title": "Rails is omakase",
81061          "body": "I want this for my ORM, I want that for my template language..."
81062          "comments": ["1", "2"]
81063        }
81064      }
81065      ```
81066       To embed the relationship as a collection of objects with `id` and `type` keys, set
81067      `ids-and-types` for the related object.
81068       This is particularly useful for polymorphic relationships where records don't share
81069      the same table and the `id` is not enough information.
81070       By example having a user that has many pets:
81071       ```js
81072      User = DS.Model.extend({
81073        name:    DS.attr('string'),
81074        pets: DS.hasMany('pet', { polymorphic: true })
81075      });
81076       Pet = DS.Model.extend({
81077        name: DS.attr('string'),
81078      });
81079       Cat = Pet.extend({
81080        // ...
81081      });
81082       Parrot = Pet.extend({
81083        // ...
81084      });
81085      ```
81086       ```app/serializers/user.js
81087      import DS from 'ember-data;
81088       export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
81089        attrs: {
81090          pets: { serialize: 'ids-and-types', deserialize: 'records' }
81091        }
81092      });
81093      ```
81094       ```js
81095      {
81096        "user": {
81097          "id": "1"
81098          "name": "Bertin Osborne",
81099          "pets": [
81100            { "id": "1", "type": "Cat" },
81101            { "id": "1", "type": "Parrot"}
81102          ]
81103        }
81104      }
81105      ```
81106       Note that the `ids-and-types` strategy is still behind the `ds-serialize-ids-and-types` feature flag.
81107       @method serializeHasMany
81108      @param {DS.Snapshot} snapshot
81109      @param {Object} json
81110      @param {Object} relationship
81111    */
81112    serializeHasMany: function serializeHasMany(snapshot, json, relationship) {
81113      var attr = relationship.key;
81114      if (this.noSerializeOptionSpecified(attr)) {
81115        this._super(snapshot, json, relationship);
81116        return;
81117      }
81118
81119      if (this.hasSerializeIdsOption(attr)) {
81120        var serializedKey = this.keyForRelationship(attr, relationship.kind, 'serialize');
81121        json[serializedKey] = snapshot.hasMany(attr, { ids: true });
81122      } else if (this.hasSerializeRecordsOption(attr)) {
81123        this._serializeEmbeddedHasMany(snapshot, json, relationship);
81124      } else {
81125        if (true) {
81126          if (this.hasSerializeIdsAndTypesOption(attr)) {
81127            this._serializeHasManyAsIdsAndTypes(snapshot, json, relationship);
81128          }
81129        }
81130      }
81131    },
81132
81133    /**
81134      Serializes a hasMany relationship as an array of objects containing only `id` and `type`
81135      keys.
81136      This has its use case on polymorphic hasMany relationships where the server is not storing
81137      all records in the same table using STI, and therefore the `id` is not enough information
81138       TODO: Make the default in Ember-data 3.0??
81139    */
81140    _serializeHasManyAsIdsAndTypes: function _serializeHasManyAsIdsAndTypes(snapshot, json, relationship) {
81141      var serializedKey = this.keyForAttribute(relationship.key, 'serialize');
81142      var hasMany = snapshot.hasMany(relationship.key);
81143
81144      json[serializedKey] = _ember['default'].A(hasMany).map(function (recordSnapshot) {
81145        //
81146        // I'm sure I'm being utterly naive here. Propably id is a configurate property and
81147        // type too, and the modelName has to be normalized somehow.
81148        //
81149        return { id: recordSnapshot.id, type: recordSnapshot.modelName };
81150      });
81151    },
81152
81153    _serializeEmbeddedHasMany: function _serializeEmbeddedHasMany(snapshot, json, relationship) {
81154      var serializedKey = this._getMappedKey(relationship.key, snapshot.type);
81155      if (serializedKey === relationship.key && this.keyForRelationship) {
81156        serializedKey = this.keyForRelationship(relationship.key, relationship.kind, "serialize");
81157      }
81158
81159      (0, _emberDataPrivateDebug.warn)('The embedded relationship \'' + serializedKey + '\' is undefined for \'' + snapshot.modelName + '\' with i
81159d \'' + snapshot.id + '\'. Please include it in your original payload.', _ember['default'].typeOf(snapshot.hasMany(relationship.key)) !== 'undefined', { id: 'ds.serializer.embedded-relationship-undefined' });
81160
81161      json[serializedKey] = this._generateSerializedHasMany(snapshot, relationship);
81162    },
81163
81164    /*
81165      Returns an array of embedded records serialized to JSON
81166    */
81167    _generateSerializedHasMany: function _generateSerializedHasMany(snapshot, relationship) {
81168      var hasMany = snapshot.hasMany(relationship.key);
81169      var manyArray = _ember['default'].A(hasMany);
81170      var ret = new Array(manyArray.length);
81171
81172      for (var i = 0; i < manyArray.length; i++) {
81173        var embeddedSnapshot = manyArray[i];
81174        var embeddedJson = embeddedSnapshot.serialize({ includeId: true });
81175        this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, embeddedJson);
81176        ret[i] = embeddedJson;
81177      }
81178
81179      return ret;
81180    },
81181
81182    /**
81183      When serializing an embedded record, modify the property (in the json payload)
81184      that refers to the parent record (foreign key for relationship).
81185       Serializing a `belongsTo` relationship removes the property that refers to the
81186      parent record
81187       Serializing a `hasMany` relationship does not remove the property that refers to
81188      the parent record.
81189       @method removeEmbeddedForeignKey
81190      @param {DS.Snapshot} snapshot
81191      @param {DS.Snapshot} embeddedSnapshot
81192      @param {Object} relationship
81193      @param {Object} json
81194    */
81195    removeEmbeddedForeignKey: function removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, json) {
81196      if (relationship.kind === 'hasMany') {
81197        return;
81198      } else if (relationship.kind === 'belongsTo') {
81199        var parentRecord = snapshot.type.inverseFor(relationship.key, this.store);
81200        if (parentRecord) {
81201          var name = parentRecord.name;
81202          var embeddedSerializer = this.store.serializerFor(embeddedSnapshot.modelName);
81203          var parentKey = embeddedSerializer.keyForRelationship(name, parentRecord.kind, 'deserialize');
81204          if (parentKey) {
81205            delete json[parentKey];
81206          }
81207        }
81208      }
81209    },
81210
81211    // checks config for attrs option to embedded (always) - serialize and deserialize
81212    hasEmbeddedAlwaysOption: function hasEmbeddedAlwaysOption(attr) {
81213      var option = this.attrsOption(attr);
81214      return option && option.embedded === 'always';
81215    },
81216
81217    // checks config for attrs option to serialize ids
81218    hasSerializeRecordsOption: function hasSerializeRecordsOption(attr) {
81219      var alwaysEmbed = this.hasEmbeddedAlwaysOption(attr);
81220      var option = this.attrsOption(attr);
81221      return alwaysEmbed || option && option.serialize === 'records';
81222    },
81223
81224    // checks config for attrs option to serialize records
81225    hasSerializeIdsOption: function hasSerializeIdsOption(attr) {
81226      var option = this.attrsOption(attr);
81227      return option && (option.serialize === 'ids' || option.serialize === 'id');
81228    },
81229
81230    // checks config for attrs option to serialize records as objects containing id and types
81231    hasSerializeIdsAndTypesOption: function hasSerializeIdsAndTypesOption(attr) {
81232      var option = this.attrsOption(attr);
81233      return option && (option.serialize === 'ids-and-types' || option.serialize === 'id-and-type');
81234    },
81235
81236    // checks config for attrs option to serialize records
81237    noSerializeOptionSpecified: function noSerializeOptionSpecified(attr) {
81238      var option = this.attrsOption(attr);
81239      return !(option && (option.serialize || option.embedded));
81240    },
81241
81242    // checks config for attrs option to deserialize records
81243    // a defined option object for a resource is treated the same as
81244    // `deserialize: 'records'`
81245    hasDeserializeRecordsOption: function hasDeserializeRecordsOption(attr) {
81246      var alwaysEmbed = this.hasEmbeddedAlwaysOption(attr);
81247      var option = this.attrsOption(attr);
81248      return alwaysEmbed || option && option.deserialize === 'records';
81249    },
81250
81251    attrsOption: function attrsOption(attr) {
81252      var attrs = this.get('attrs');
81253      return attrs && (attrs[camelize(attr)] || attrs[attr]);
81254    },
81255
81256    /**
81257     @method _extractEmbeddedRecords
81258     @private
81259    */
81260    _extractEmbeddedRecords: function _extractEmbeddedRecords(serializer, store, typeClass, partial) {
81261      var _this = this;
81262
81263      typeClass.eachRelationship(function (key, relationship) {
81264        if (serializer.hasDeserializeRecordsOption(key)) {
81265          if (relationship.kind === "hasMany") {
81266            _this._extractEmbeddedHasMany(store, key, partial, relationship);
81267          }
81268          if (relationship.kind === "belongsTo") {
81269            _this._extractEmbeddedBelongsTo(store, key, partial, relationship);
81270          }
81271        }
81272      });
81273      return partial;
81274    },
81275
81276    /**
81277     @method _extractEmbeddedHasMany
81278     @private
81279    */
81280    _extractEmbeddedHasMany: function _extractEmbeddedHasMany(store, key, hash, relationshipMeta) {
81281      var relationshipHash = get(hash, 'data.relationships.' + key + '.data');
81282
81283      if (!relationshipHash) {
81284        return;
81285      }
81286
81287      var hasMany = new Array(relationshipHash.length);
81288
81289      for (var i = 0; i < relationshipHash.length; i++) {
81290        var item = relationshipHash[i];
81291
81292        var _normalizeEmbeddedRelationship2 = this._normalizeEmbeddedRelationship(store, relationshipMeta, item);
81293
81294        var data = _normalizeEmbeddedRelationship2.data;
81295        var included = _normalizeEmbeddedRelationship2.included;
81296
81297        hash.included = hash.included || [];
81298        hash.included.push(data);
81299        if (included) {
81300          var _hash$included;
81301
81302          (_hash$included = hash.included).push.apply(_hash$included, _toConsumableArray(included));
81303        }
81304
81305        hasMany[i] = { id: data.id, type: data.type };
81306      }
81307
81308      var relationship = { data: hasMany };
81309      set(hash, 'data.relationships.' + key, relationship);
81310    },
81311
81312    /**
81313     @method _extractEmbeddedBelongsTo
81314     @private
81315    */
81316    _extractEmbeddedBelongsTo: function _extractEmbeddedBelongsTo(store, key, hash, relationshipMeta) {
81317      var relationshipHash = get(hash, 'data.relationships.' + key + '.data');
81318      if (!relationshipHash) {
81319        return;
81320      }
81321
81322      var _normalizeEmbeddedRelationship3 = this._normalizeEmbeddedRelationship(store, relationshipMeta, relationshipHash);
81323
81324      var data = _normalizeEmbeddedRelationship3.data;
81325      var included = _normalizeEmbeddedRelationship3.included;
81326
81327      hash.included = hash.included || [];
81328      hash.included.push(data);
81329      if (included) {
81330        var _hash$included2;
81331
81332        (_hash$included2 = hash.included).push.apply(_hash$included2, _toConsumableArray(included));
81333      }
81334
81335      var belongsTo = { id: data.id, type: data.type };
81336      var relationship = { data: belongsTo };
81337
81338      set(hash, 'data.relationships.' + key, relationship);
81339    },
81340
81341    /**
81342     @method _normalizeEmbeddedRelationship
81343     @private
81344    */
81345    _normalizeEmbeddedRelationship: function _normalizeEmbeddedRelationship(store, relationshipMeta, relationshipHash) {
81346      var modelName = relationshipMeta.type;
81347      if (relationshipMeta.options.polymorphic) {
81348        modelName = relationshipHash.type;
81349      }
81350      var modelClass = store.modelFor(modelName);
81351      var serializer = store.serializerFor(modelName);
81352
81353      return serializer.normalize(modelClass, relationshipHash, null);
81354    },
81355    isEmbeddedRecordsMixin: true
81356  });
81357});
81358define('ember-data/serializers/json-api', ['exports', 'ember', 'ember-data/-private/debug', 'ember-data/serializers/json', 'ember-data/-private/system/normalize-model-name', 'ember-inflector', 'ember-data/-private/features'], function (exports, _ember, _emberDataPrivateDebug, _emberDataSerializersJson, _emberDataPrivateSystemNormalizeModelName, _emberInflector, _emberDataPrivateFeatures) {
81359  /**
81360    @module ember-data
81361  */
81362
81363  'use strict';
81364
81365  var dasherize = _ember['default'].String.dasherize;
81366
81367  /**
81368    Ember Data 2.0 Serializer:
81369  
81370    In Ember Data a Serializer is used to serialize and deserialize
81371    records when they are transferred in and out of an external source.
81372    This process involves normalizing property names, transforming
81373    attribute values and serializing relationships.
81374  
81375    `JSONAPISerializer` supports the http://jsonapi.org/ spec and is the
81376    serializer recommended by Ember Data.
81377  
81378    This serializer normalizes a JSON API payload that looks like:
81379  
81380    ```js
81381  
81382      
81382// models/player.js
81383      import DS from "ember-data";
81384  
81385      export default DS.Model.extend({
81386        name: DS.attr(),
81387        skill: DS.attr(),
81388        gamesPlayed: DS.attr(),
81389        club: DS.belongsTo('club')
81390      });
81391  
81392      
81392// models/club.js
81393      import DS from "ember-data";
81394  
81395      export default DS.Model.extend({
81396        name: DS.attr(),
81397        location: DS.attr(),
81398        players: DS.hasMany('player')
81399      });
81400    ```
81401  
81402    ```js
81403  
81404      {
81405        "data": [
81406          {
81407            "attributes": {
81408              "name": "Benfica",
81409              "location": "Portugal"
81410            },
81411            "id": "1",
81412            "relationships": {
81413              "players": {
81414                "data": [
81415                  {
81416                    "id": "3",
81417                    "type": "players"
81418                  }
81419                ]
81420              }
81421            },
81422            "type": "clubs"
81423          }
81424        ],
81425        "included": [
81426          {
81427            "attributes": {
81428              "name": "Eusebio Silva Ferreira",
81429              "skill": "Rocket shot",
81430              "games-played": 431
81431            },
81432            "id": "3",
81433            "relationships": {
81434              "club": {
81435                "data": {
81436                  "id": "1",
81437                  "type": "clubs"
81438                }
81439              }
81440            },
81441            "type": "players"
81442          }
81443        ]
81444      }
81445    ```
81446  
81447    to the format that the Ember Data store expects.
81448  
81449    @since 1.13.0
81450    @class JSONAPISerializer
81451    @namespace DS
81452    @extends DS.JSONSerializer
81453  */
81454  var JSONAPISerializer = _emberDataSerializersJson['default'].extend({
81455
81456    /**
81457      @method _normalizeDocumentHelper
81458      @param {Object} documentHash
81459      @return {Object}
81460      @private
81461    */
81462    _normalizeDocumentHelper: function _normalizeDocumentHelper(documentHash) {
81463
81464      if (_ember['default'].typeOf(documentHash.data) === 'object') {
81465        documentHash.data = this._normalizeResourceHelper(documentHash.data);
81466      } else if (Array.isArray(documentHash.data)) {
81467        var ret = new Array(documentHash.data.length);
81468
81469        for (var i = 0; i < documentHash.data.length; i++) {
81470          var data = documentHash.data[i];
81471          ret[i] = this._normalizeResourceHelper(data);
81472        }
81473
81474        documentHash.data = ret;
81475      }
81476
81477      if (Array.isArray(documentHash.included)) {
81478        var ret = new Array(documentHash.included.length);
81479
81480        for (var i = 0; i < documentHash.included.length; i++) {
81481          var included = documentHash.included[i];
81482          ret[i] = this._normalizeResourceHelper(included);
81483        }
81484
81485        documentHash.included = ret;
81486      }
81487
81488      return documentHash;
81489    },
81490
81491    /**
81492      @method _normalizeRelationshipDataHelper
81493      @param {Object} relationshipDataHash
81494      @return {Object}
81495      @private
81496    */
81497    _normalizeRelationshipDataHelper: function _normalizeRelationshipDataHelper(relationshipDataHash) {
81498      if (false) {
81499        var modelName = this.modelNameFromPayloadType(relationshipDataHash.type);
81500        var deprecatedModelNameLookup = this.modelNameFromPayloadKey(relationshipDataHash.type);
81501
81502        if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) {
81503          (0, _emberDataPrivateDebug.deprecate)("You are using modelNameFromPayloadKey to normalize the type for a relationship. This has been deprecated in favor of modelNameFromPayloadType", false, {
81504            id: 'ds.json-api-serializer.deprecated-model-name-for-relationship',
81505            until: '3.0.0'
81506          });
81507
81508          modelName = deprecatedModelNameLookup;
81509        }
81510
81511        relationshipDataHash.type = modelName;
81512      } else {
81513        var type = this.modelNameFromPayloadKey(relationshipDataHash.type);
81514        relationshipDataHash.type = type;
81515      }
81516
81517      return relationshipDataHash;
81518    },
81519
81520    /**
81521      @method _normalizeResourceHelper
81522      @param {Object} resourceHash
81523      @return {Object}
81524      @private
81525    */
81526    _normalizeResourceHelper: function _normalizeResourceHelper(resourceHash) {
81527      (0, _emberDataPrivateDebug.assert)(this.warnMessageForUndefinedType(), !_ember['default'].isNone(resourceHash.type), {
81528        id: 'ds.serializer.type-is-undefined'
81529      });
81530
81531      var modelName = undefined,
81532          usedLookup = undefined;
81533
81534      if (false) {
81535        modelName = this.modelNameFromPayloadType(resourceHash.type);
81536        var deprecatedModelNameLookup = this.modelNameFromPayloadKey(resourceHash.type);
81537
81538        usedLookup = 'modelNameFromPayloadType';
81539
81540        if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) {
81541          (0, _emberDataPrivateDebug.deprecate)("You are using modelNameFromPayloadKey to normalize the type for a resource. This has been deprecated in favor of modelNameFromPayloadType", false, {
81542            id: 'ds.json-api-serializer.deprecated-model-name-for-resource',
81543            until: '3.0.0'
81544          });
81545
81546          modelName = deprecatedModelNameLookup;
81547          usedLookup = 'modelNameFromPayloadKey';
81548        }
81549      } else {
81550        modelName = this.modelNameFromPayloadKey(resourceHash.type);
81551        usedLookup = 'modelNameFromPayloadKey';
81552      }
81553
81554      if (!this.store._hasModelFor(modelName)) {
81555        (0, _emberDataPrivateDebug.warn)(this.warnMessageNoModelForType(modelName, resourceHash.type, usedLookup), false, {
81556          id: 'ds.serializer.model-for-type-missing'
81557        });
81558        return null;
81559      }
81560
81561      var modelClass = this.store.modelFor(modelName);
81562      var serializer = this.store.serializerFor(modelName);
81563
81564      var _serializer$normalize = serializer.normalize(modelClass, resourceHash);
81565
81566      var data = _serializer$normalize.data;
81567
81568      return data;
81569    },
81570
81571    /**
81572      @method pushPayload
81573      @param {DS.Store} store
81574      @param {Object} payload
81575    */
81576    pushPayload: function pushPayload(store, payload) {
81577      var normalizedPayload = this._normalizeDocumentHelper(payload);
81578      if (false) {
81579        return store.push(normalizedPayload);
81580      } else {
81581        store.push(normalizedPayload);
81582      }
81583    },
81584
81585    /**
81586      @method _normalizeResponse
81587      @param {DS.Store} store
81588      @param {DS.Model} primaryModelClass
81589      @param {Object} payload
81590      @param {String|Number} id
81591      @param {String} requestType
81592      @param {Boolean} isSingle
81593      @return {Object} JSON-API Document
81594      @private
81595    */
81596    _normalizeResponse: function _normalizeResponse(store, primaryModelClass, payload, id, requestType, isSingle) {
81597      var normalizedPayload = this._normalizeDocumentHelper(payload);
81598      return normalizedPayload;
81599    },
81600
81601    normalizeQueryRecordResponse: function normalizeQueryRecordResponse() {
81602      var normalized = this._super.apply(this, arguments);
81603
81604      (0, _emberDataPrivateDebug.assert)('Expected the primary data returned by the serializer for a `queryRecord` response to be a single object but instead it was an array.', !Array.isArray(normalized.data), {
81605        id: 'ds.serializer.json-api.queryRecord-array-response'
81606      });
81607
81608      return normalized;
81609    },
81610
81611    /**
81612      @method extractAttributes
81613      @param {DS.Model} modelClass
81614      @param {Object} resourceHash
81615      @return {Object}
81616    */
81617    extractAttributes: function extractAttributes(modelClass, resourceHash) {
81618      var _this = this;
81619
81620      var attributes = {};
81621
81622      if (resourceHash.attributes) {
81623        modelClass.eachAttribute(function (key) {
81624          var attributeKey = _this.keyForAttribute(key, 'deserialize');
81625          if (resourceHash.attributes[attributeKey] !== undefined) {
81626            attributes[key] = resourceHash.attributes[attributeKey];
81627          }
81628        });
81629      }
81630
81631      return attributes;
81632    },
81633
81634    /**
81635      @method extractRelationship
81636      @param {Object} relationshipHash
81637      @return {Object}
81638    */
81639    extractRelationship: function extractRelationship(relationshipHash) {
81640
81641      if (_ember['default'].typeOf(relationshipHash.data) === 'object') {
81642        relationshipHash.data = this._normalizeRelationshipDataHelper(relationshipHash.data);
81643      }
81644
81645      if (Array.isArray(relationshipHash.data)) {
81646        var ret = new Array(relationshipHash.data.length);
81647
81648        for (var i = 0; i < relationshipHash.data.length; i++) {
81649          var data = relationshipHash.data[i];
81650          ret[i] = this._normalizeRelationshipDataHelper(data);
81651        }
81652
81653        relationshipHash.data = ret;
81654      }
81655
81656      return relationshipHash;
81657    },
81658
81659    /**
81660      @method extractRelationships
81661      @param {Object} modelClass
81662      @param {Object} resourceHash
81663      @return {Object}
81664    */
81665    extractRelationships: function extractRelationships(modelClass, resourceHash) {
81666      var _this2 = this;
81667
81668      var relationships = {};
81669
81670      if (resourceHash.relationships) {
81671        modelClass.eachRelationship(function (key, relationshipMeta) {
81672          var relationshipKey = _this2.keyForRelationship(key, relationshipMeta.kind, 'deserialize');
81673          if (resourceHash.relationships[relationshipKey] !== undefined) {
81674
81675            var relationshipHash = resourceHash.relationships[relationshipKey];
81676            relationships[key] = _this2.extractRelationship(relationshipHash);
81677          }
81678        });
81679      }
81680
81681      return relationships;
81682    },
81683
81684    /**
81685      @method _extractType
81686      @param {DS.Model} modelClass
81687      @param {Object} resourceHash
81688      @return {String}
81689      @private
81690    */
81691    _extractType: function _extractType(modelClass, resourceHash) {
81692      if (false) {
81693        var modelName = this.modelNameFromPayloadType(resourceHash.type);
81694        var deprecatedModelNameLookup = this.modelNameFromPayloadKey(resourceHash.type);
81695
81696        if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) {
81697          (0, _emberDataPrivateDebug.deprecate)("You are using modelNameFromPayloadKey to normalize the type for a polymorphic relationship. This has been deprecated in favor of modelNameFromPayloadType", false, {
81698            id: 'ds.json-api-serializer.deprecated-model-name-for-polymorphic-type',
81699            until: '3.0.0'
81700          });
81701
81702          modelName = deprecatedModelNameLookup;
81703        }
81704
81705        return modelName;
81706      } else {
81707        return this.modelNameFromPayloadKey(resourceHash.type);
81708      }
81709    },
81710
81711    /**
81712      @method modelNameFromPayloadKey
81713      @param {String} key
81714      @return {String} the model's modelName
81715    */
81716    // TODO @deprecated Use modelNameFromPayloadType instead
81717    modelNameFromPayloadKey: function modelNameFromPayloadKey(key) {
81718      return (0, _emberInflector.singularize)((0, _emberDataPrivateSystemNormalizeModelName['default'])(key));
81719    },
81720
81721    /**
81722      @method payloadKeyFromModelName
81723      @param {String} modelName
81724      @return {String}
81725    */
81726    // TODO @deprecated Use payloadTypeFromModelName instead
81727    payloadKeyFromModelName: function payloadKeyFromModelName(modelName) {
81728      return (0, _emberInflector.pluralize)(modelName);
81729    },
81730
81731    /**
81732      @method normalize
81733      @param {DS.Model} modelClass
81734      @param {Object} resourceHash the resource hash from the adapter
81735      @return {Object} the normalized resource hash
81736    */
81737    normalize: function normalize(modelClass, resourceHash) {
81738      if (resourceHash.attributes) {
81739        this.normalizeUsingDeclaredMapping(modelClass, resourceHash.attributes);
81740      }
81741
81742      if (resourceHash.relationships) {
81743        this.normalizeUsingDeclaredMapping(modelClass, resourceHash.relationships);
81744      }
81745
81746      var data = {
81747        id: this.extractId(modelClass, resourceHash),
81748        type: this._extractType(modelClass, resourceHash),
81749        attributes: this.extractAttributes(modelClass, resourceHash),
81750        relationships: this.extractRelationships(modelClass, resourceHash)
81751      };
81752
81753      this.applyTransforms(modelClass, data.attributes);
81754
81755      return { data: data };
81756    },
81757
81758    /**
81759     `keyForAttribute` can be used to define rules for how to convert an
81760     attribute name in your model to a key in your JSON.
81761     By default `JSONAPISerializer` follows the format used on the examples of
81762     http://jsonapi.org/format and uses dashes as the word separator in the JSON
81763     attribute keys.
81764      This behaviour can be easily customized by extending this method.
81765      Example
81766      ```app/serializers/application.js
81767     import DS from 'ember-data';
81768      export default DS.JSONAPISerializer.extend({
81769       keyForAttribute: function(attr, method) {
81770         return Ember.String.dasherize(attr).toUpperCase();
81771       }
81772     });
81773     ```
81774      @method keyForAttribute
81775     @param {String} key
81776     @param {String} method
81777     @return {String} normalized key
81778    */
81779    keyForAttribute: function keyForAttribute(key, method) {
81780      return dasherize(key);
81781    },
81782
81783    /**
81784     `keyForRelationship` can be used to define a custom key when
81785     serializing and deserializing relationship properties.
81786     By default `JSONAPISerializer` follows the format used on the examples of
81787     http://jsonapi.org/format and uses dashes as word separators in
81788     relationship properties.
81789      This behaviour can be easily customized by extending this method.
81790      Example
81791       ```app/serializers/post.js
81792      import DS from 'ember-data';
81793       export default DS.JSONAPISerializer.extend({
81794        keyForRelationship: function(key, relationship, method) {
81795          return Ember.String.underscore(key);
81796        }
81797      });
81798      ```
81799     @method keyForRelationship
81800     @param {String} key
81801     @param {String} typeClass
81802     @param {String} method
81803     @return {String} normalized key
81804    */
81805    keyForRelationship: function keyForRelationship(key, typeClass, method) {
81806      return dasherize(key);
81807    },
81808
81809    /**
81810      @method serialize
81811      @param {DS.Snapshot} snapshot
81812      @param {Object} options
81813      @return {Object} json
81814    */
81815    serialize: function serialize(snapshot, options) {
81816      var data = this._super.apply(this, arguments);
81817
81818      var payloadType = undefined;
81819      if (false) {
81820        payloadType = this.payloadTypeFromModelName(snapshot.modelName);
81821        var deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(snapshot.modelName);
81822
81823        if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) {
81824          (0, _emberDataPrivateDebug.deprecate)("You used payloadKeyFromModelName to customize how a type is serialized. Use payloadTypeFromModelName instead.", false, {
81825            id: 'ds.json-api-serializer.deprecated-payload-type-for-model',
81826            until: '3.0.0'
81827          });
81828
81829          payloadType = deprecatedPayloadTypeLookup;
81830        }
81831      } else {
81832        payloadType = this.payloadKeyFromModelName(snapshot.modelName);
81833      }
81834
81835      data.type = payloadType;
81836      return { data: data };
81837    },
81838
81839    /**
81840     @method serializeAttribute
81841     @param {DS.Snapshot} snapshot
81842     @param {Object} json
81843     @param {String} key
81844     @param {Object} attribute
81845    */
81846    serializeAttribute: function serializeAttribute(snapshot, json, key, attribute) {
81847      var type = attribute.type;
81848
81849      if (this._canSerialize(key)) {
81850        json.attributes = json.attributes || {};
81851
81852        var value = snapshot.attr(key);
81853        if (type) {
81854          var transform = this.transformFor(type);
81855          value = transform.serialize(value, attribute.options);
81856        }
81857
81858        var payloadKey = this._getMappedKey(key, snapshot.type);
81859
81860        if (payloadKey === key) {
81861          payloadKey = this.keyForAttribute(key, 'serialize');
81862        }
81863
81864        json.attributes[payloadKey] = value;
81865      }
81866    },
81867
81868    /**
81869     @method serializeBelongsTo
81870     @param {DS.Snapshot} snapshot
81871     @param {Object} json
81872     @param {Object} relationship
81873    */
81874    serializeBelongsTo: function serializeBelongsTo(snapshot, json, relationship
81874) {
81875      var key = relationship.key;
81876
81877      if (this._canSerialize(key)) {
81878        var belongsTo = snapshot.belongsTo(key);
81879        if (belongsTo !== undefined) {
81880
81881          json.relationships = json.relationships || {};
81882
81883          var payloadKey = this._getMappedKey(key, snapshot.type);
81884          if (payloadKey === key) {
81885            payloadKey = this.keyForRelationship(key, 'belongsTo', 'serialize');
81886          }
81887
81888          var data = null;
81889          if (belongsTo) {
81890            var payloadType = undefined;
81891
81892            if (false) {
81893              payloadType = this.payloadTypeFromModelName(belongsTo.modelName);
81894              var deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(belongsTo.modelName);
81895
81896              if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) {
81897                (0, _emberDataPrivateDebug.deprecate)("You used payloadKeyFromModelName to serialize type for belongs-to relationship. Use payloadTypeFromModelName instead.", false, {
81898                  id: 'ds.json-api-serializer.deprecated-payload-type-for-belongs-to',
81899                  until: '3.0.0'
81900                });
81901
81902                payloadType = deprecatedPayloadTypeLookup;
81903              }
81904            } else {
81905              payloadType = this.payloadKeyFromModelName(belongsTo.modelName);
81906            }
81907
81908            data = {
81909              type: payloadType,
81910              id: belongsTo.id
81911            };
81912          }
81913
81914          json.relationships[payloadKey] = { data: data };
81915        }
81916      }
81917    },
81918
81919    /**
81920     @method serializeHasMany
81921     @param {DS.Snapshot} snapshot
81922     @param {Object} json
81923     @param {Object} relationship
81924    */
81925    serializeHasMany: function serializeHasMany(snapshot, json, relationship) {
81926      var key = relationship.key;
81927      var shouldSerializeHasMany = '_shouldSerializeHasMany';
81928      if (false) {
81929        shouldSerializeHasMany = 'shouldSerializeHasMany';
81930      }
81931
81932      if (this[shouldSerializeHasMany](snapshot, key, relationship)) {
81933        var hasMany = snapshot.hasMany(key);
81934        if (hasMany !== undefined) {
81935
81936          json.relationships = json.relationships || {};
81937
81938          var payloadKey = this._getMappedKey(key, snapshot.type);
81939          if (payloadKey === key && this.keyForRelationship) {
81940            payloadKey = this.keyForRelationship(key, 'hasMany', 'serialize');
81941          }
81942
81943          var data = new Array(hasMany.length);
81944
81945          for (var i = 0; i < hasMany.length; i++) {
81946            var item = hasMany[i];
81947
81948            var payloadType = undefined;
81949
81950            if (false) {
81951              payloadType = this.payloadTypeFromModelName(item.modelName);
81952              var deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(item.modelName);
81953
81954              if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) {
81955                (0, _emberDataPrivateDebug.deprecate)("You used payloadKeyFromModelName to serialize type for belongs-to relationship. Use payloadTypeFromModelName instead.", false, {
81956                  id: 'ds.json-api-serializer.deprecated-payload-type-for-has-many',
81957                  until: '3.0.0'
81958                });
81959
81960                payloadType = deprecatedPayloadTypeLookup;
81961              }
81962            } else {
81963              payloadType = this.payloadKeyFromModelName(item.modelName);
81964            }
81965
81966            data[i] = {
81967              type: payloadType,
81968              id: item.id
81969            };
81970          }
81971
81972          json.relationships[payloadKey] = { data: data };
81973        }
81974      }
81975    }
81976  });
81977
81978  if (false) {
81979
81980    JSONAPISerializer.reopen({
81981
81982      /**
81983        `modelNameFromPayloadType` can be used to change the mapping for a DS model
81984        name, taken from the value in the payload.
81985         Say your API namespaces the type of a model and returns the following
81986        payload for the `post` model:
81987         ```javascript
81988        // GET /api/posts/1
81989        {
81990          "data": {
81991            "id": 1,
81992            "type: "api::v1::post"
81993          }
81994        }
81995        ```
81996         By overwriting `modelNameFromPayloadType` you can specify that the
81997        `posr` model should be used:
81998         ```app/serializers/application.js
81999        import DS from "ember-data";
82000         export default DS.JSONAPISerializer.extend({
82001          modelNameFromPayloadType(payloadType) {
82002            return payloadType.replace('api::v1::', '');
82003          }
82004        });
82005        ```
82006         By default the modelName for a model is its singularized name in dasherized
82007        form.  Usually, Ember Data can use the correct inflection to do this for
82008        you. Most of the time, you won't need to override
82009        `modelNameFromPayloadType` for this purpose.
82010         Also take a look at
82011        [payloadTypeFromModelName](#method_payloadTypeFromModelName) to customize
82012        how the type of a record should be serialized.
82013         @method modelNameFromPayloadType
82014        @public
82015        @param {String} payloadType type from payload
82016        @return {String} modelName
82017      */
82018      modelNameFromPayloadType: function modelNameFromPayloadType(type) {
82019        return (0, _emberInflector.singularize)((0, _emberDataPrivateSystemNormalizeModelName['default'])(type));
82020      },
82021
82022      /**
82023        `payloadTypeFromModelName` can be used to change the mapping for the type in
82024        the payload, taken from the model name.
82025         Say your API namespaces the type of a model and expects the following
82026        payload when you update the `post` model:
82027         ```javascript
82028        // POST /api/posts/1
82029        {
82030          "data": {
82031            "id": 1,
82032            "type": "api::v1::post"
82033          }
82034        }
82035        ```
82036         By overwriting `payloadTypeFromModelName` you can specify that the
82037        namespaces model name for the `post` should be used:
82038         ```app/serializers/application.js
82039        import DS from "ember-data";
82040         export default JSONAPISerializer.extend({
82041          payloadTypeFromModelName(modelName) {
82042            return "api::v1::" + modelName;
82043          }
82044        });
82045        ```
82046         By default the payload type is the pluralized model name. Usually, Ember
82047        Data can use the correct inflection to do this for you. Most of the time,
82048        you won't need to override `payloadTypeFromModelName` for this purpose.
82049         Also take a look at
82050        [modelNameFromPayloadType](#method_modelNameFromPayloadType) to customize
82051        how the model name from should be mapped from the payload.
82052         @method payloadTypeFromModelName
82053        @public
82054        @param {String} modelname modelName from the record
82055        @return {String} payloadType
82056      */
82057      payloadTypeFromModelName: function payloadTypeFromModelName(modelName) {
82058        return (0, _emberInflector.pluralize)(modelName);
82059      },
82060
82061      _hasCustomModelNameFromPayloadKey: function _hasCustomModelNameFromPayloadKey() {
82062        return this.modelNameFromPayloadKey !== JSONAPISerializer.prototype.modelNameFromPayloadKey;
82063      },
82064
82065      _hasCustomPayloadKeyFromModelName: function _hasCustomPayloadKeyFromModelName() {
82066        return this.payloadKeyFromModelName !== JSONAPISerializer.prototype.payloadKeyFromModelName;
82067      }
82068
82069    });
82070  }
82071
82072  (0, _emberDataPrivateDebug.runInDebug)(function () {
82073    JSONAPISerializer.reopen({
82074      willMergeMixin: function willMergeMixin(props) {
82075        (0, _emberDataPrivateDebug.warn)('The JSONAPISerializer does not work with the EmbeddedRecordsMixin because the JSON API spec does not describe how to format embedded resources.', !props.isEmbeddedRecordsMixin, {
82076          id: 'ds.serializer.embedded-records-mixin-not-supported'
82077        });
82078      },
82079      warnMessageForUndefinedType: function warnMessageForUndefinedType() {
82080        return 'Encountered a resource object with an undefined type (resolved resource using ' + this.constructor.toString() + ')';
82081      },
82082      warnMessageNoModelForType: function warnMessageNoModelForType(modelName, originalType, usedLookup) {
82083        return 'Encountered a resource object with type "' + originalType + '", but no model was found for model name "' + modelName + '" (resolved model name using \'' + this.constructor.toString() + '.' + usedLookup + '("' + originalType + '")).';
82084      }
82085    });
82086  });
82087
82088  exports['default'] = JSONAPISerializer;
82089});
82090define('ember-data/serializers/json', ['exports', 'ember', 'ember-data/-private/debug', 'ember-data/serializer', 'ember-data/-private/system/coerce-id', 'ember-data/-private/system/normalize-model-name', 'ember-data/-private/utils', 'ember-data/-private/features', 'ember-data/adapters/errors'], function (exports, _ember, _emberDataPrivateDebug, _emberDataSerializer, _emberDataPrivateSystemCoerceId, _emberDataPrivateSystemNormalizeModelName, _emberDataPrivateUtils, _emberDataPrivateFeatures, _emberDataAdaptersErrors) {
82091  'use strict';
82092
82093  function _toConsumableArray(arr) {
82094    if (Array.isArray(arr)) {
82095      for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];return arr2;
82096    } else {
82097      return Array.from(arr);
82098    }
82099  }
82100
82101  var get = _ember['default'].get;
82102  var isNone = _ember['default'].isNone;
82103  var assign = _ember['default'].assign || _ember['default'].merge;
82104
82105  /**
82106    Ember Data 2.0 Serializer:
82107  
82108    In Ember Data a Serializer is used to serialize and deserialize
82109    records when they are transferred in and out of an external source.
82110    This process involves normalizing property names, transforming
82111    attribute values and serializing relationships.
82112  
82113    By default, Ember Data uses and recommends the `JSONAPISerializer`.
82114  
82115    `JSONSerializer` is useful for simpler or legacy backends that may
82116    not support the http://jsonapi.org/ spec.
82117  
82118    For example, given the following `User` model and JSON payload:
82119  
82120    ```app/models/user.js
82121    import DS from 'ember-data';
82122  
82123    export default DS.Model.extend({
82124      friends: DS.hasMany('user'),
82125      house: DS.belongsTo('location'),
82126  
82127      name: DS.attr('string')
82128    });
82129    ```
82130  
82131    ```js
82132    {
82133      id: 1,
82134      name: 'Sebastian',
82135      friends: [3, 4],
82136      links: {
82137        house: '/houses/lefkada'
82138      }
82139    }
82140    ```
82141  
82142    `JSONSerializer` will normalize the JSON payload to the JSON API format that the
82143    Ember Data store expects.
82144  
82145    You can customize how JSONSerializer processes its payload by passing options in
82146    the `attrs` hash or by subclassing the `JSONSerializer` and overriding hooks:
82147  
82148      - To customize how a single record is normalized, use the `normalize` hook.
82149      - To customize how `JSONSerializer` normalizes the whole server response, use the
82150        `normalizeResponse` hook.
82151      - To customize how `JSONSerializer` normalizes a specific response from the server,
82152        use one of the many specific `normalizeResponse` hooks.
82153      - To customize how `JSONSerializer` normalizes your id, attributes or relationships,
82154        use the `extractId`, `extractAttributes` and `extractRelationships` hooks.
82155  
82156    The `JSONSerializer` normalization process follows these steps:
82157  
82158      - `normalizeResponse` - entry method to the serializer.
82159      - `normalizeCreateRecordResponse` - a `normalizeResponse` for a specific operation is called.
82160      - `normalizeSingleResponse`|`normalizeArrayResponse` - for methods like `createRecord` we expect
82161        a single record back, while for methods like `findAll` we expect multiple methods back.
82162      - `normalize` - `normalizeArray` iterates and calls `normalize` for each of its records while `normalizeSingle`
82163        calls it once. This is the method you most likely want to subclass.
82164      - `extractId` | `extractAttributes` | `extractRelationships` - `normalize` delegates to these methods to
82165        turn the record payload into the JSON API format.
82166  
82167    @class JSONSerializer
82168    @namespace DS
82169    @extends DS.Serializer
82170  */
82171  var JSONSerializer = _emberDataSerializer['default'].extend({
82172
82173    /**
82174      The `primaryKey` is used when serializing and deserializing
82175      data. Ember Data always uses the `id` property to store the id of
82176      the record. The external source may not always follow this
82177      convention. In these cases it is useful to override the
82178      `primaryKey` property to match the `primaryKey` of your external
82179      store.
82180       Example
82181       ```app/serializers/application.js
82182      import DS from 'ember-data';
82183       export default DS.JSONSerializer.extend({
82184        primaryKey: '_id'
82185      });
82186      ```
82187       @property primaryKey
82188      @type {String}
82189      @default 'id'
82190    */
82191    primaryKey: 'id',
82192
82193    /**
82194      The `attrs` object can be used to declare a simple mapping between
82195      property names on `DS.Model` records and payload keys in the
82196      serialized JSON object representing the record. An object with the
82197      property `key` can also be used to designate the attribute's key on
82198      the response payload.
82199       Example
82200       ```app/models/person.js
82201      import DS from 'ember-data';
82202       export default DS.Model.extend({
82203        firstName: DS.attr('string'),
82204        lastName: DS.attr('string'),
82205        occupation: DS.attr('string'),
82206        admin: DS.attr('boolean')
82207      });
82208      ```
82209       ```app/serializers/person.js
82210      import DS from 'ember-data';
82211       export default DS.JSONSerializer.extend({
82212        attrs: {
82213          admin: 'is_admin',
82214          occupation: { key: 'career' }
82215        }
82216      });
82217      ```
82218       You can also remove attributes by setting the `serialize` key to
82219      `false` in your mapping object.
82220       Example
82221       ```app/serializers/person.js
82222      import DS from 'ember-data';
82223       export default DS.JSONSerializer.extend({
82224        attrs: {
82225          admin: { serialize: false },
82226          occupation: { key: 'career' }
82227        }
82228      });
82229      ```
82230       When serialized:
82231       ```javascript
82232      {
82233        "firstName": "Harry",
82234        "lastName": "Houdini",
82235        "career": "magician"
82236      }
82237      ```
82238       Note that the `admin` is now not included in the payload.
82239       @property attrs
82240      @type {Object}
82241    */
82242    mergedProperties: ['attrs'],
82243
82244    /**
82245     Given a subclass of `DS.Model` and a JSON object this method will
82246     iterate through each attribute of the `DS.Model` and invoke the
82247     `DS.Transform#deserialize` method on the matching property of the
82248     JSON object.  This method is typically called after the
82249     serializer's `normalize` method.
82250      @method applyTransforms
82251     @private
82252     @param {DS.Model} typeClass
82253     @param {Object} data The data to transform
82254     @return {Object} data The transformed data object
82255    */
82256    applyTransforms: function applyTransforms(typeClass, data) {
82257      var _this = this;
82258
82259      var attributes = get(typeClass, 'attributes');
82260
82261      typeClass.eachTransformedAttribute(function (key, typeClass) {
82262        if (data[key] === undefined) {
82263          return;
82264        }
82265
82266        var transform = _this.transformFor(typeClass);
82267        var transformMeta = attributes.get(key);
82268        data[key] = transform.deserialize(data[key], transformMeta.options);
82269      });
82270
82271      return data;
82272    },
82273
82274    /**
82275      The `normalizeResponse` method is used to normalize a payload from the
82276      server to a JSON-API Document.
82277       http://jsonapi.org/format/#document-structure
82278       This method delegates to a more specific normalize method based on
82279      the `requestType`.
82280       To override this method with a custom one, make sure to call
82281      `return this._super(store, primaryModelClass, payload, id, requestType)` with your
82282      pre-processed data.
82283       Here's an example of using `normalizeResponse` manually:
82284       ```javascript
82285      socket.on('message', function(message) {
82286        var data = message.data;
82287        var modelClass = store.modelFor(data.modelName);
82288        var serializer = store.serializerFor(data.modelName);
82289        var normalized = serializer.normalizeSingleResponse(store, modelClass, data, data.id);
82290         store.push(normalized);
82291      });
82292      ```
82293       @since 1.13.0
82294      @method normalizeResponse
82295      @param {DS.Store} store
82296      @param {DS.Model} primaryModelClass
82297      @param {Object} payload
82298      @param {String|Number} id
82299      @param {String} requestType
82300      @return {Object} JSON-API Document
82301    */
82302    normalizeResponse: function normalizeResponse(store, primaryModelClass, payload, id, requestType) {
82303      switch (requestType) {
82304        case 'findRecord':
82305          return this.normalizeFindRecordResponse.apply(this, arguments);
82306        case 'queryRecord':
82307          return this.normalizeQueryRecordResponse.apply(this, arguments);
82308        case 'findAll':
82309          return this.normalizeFindAllResponse.apply(this, arguments);
82310        case 'findBelongsTo':
82311          return this.normalizeFindBelongsToResponse.apply(this, arguments);
82312        case 'findHasMany':
82313          return this.normalizeFindHasManyResponse.apply(this, arguments);
82314        case 'findMany':
82315          return this.normalizeFindManyResponse.apply(this, arguments);
82316        case 'query':
82317          return this.normalizeQueryResponse.apply(this, arguments);
82318        case 'createRecord':
82319          return this.normalizeCreateRecordResponse.apply(this, arguments);
82320        case 'deleteRecord':
82321          return this.normalizeDeleteRecordResponse.apply(this, arguments);
82322        case 'updateRecord':
82323          return this.normalizeUpdateRecordResponse.apply(this, arguments);
82324      }
82325    },
82326
82327    /**
82328      @since 1.13.0
82329      @method normalizeFindRecordResponse
82330      @param {DS.Store} store
82331      @param {DS.Model} primaryModelClass
82332      @param {Object} payload
82333      @param {String|Number} id
82334      @param {String} requestType
82335      @return {Object} JSON-API Document
82336    */
82337    normalizeFindRecordResponse: function normalizeFindRecordResponse(store, primaryModelClass, payload, id, requestType) {
82338      return this.normalizeSingleResponse.apply(this, arguments);
82339    },
82340
82341    /**
82342      @since 1.13.0
82343      @method normalizeQueryRecordResponse
82344      @param {DS.Store} store
82345      @param {DS.Model} primaryModelClass
82346      @param {Object} payload
82347      @param {String|Number} id
82348      @param {String} requestType
82349      @return {Object} JSON-API Document
82350    */
82351    normalizeQueryRecordResponse: function normalizeQueryRecordResponse(store, primaryModelClass, payload, id, requestType) {
82352      return this.normalizeSingleResponse.apply(this, arguments);
82353    },
82354
82355    /**
82356      @since 1.13.0
82357      @method normalizeFindAllResponse
82358      @param {DS.Store} store
82359      @param {DS.Model} primaryModelClass
82360      @param {Object} payload
82361      @param {String|Number} id
82362      @param {String} requestType
82363      @return {Object} JSON-API Document
82364    */
82365    normalizeFindAllResponse: function normalizeFindAllResponse(store, primaryModelClass, payload, id, requestType) {
82366      return this.normalizeArrayResponse.apply(this, arguments);
82367    },
82368
82369    /**
82370      @since 1.13.0
82371      @method normalizeFindBelongsToResponse
82372      @param {DS.Store} store
82373      @param {DS.Model} primaryModelClass
82374      @param {Object} payload
82375      @param {String|Number} id
82376      @param {String} requestType
82377      @return {Object} JSON-API Document
82378    */
82379    normalizeFindBelongsToResponse: function normalizeFindBelongsToResponse(store, primaryModelClass, payload, id, requestType) {
82380      return this.normalizeSingleResponse.apply(this, arguments);
82381    },
82382
82383    /**
82384      @since 1.13.0
82385      @method normalizeFindHasManyResponse
82386      @param {DS.Store} store
82387      @param {DS.Model} primaryModelClass
82388      @param {Object} payload
82389      @param {String|Number} id
82390      @param {String} requestType
82391      @return {Object} JSON-API Document
82392    */
82393    normalizeFindHasManyResponse: function normalizeFindHasManyResponse(store, primaryModelClass, payload, id, requestType) {
82394      return this.normalizeArrayResponse.apply(this, arguments);
82395    },
82396
82397    /**
82398      @since 1.13.0
82399      @method normalizeFindManyResponse
82400      @param {DS.Store} store
82401      @param {DS.Model} primaryModelClass
82402      @param {Object} payload
82403      @param {String|Number} id
82404      @param {String} requestType
82405      @return {Object} JSON-API Document
82406    */
82407    normalizeFindManyResponse: function normalizeFindManyResponse(store, primaryModelClass, payload, id, requestType) {
82408      return this.normalizeArrayResponse.apply(this, arguments);
82409    },
82410
82411    /**
82412      @since 1.13.0
82413      @method normalizeQueryResponse
82414      @param {DS.Store} store
82415      @param {DS.Model} primaryModelClass
82416      @param {Object} payload
82417      @param {String|Number} id
82418      @param {String} requestType
82419      @return {Object} JSON-API Document
82420    */
82421    normalizeQueryResponse: function normalizeQueryResponse(store, primaryModelClass, payload, id, requestType) {
82422      return this.normalizeArrayResponse.apply(this, arguments);
82423    },
82424
82425    /**
82426      @since 1.13.0
82427      @method normalizeCreateRecordResponse
82428      @param {DS.Store} store
82429      @param {DS.Model} primaryModelClass
82430      @param {Object} payload
82431      @param {String|Number} id
82432      @param {String} requestType
82433      @return {Object} JSON-API Document
82434    */
82435    normalizeCreateRecordResponse: function normalizeCreateRecordResponse(store, primaryModelClass, payload, id, requestType) {
82436      return this.normalizeSaveResponse.apply(this, arguments);
82437    },
82438
82439    /**
82440      @since 1.13.0
82441      @method normalizeDeleteRecordResponse
82442      @param {DS.Store} store
82443      @param {DS.Model} primaryModelClass
82444      @param {Object} payload
82445      @param {String|Number} id
82446      @param {String} requestType
82447      @return {Object} JSON-API Document
82448    */
82449    normalizeDeleteRecordResponse: function normalizeDeleteRecordResponse(store, primaryModelClass, payload, id, requestType) {
82450      return this.normalizeSaveResponse.apply(this, arguments);
82451    },
82452
82453    /**
82454      @since 1.13.0
82455      @method normalizeUpdateRecordResponse
82456      @param {DS.Store} store
82457      @param {DS.Model} primaryModelClass
82458      @param {Object} payload
82459      @param {String|Number} id
82460      @param {String} requestType
82461      @return {Object} JSON-API Document
82462    */
82463    normalizeUpdateRecordResponse: function normalizeUpdateRecordResponse(store, primaryModelClass, payload, id, requestType) {
82464      return this.normalizeSaveResponse.apply(this, arguments);
82465    },
82466
82467    /**
82468      @since 1.13.0
82469      @method normalizeSaveResponse
82470      @param {DS.Store} store
82471      @param {DS.Model} primaryModelClass
82472      @param {Object} payload
82473      @param {String|Number} id
82474      @param {String} requestType
82475      @return {Object} JSON-API Document
82476    */
82477    normalizeSaveResponse: function normalizeSaveResponse(store, primaryModelClass, payload, id, requestType) {
82478      return this.normalizeSingleResponse.apply(this, arguments);
82479    },
82480
82481    /**
82482      @since 1.13.0
82483      @method normalizeSingleResponse
82484      @param {DS.Store} store
82485      @param {DS.Model} primaryModelClass
82486      @param {Object} payload
82487      @param {String|Number} id
82488      @param {String} requestType
82489      @return {Object} JSON-API Document
82490    */
82491    normalizeSingleResponse: function normalizeSingleResponse(store, primaryModelClass, payload, id, requestType) {
82492      return this._normalizeResponse(store, primaryModelClass, payload, id, requestType, true);
82493    },
82494
82495    /**
82496      @since 1.13.0
82497      @method normalizeArrayResponse
82498      @param {DS.Store} store
82499      @param {DS.Model} primaryModelClass
82500      @param {Object} payload
82501      @param {String|Number} id
82502      @param {String} requestType
82503      @return {Object} JSON-API Document
82504    */
82505    normalizeArrayResponse: function normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
82506      return this._normalizeResponse(store, primaryModelClass, payload, id, requestType, false);
82507    },
82508
82509    /**
82510      @method _normalizeResponse
82511      @param {DS.Store} store
82512      @param {DS.Model} primaryModelClass
82513      @param {Object} payload
82514      @param {String|Number} id
82515      @param {String} requestType
82516      @param {Boolean} isSingle
82517      @return {Object} JSON-API Document
82518      @private
82519    */
82520    _normalizeResponse: function _normalizeResponse(store, primaryModelClass, payload, id, requestType, isSingle) {
82521      var documentHash = {
82522        data: null,
82523        included: []
82524      };
82525
82526      var meta = this.extractMeta(store, primaryModelClass, payload);
82527      if (meta) {
82528        (0, _emberDataPrivateDebug.assert)('The `meta` returned from `extractMeta` has to be an object, not "' + _ember['default'].typeOf(meta) + '".', _ember['default'].typeOf(meta) === 'object');
82529        documentHash.meta = meta;
82530      }
82531
82532      if (isSingle) {
82533        var _normalize = this.normalize(primaryModelClass, payload);
82534
82535        var data = _normalize.data;
82536        var included = _normalize.included;
82537
82538        documentHash.data = data;
82539        if (included) {
82540          documentHash.included = included;
82541        }
82542      } else {
82543        var ret = new Array(payload.length);
82544        for (var i = 0, l = payload.length; i < l; i++) {
82545          var item = payload[i];
82546
82547          var _normalize2 = this.normalize(primaryModelClass, item);
82548
82549          var data = _normalize2.data;
82550          var included = _normalize2.included;
82551
82552          if (included) {
82553            var _documentHash$included;
82554
82555            (_documentHash$included = documentHash.included).push.apply(_documentHash$included, _toConsumableArray(included));
82556          }
82557          ret[i] = data;
82558        }
82559
82560        documentHash.data = ret;
82561      }
82562
82563      return documentHash;
82564    },
82565
82566    /**
82567      Normalizes a part of the JSON payload returned by
82568      the server. You should override this method, munge the hash
82569      and call super if you have generic normalization to do.
82570       It takes the type of the record that is being normalized
82571      (as a DS.Model class), the property where the hash was
82572      originally found, and the hash to normalize.
82573       You can use this method, for example, to normalize underscored keys to camelized
82574      or other general-purpose normalizations.
82575       Example
82576       ```app/serializers/application.js
82577      import DS from 'ember-data';
82578       export default DS.JSONSerializer.extend({
82579        normalize: function(typeClass, hash) {
82580          var fields = Ember.get(typeClass, 'fields');
82581          fields.forEach(function(field) {
82582            var payloadField = Ember.String.underscore(field);
82583            if (field === payloadField) { return; }
82584             hash[field] = hash[payloadField];
82585            delete hash[payloadField];
82586          });
82587          return this._super.apply(this, arguments);
82588        }
82589      });
82590      ```
82591       @method normalize
82592      @param {DS.Model} typeClass
82593      @param {Object} hash
82594      @return {Object}
82595    */
82596    normalize: function normalize(modelClass, resourceHash) {
82597      var data = null;
82598
82599      if (resourceHash) {
82600        this.normalizeUsingDeclaredMapping(modelClass, resourceHash);
82601        if (_ember['default'].typeOf(resourceHash.links) === 'object') {
82602          this.normalizeUsingDeclaredMapping(modelClass, resourceHash.links);
82603        }
82604
82605        data = {
82606          id: this.extractId(modelClass, resourceHash),
82607          type: modelClass.modelName,
82608          attributes: this.extractAttributes(modelClass, resourceHash),
82609          relationships: this.extractRelationships(modelClass, resourceHash)
82610        };
82611
82612        this.applyTransforms(modelClass, data.attributes);
82613      }
82614
82615      return { data: data };
82616    },
82617
82618    /**
82619      Returns the resource's ID.
82620       @method extractId
82621      @param {Object} modelClass
82622      @param {Object} resourceHash
82623      @return {String}
82624    */
82625    extractId: function extractId(modelClass, resourceHash) {
82626      var primaryKey = get(this, 'primaryKey');
82627      var id = resourceHash[primaryKey];
82628      return (0, _emberDataPrivateSystemCoerceId['default'])(id);
82629    },
82630
82631    /**
82632      Returns the resource's attributes formatted as a JSON-API "attributes object".
82633       http://jsonapi.org/format/#document-resource-object-attributes
82634       @method extractAttributes
82635      @param {Object} modelClass
82636      @param {Object} resourceHash
82637      @return {Object}
82638    */
82639    extractAttributes: function extractAttributes(modelClass, resourceHash) {
82640      var _this2 = this;
82641
82642      var attributeKey;
82643      var attributes = {};
82644
82645      modelClass.eachAttribute(function (key) {
82646        attributeKey = _this2.keyForAttribute(key, 'deserialize');
82647        if (resourceHash[attributeKey] !== undefined) {
82648          attributes[key] = resourceHash[attributeKey];
82649        }
82650      });
82651
82652      return attributes;
82653    },
82654
82655    /**
82656      Returns a relationship formatted as a JSON-API "relationship object".
82657       http://jsonapi.org/format/#document-resource-object-relationships
82658       @method extractRelationship
82659      @param {Object}
82659 relationshipModelName
82660      @param {Object} relationshipHash
82661      @return {Object}
82662    */
82663    extractRelationship: function extractRelationship(relationshipModelName, relationshipHash) {
82664      if (_ember['default'].isNone(relationshipHash)) {
82665        return null;
82666      }
82667      /*
82668        When `relationshipHash` is an object it usually means that the relationship
82669        is polymorphic. It could however also be embedded resources that the
82670        EmbeddedRecordsMixin has be able to process.
82671      */
82672      if (_ember['default'].typeOf(relationshipHash) === 'object') {
82673        if (relationshipHash.id) {
82674          relationshipHash.id = (0, _emberDataPrivateSystemCoerceId['default'])(relationshipHash.id);
82675        }
82676
82677        var modelClass = this.store.modelFor(relationshipModelName);
82678        if (relationshipHash.type && !(0, _emberDataPrivateUtils.modelHasAttributeOrRelationshipNamedType)(modelClass)) {
82679
82680          if (false) {
82681            var modelName = this.modelNameFromPayloadType(relationshipHash.type);
82682            var deprecatedModelNameLookup = this.modelNameFromPayloadKey(relationshipHash.type);
82683
82684            if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) {
82685              (0, _emberDataPrivateDebug.deprecate)("You used modelNameFromPayloadKey to customize how a type is normalized. Use modelNameFromPayloadType instead", false, {
82686                id: 'ds.json-serializer.deprecated-type-for-polymorphic-relationship',
82687                until: '3.0.0'
82688              });
82689
82690              modelName = deprecatedModelNameLookup;
82691            }
82692
82693            relationshipHash.type = modelName;
82694          } else {
82695            relationshipHash.type = this.modelNameFromPayloadKey(relationshipHash.type);
82696          }
82697        }
82698        return relationshipHash;
82699      }
82700      return { id: (0, _emberDataPrivateSystemCoerceId['default'])(relationshipHash), type: relationshipModelName };
82701    },
82702
82703    /**
82704      Returns a polymorphic relationship formatted as a JSON-API "relationship object".
82705       http://jsonapi.org/format/#document-resource-object-relationships
82706       `relationshipOptions` is a hash which contains more information about the
82707      polymorphic relationship which should be extracted:
82708        - `resourceHash` complete hash of the resource the relationship should be
82709          extracted from
82710        - `relationshipKey` key under which the value for the relationship is
82711          extracted from the resourceHash
82712        - `relationshipMeta` meta information about the relationship
82713       @method extractPolymorphicRelationship
82714      @param {Object} relationshipModelName
82715      @param {Object} relationshipHash
82716      @param {Object} relationshipOptions
82717      @return {Object}
82718    */
82719    extractPolymorphicRelationship: function extractPolymorphicRelationship(relationshipModelName, relationshipHash, relationshipOptions) {
82720      return this.extractRelationship(relationshipModelName, relationshipHash);
82721    },
82722
82723    /**
82724      Returns the resource's relationships formatted as a JSON-API "relationships object".
82725       http://jsonapi.org/format/#document-resource-object-relationships
82726       @method extractRelationships
82727      @param {Object} modelClass
82728      @param {Object} resourceHash
82729      @return {Object}
82730    */
82731    extractRelationships: function extractRelationships(modelClass, resourceHash) {
82732      var _this3 = this;
82733
82734      var relationships = {};
82735
82736      modelClass.eachRelationship(function (key, relationshipMeta) {
82737        var relationship = null;
82738        var relationshipKey = _this3.keyForRelationship(key, relationshipMeta.kind, 'deserialize');
82739        if (resourceHash[relationshipKey] !== undefined) {
82740          var data = null;
82741          var relationshipHash = resourceHash[relationshipKey];
82742          if (relationshipMeta.kind === 'belongsTo') {
82743            if (relationshipMeta.options.polymorphic) {
82744              // extracting a polymorphic belongsTo may need more information
82745              // than the type and the hash (which might only be an id) for the
82746              // relationship, hence we pass the key, resource and
82747              // relationshipMeta too
82748              data = _this3.extractPolymorphicRelationship(relationshipMeta.type, relationshipHash, { key: key, resourceHash: resourceHash, relationshipMeta: relationshipMeta });
82749            } else {
82750              data = _this3.extractRelationship(relationshipMeta.type, relationshipHash);
82751            }
82752          } else if (relationshipMeta.kind === 'hasMany') {
82753            if (!_ember['default'].isNone(relationshipHash)) {
82754              data = new Array(relationshipHash.length);
82755              for (var i = 0, l = relationshipHash.length; i < l; i++) {
82756                var item = relationshipHash[i];
82757                data[i] = _this3.extractRelationship(relationshipMeta.type, item);
82758              }
82759            }
82760          }
82761          relationship = { data: data };
82762        }
82763
82764        var linkKey = _this3.keyForLink(key, relationshipMeta.kind);
82765        if (resourceHash.links && resourceHash.links[linkKey] !== undefined) {
82766          var related = resourceHash.links[linkKey];
82767          relationship = relationship || {};
82768          relationship.links = { related: related };
82769        }
82770
82771        if (relationship) {
82772          relationships[key] = relationship;
82773        }
82774      });
82775
82776      return relationships;
82777    },
82778
82779    /**
82780      @method modelNameFromPayloadKey
82781      @param {String} key
82782      @return {String} the model's modelName
82783    */
82784    // TODO @deprecated Use modelNameFromPayloadType instead
82785    modelNameFromPayloadKey: function modelNameFromPayloadKey(key) {
82786      return (0, _emberDataPrivateSystemNormalizeModelName['default'])(key);
82787    },
82788
82789    /**
82790      @method normalizeAttributes
82791      @private
82792    */
82793    normalizeAttributes: function normalizeAttributes(typeClass, hash) {
82794      var _this4 = this;
82795
82796      var payloadKey;
82797
82798      if (this.keyForAttribute) {
82799        typeClass.eachAttribute(function (key) {
82800          payloadKey = _this4.keyForAttribute(key, 'deserialize');
82801          if (key === payloadKey) {
82802            return;
82803          }
82804          if (hash[payloadKey] === undefined) {
82805            return;
82806          }
82807
82808          hash[key] = hash[payloadKey];
82809          delete hash[payloadKey];
82810        });
82811      }
82812    },
82813
82814    /**
82815      @method normalizeRelationships
82816      @private
82817    */
82818    normalizeRelationships: function normalizeRelationships(typeClass, hash) {
82819      var _this5 = this;
82820
82821      var payloadKey;
82822
82823      if (this.keyForRelationship) {
82824        typeClass.eachRelationship(function (key, relationship) {
82825          payloadKey = _this5.keyForRelationship(key, relationship.kind, 'deserialize');
82826          if (key === payloadKey) {
82827            return;
82828          }
82829          if (hash[payloadKey] === undefined) {
82830            return;
82831          }
82832
82833          hash[key] = hash[payloadKey];
82834          delete hash[payloadKey];
82835        });
82836      }
82837    },
82838
82839    /**
82840      @method normalizeUsingDeclaredMapping
82841      @private
82842    */
82843    normalizeUsingDeclaredMapping: function normalizeUsingDeclaredMapping(modelClass, hash) {
82844      var attrs = get(this, 'attrs');
82845      var normalizedKey, payloadKey, key;
82846
82847      if (attrs) {
82848        for (key in attrs) {
82849          normalizedKey = payloadKey = this._getMappedKey(key, modelClass);
82850
82851          if (hash[payloadKey] === undefined) {
82852            continue;
82853          }
82854
82855          if (get(modelClass, 'attributes').has(key)) {
82856            normalizedKey = this.keyForAttribute(key);
82857          }
82858
82859          if (get(modelClass, 'relationshipsByName').has(key)) {
82860            normalizedKey = this.keyForRelationship(key);
82861          }
82862
82863          if (payloadKey !== normalizedKey) {
82864            hash[normalizedKey] = hash[payloadKey];
82865            delete hash[payloadKey];
82866          }
82867        }
82868      }
82869    },
82870
82871    /**
82872      Looks up the property key that was set by the custom `attr` mapping
82873      passed to the serializer.
82874       @method _getMappedKey
82875      @private
82876      @param {String} key
82877      @return {String} key
82878    */
82879    _getMappedKey: function _getMappedKey(key, modelClass) {
82880      (0, _emberDataPrivateDebug.warn)('There is no attribute or relationship with the name `' + key + '` on `' + modelClass.modelName + '`. Check your serializers attrs hash.', get(modelClass, 'attributes').has(key) || get(modelClass, 'relationshipsByName').has(key), {
82881        id: 'ds.serializer.no-mapped-attrs-key'
82882      });
82883
82884      var attrs = get(this, 'attrs');
82885      var mappedKey;
82886      if (attrs && attrs[key]) {
82887        mappedKey = attrs[key];
82888        //We need to account for both the { title: 'post_title' } and
82889        //{ title: { key: 'post_title' }} forms
82890        if (mappedKey.key) {
82891          mappedKey = mappedKey.key;
82892        }
82893        if (typeof mappedKey === 'string') {
82894          key = mappedKey;
82895        }
82896      }
82897
82898      return key;
82899    },
82900
82901    /**
82902      Check attrs.key.serialize property to inform if the `key`
82903      can be serialized
82904       @method _canSerialize
82905      @private
82906      @param {String} key
82907      @return {boolean} true if the key can be serialized
82908    */
82909    _canSerialize: function _canSerialize(key) {
82910      var attrs = get(this, 'attrs');
82911
82912      return !attrs || !attrs[key] || attrs[key].serialize !== false;
82913    },
82914
82915    /**
82916      When attrs.key.serialize is set to true then
82917      it takes priority over the other checks and the related
82918      attribute/relationship will be serialized
82919       @method _mustSerialize
82920      @private
82921      @param {String} key
82922      @return {boolean} true if the key must be serialized
82923    */
82924    _mustSerialize: function _mustSerialize(key) {
82925      var attrs = get(this, 'attrs');
82926
82927      return attrs && attrs[key] && attrs[key].serialize === true;
82928    },
82929
82930    /**
82931      Check if the given hasMany relationship should be serialized
82932       @method shouldSerializeHasMany
82933      @param {DS.Snapshot} snapshot
82934      @param {String} key
82935      @param {String} relationshipType
82936      @return {boolean} true if the hasMany relationship should be serialized
82937    */
82938
82939    shouldSerializeHasMany: function shouldSerializeHasMany(snapshot, key, relationship
82939) {
82940      if (this._shouldSerializeHasMany !== JSONSerializer.prototype._shouldSerializeHasMany) {
82941        (0, _emberDataPrivateDebug.deprecate)('The private method _shouldSerializeHasMany has been promoted to the public API. Please remove the underscore to use the public shouldSerializeHasMany method.', false, {
82942          id: 'ds.serializer.private-should-serialize-has-many',
82943          until: '3.0.0'
82944        });
82945      }
82946
82947      return this._shouldSerializeHasMany(snapshot, key, relationship);
82948    },
82949
82950    /**
82951      Check if the given hasMany relationship should be serialized
82952       @method _shouldSerializeHasMany
82953      @private
82954      @param {DS.Snapshot} snapshot
82955      @param {String} key
82956      @param {String} relationshipType
82957      @return {boolean} true if the hasMany relationship should be serialized
82958    */
82959    _shouldSerializeHasMany: function _shouldSerializeHasMany(snapshot, key, relationship) {
82960      var relationshipType = snapshot.type.determineRelationshipType(relationship, this.store);
82961      if (this._mustSerialize(key)) {
82962        return true;
82963      }
82964      return this._canSerialize(key) && (relationshipType === 'manyToNone' || relationshipType === 'manyToMany');
82965    },
82966
82967    // SERIALIZE
82968    /**
82969      Called when a record is saved in order to convert the
82970      record into JSON.
82971       By default, it creates a JSON object with a key for
82972      each attribute and belongsTo relationship.
82973       For example, consider this model:
82974       ```app/models/comment.js
82975      import DS from 'ember-data';
82976       export default DS.Model.extend({
82977        title: DS.attr(),
82978        body: DS.attr(),
82979         author: DS.belongsTo('user')
82980      });
82981      ```
82982       The default serialization would create a JSON object like:
82983       ```javascript
82984      {
82985        "title": "Rails is unagi",
82986        "body": "Rails? Omakase? O_O",
82987        "author": 12
82988      }
82989      ```
82990       By default, attributes are passed through as-is, unless
82991      you specified an attribute type (`DS.attr('date')`). If
82992      you specify a transform, the JavaScript value will be
82993      serialized when inserted into the JSON hash.
82994       By default, belongs-to relationships are converted into
82995      IDs when inserted into the JSON hash.
82996       ## IDs
82997       `serialize` takes an options hash with a single option:
82998      `includeId`. If this option is `true`, `serialize` will,
82999      by default include the ID in the JSON object it builds.
83000       The adapter passes in `includeId: true` when serializing
83001      a record for `createRecord`, but not for `updateRecord`.
83002       ## Customization
83003       Your server may expect a different JSON format than the
83004      built-in serialization format.
83005       In that case, you can implement `serialize` yourself and
83006      return a JSON hash of your choosing.
83007       ```app/serializers/post.js
83008      import DS from 'ember-data';
83009       export default DS.JSONSerializer.extend({
83010        serialize: function(snapshot, options) {
83011          var json = {
83012            POST_TTL: snapshot.attr('title'),
83013            POST_BDY: snapshot.attr('body'),
83014            POST_CMS: snapshot.hasMany('comments', { ids: true })
83015          }
83016           if (options.includeId) {
83017            json.POST_ID_ = snapshot.id;
83018          }
83019           return json;
83020        }
83021      });
83022      ```
83023       ## Customizing an App-Wide Serializer
83024       If you want to define a serializer for your entire
83025      application, you'll probably want to use `eachAttribute`
83026      and `eachRelationship` on the record.
83027       ```app/serializers/application.js
83028      import DS from 'ember-data';
83029       export default DS.JSONSerializer.extend({
83030        serialize: function(snapshot, options) {
83031          var json = {};
83032           snapshot.eachAttribute(function(name) {
83033            json[serverAttributeName(name)] = snapshot.attr(name);
83034          })
83035           snapshot.eachRelationship(function(name, relationship) {
83036            if (relationship.kind === 'hasMany') {
83037              json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
83038            }
83039          });
83040           if (options.includeId) {
83041            json.ID_ = snapshot.id;
83042          }
83043           return json;
83044        }
83045      });
83046       function serverAttributeName(attribute) {
83047        return attribute.underscore().toUpperCase();
83048      }
83049       function serverHasManyName(name) {
83050        return serverAttributeName(name.singularize()) + "_IDS";
83051      }
83052      ```
83053       This serializer will generate JSON that looks like this:
83054       ```javascript
83055      {
83056        "TITLE": "Rails is omakase",
83057        "BODY": "Yep. Omakase.",
83058        "COMMENT_IDS": [ 1, 2, 3 ]
83059      }
83060      ```
83061       ## Tweaking the Default JSON
83062       If you just want to do some small tweaks on the default JSON,
83063      you can call super first and make the tweaks on the returned
83064      JSON.
83065       ```app/serializers/post.js
83066      import DS from 'ember-data';
83067       export default DS.JSONSerializer.extend({
83068        serialize: function(snapshot, options) {
83069          var json = this._super.apply(this, arguments);
83070           json.subject = json.title;
83071          delete json.title;
83072           return json;
83073        }
83074      });
83075      ```
83076       @method serialize
83077      @param {DS.Snapshot} snapshot
83078      @param {Object} options
83079      @return {Object} json
83080    */
83081    serialize: function serialize(snapshot, options) {
83082      var _this6 = this;
83083
83084      var json = {};
83085
83086      if (options && options.includeId) {
83087        var id = snapshot.id;
83088
83089        if (id) {
83090          json[get(this, 'primaryKey')] = id;
83091        }
83092      }
83093
83094      snapshot.eachAttribute(function (key, attribute) {
83095        _this6.serializeAttribute(snapshot, json, key, attribute);
83096      });
83097
83098      snapshot.eachRelationship(function (key, relationship) {
83099        if (relationship.kind === 'belongsTo') {
83100          _this6.serializeBelongsTo(snapshot, json, relationship);
83101        } else if (relationship.kind === 'hasMany') {
83102          _this6.serializeHasMany(snapshot, json, relationship);
83103        }
83104      });
83105
83106      return json;
83107    },
83108
83109    /**
83110      You can use this method to customize how a serialized record is added to the complete
83111      JSON hash to be sent to the server. By default the JSON Serializer does not namespace
83112      the payload and just sends the raw serialized JSON object.
83113      If your server expects namespaced keys, you should consider using the RESTSerializer.
83114      Otherwise you can override this method to customize how the record is added to the hash.
83115      The hash property should be modified by reference.
83116       For example, your server may expect underscored root objects.
83117       ```app/serializers/application.js
83118      import DS from 'ember-data';
83119       export default DS.RESTSerializer.extend({
83120        serializeIntoHash: function(data, type, snapshot, options) {
83121          var root = Ember.String.decamelize(type.modelName);
83122          data[root] = this.serialize(snapshot, options);
83123        }
83124      });
83125      ```
83126       @method serializeIntoHash
83127      @param {Object} hash
83128      @param {DS.Model} typeClass
83129      @param {DS.Snapshot} snapshot
83130      @param {Object} options
83131    */
83132    serializeIntoHash: function serializeIntoHash(hash, typeClass, snapshot, options) {
83133      assign(hash, this.serialize(snapshot, options));
83134    },
83135
83136    /**
83137     `serializeAttribute` can be used to customize how `DS.attr`
83138     properties are serialized
83139      For example if you wanted to ensure all your attributes were always
83140     serialized as properties on an `attributes` object you could
83141     write:
83142      ```app/serializers/application.js
83143     import DS from 'ember-data';
83144      export default DS.JSONSerializer.extend({
83145       serializeAttribute: function(snapshot, json, key, attributes) {
83146         json.attributes = json.attributes || {};
83147         this._super(snapshot, json.attributes, key, attributes);
83148       }
83149     });
83150     ```
83151      @method serializeAttribute
83152     @param {DS.Snapshot} snapshot
83153     @param {Object} json
83154     @param {String} key
83155     @param {Object} attribute
83156    */
83157    serializeAttribute: function serializeAttribute(snapshot, json, key, attribute) {
83158      var type = attribute.type;
83159
83160      if (this._canSerialize(key)) {
83161        var value = snapshot.attr(key);
83162        if (type) {
83163          var transform = this.transformFor(type);
83164          value = transform.serialize(value, attribute.options);
83165        }
83166
83167        // if provided, use the mapping provided by `attrs` in
83168        // the serializer
83169        var payloadKey = this._getMappedKey(key, snapshot.type);
83170
83171        if (payloadKey === key && this.keyForAttribute) {
83172          payloadKey = this.keyForAttribute(key, 'serialize');
83173        }
83174
83175        json[payloadKey] = value;
83176      }
83177    },
83178
83179    /**
83180     `serializeBelongsTo` can be used to customize how `DS.belongsTo`
83181     properties are serialized.
83182      Example
83183      ```app/serializers/post.js
83184     import DS from 'ember-data';
83185      export default DS.JSONSerializer.extend({
83186       serializeBelongsTo: function(snapshot, json, relationship
83186) {
83187         var key = relationship.key;
83188          var belongsTo = snapshot.belongsTo(key);
83189          key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo", "serialize") : key;
83190          json[key] = Ember.isNone(belongsTo) ? belongsTo : belongsTo.record.toJSON();
83191       }
83192     });
83193     ```
83194      @method serializeBelongsTo
83195     @param {DS.Snapshot} snapshot
83196     @param {Object} json
83197     @param {Object} relationship
83198    */
83199    serializeBelongsTo: function serializeBelongsTo(snapshot, json, relationship) {
83200      var key = relationship.key;
83201
83202      if (this._canSerialize(key)) {
83203        var belongsToId = snapshot.belongsTo(key, { id: true });
83204
83205        // if provided, use the mapping provided by `attrs` in
83206        // the serializer
83207        var payloadKey = this._getMappedKey(key, snapshot.type);
83208        if (payloadKey === key && this.keyForRelationship) {
83209          payloadKey = this.keyForRelationship(key, "belongsTo", "serialize");
83210        }
83211
83212        //Need to check whether the id is there for new&async records
83213        if (isNone(belongsToId)) {
83214          json[payloadKey] = null;
83215        } else {
83216          json[payloadKey] = belongsToId;
83217        }
83218
83219        if (relationship.options.polymorphic) {
83220          this.serializePolymorphicType(snapshot, json, relationship);
83221        }
83222      }
83223    },
83224
83225    /**
83226     `serializeHasMany` can be used to customize how `DS.hasMany`
83227     properties are serialized.
83228      Example
83229      ```app/serializers/post.js
83230     import DS from 'ember-data';
83231      export default DS.JSONSerializer.extend({
83232       serializeHasMany: function(snapshot, json, relationship) {
83233         var key = relationship.key;
83234         if (key === 'comments') {
83235           return;
83236         } else {
83237           this._super.apply(this, arguments);
83238         }
83239       }
83240     });
83241     ```
83242      @method serializeHasMany
83243     @param {DS.Snapshot} snapshot
83244     @param {Object} json
83245     @param {Object} relationship
83246    */
83247    serializeHasMany: function serializeHasMany(snapshot, json, relationship) {
83248      var key = relationship.key;
83249      var shouldSerializeHasMany = '_shouldSerializeHasMany';
83250      if (false) {
83251        shouldSerializeHasMany = 'shouldSerializeHasMany';
83252      }
83253
83254      if (this[shouldSerializeHasMany](snapshot, key, relationship)) {
83255        var hasMany = snapshot.hasMany(key, { ids: true });
83256        if (hasMany !== undefined) {
83257          // if provided, use the mapping provided by `attrs` in
83258          // the serializer
83259          var payloadKey = this._getMappedKey(key, snapshot.type);
83260          if (payloadKey === key && this.keyForRelationship) {
83261            payloadKey = this.keyForRelationship(key, "hasMany", "serialize");
83262          }
83263
83264          json[payloadKey] = hasMany;
83265          // TODO support for polymorphic manyToNone and manyToMany relationships
83266        }
83267      }
83268    },
83269
83270    /**
83271      You can use this method to customize how polymorphic objects are
83272      serialized. Objects are considered to be polymorphic if
83273      `{ polymorphic: true }` is pass as the second argument to the
83274      `DS.belongsTo` function.
83275       Example
83276       ```app/serializers/comment.js
83277      import DS from 'ember-data';
83278       export default DS.JSONSerializer.extend({
83279        serializePolymorphicType: function(snapshot, json, relationship) {
83280          var key = relationship.key,
83281              belongsTo = snapshot.belongsTo(key);
83282          key = this.keyForAttribute ? this.keyForAttribute(key, "serialize") : key;
83283           if (Ember.isNone(belongsTo)) {
83284            json[key + "_type"] = null;
83285          } else {
83286            json[key + "_type"] = belongsTo.modelName;
83287          }
83288        }
83289      });
83290      ```
83291       @method serializePolymorphicType
83292      @param {DS.Snapshot} snapshot
83293      @param {Object} json
83294      @param {Object} relationship
83295    */
83296    serializePolymorphicType: _ember['default'].K,
83297
83298    /**
83299      `extractMeta` is used to deserialize any meta information in the
83300      adapter payload. By default Ember Data expects meta information to
83301      be located on the `meta` property of the payload object.
83302       Example
83303       ```app/serializers/post.js
83304      import DS from 'ember-data';
83305       export default DS.JSONSerializer.extend({
83306        extractMeta: function(store, typeClass, payload) {
83307          if (payload && payload.hasOwnProperty('_pagination')) {
83308            let meta = payload._pagination;
83309            delete payload._pagination;
83310            return meta;
83311          }
83312        }
83313      });
83314      ```
83315       @method extractMeta
83316      @param {DS.Store} store
83317      @param {DS.Model} modelClass
83318      @param {Object} payload
83319    */
83320    extractMeta: function extractMeta(store, modelClass, payload) {
83321      if (payload && payload['meta'] !== undefined) {
83322        var meta = payload.meta;
83323        delete payload.meta;
83324        return meta;
83325      }
83326    },
83327
83328    /**
83329      `extractErrors` is used to extract model errors when a call
83330      to `DS.Model#save` fails with an `InvalidError`. By default
83331      Ember Data expects error information to be located on the `errors`
83332      property of the payload object.
83333       This serializer expects this `errors` object to be an Array similar
83334      to the following, compliant with the JSON-API specification:
83335       ```js
83336      {
83337        "errors": [
83338          {
83339            "detail": "This username is already taken!",
83340            "source": {
83341              "pointer": "data/attributes/username"
83342            }
83343          }, {
83344            "detail": "Doesn't look like a valid email.",
83345            "source": {
83346              "pointer": "data/attributes/email"
83347            }
83348          }
83349        ]
83350      }
83351      ```
83352       The key `detail` provides a textual description of the problem.
83353      Alternatively, the key `title` can be used for the same purpose.
83354       The nested keys `source.pointer` detail which specific element
83355      of the request data was invalid.
83356       Note that JSON-API also allows for object-level errors to be placed
83357      in an object with pointer `data`, signifying that the problem
83358      cannot be traced to a specific attribute:
83359       ```javascript
83360      {
83361        "errors": [
83362          {
83363            "detail": "Some generic non property error message",
83364            "source": {
83365              "pointer": "data"
83366            }
83367          }
83368        ]
83369      }
83370      ```
83371       When turn into a `DS.Errors` object, you can read these errors
83372      through the property `base`:
83373       ```handlebars
83374      {{#each model.errors.base as |error|}}
83375        <div class="error">
83376          {{error.message}}
83377        </div>
83378      {{/each}}
83379      ```
83380       Example of alternative implementation, overriding the default
83381      behavior to deal with a different format of errors:
83382       ```app/serializers/post.js
83383      import DS from 'ember-data';
83384       export default DS.JSONSerializer.extend({
83385        extractErrors: function(store, typeClass, payload, id) {
83386          if (payload && typeof payload === 'object' && payload._problems) {
83387            payload = payload._problems;
83388            this.normalizeErrors(typeClass, payload);
83389          }
83390          return payload;
83391        }
83392      });
83393      ```
83394       @method extractErrors
83395      @param {DS.Store} store
83396      @param {DS.Model} typeClass
83397      @param {Object} payload
83398      @param {(String|Number)} id
83399      @return {Object} json The deserialized errors
83400    */
83401    extractErrors: function extractErrors(store, typeClass, payload, id) {
83402      var _this7 = this;
83403
83404      if (payload && typeof payload === 'object' && payload.errors) {
83405        payload = (0, _emberDataAdaptersErrors.errorsArrayToHash)(payload.errors);
83406
83407        this.normalizeUsingDeclaredMapping(typeClass, payload);
83408
83409        typeClass.eachAttribute(function (name) {
83410          var key = _this7.keyForAttribute(name, 'deserialize');
83411          if (key !== name && payload[key] !== undefined) {
83412            payload[name] = payload[key];
83413            delete payload[key];
83414          }
83415        });
83416
83417        typeClass.eachRelationship(function (name) {
83418          var key = _this7.keyForRelationship(name, 'deserialize');
83419          if (key !== name && payload[key] !== undefined) {
83420            payload[name] = payload[key];
83421            delete payload[key];
83422          }
83423        });
83424      }
83425
83426      return payload;
83427    },
83428
83429    /**
83430     `keyForAttribute` can be used to define rules for how to convert an
83431     attribute name in your model to a key in your JSON.
83432      Example
83433      ```app/serializers/application.js
83434     import DS from 'ember-data';
83435      export default DS.RESTSerializer.extend({
83436       keyForAttribute: function(attr, method) {
83437         return Ember.String.underscore(attr).toUpperCase();
83438       }
83439     });
83440     ```
83441      @method keyForAttribute
83442     @param {String} key
83443     @param {String} method
83444     @return {String} normalized key
83445    */
83446    keyForAttribute: function keyForAttribute(key, method) {
83447      return key;
83448    },
83449
83450    /**
83451     `keyForRelationship` can be used to define a custom key when
83452     serializing and deserializing relationship properties. By default
83453     `JSONSerializer` does not provide an implementation of this method.
83454      Example
83455       ```app/serializers/post.js
83456      import DS from 'ember-data';
83457       export default DS.JSONSerializer.extend({
83458        keyForRelationship: function(key, relationship, method) {
83459          return 'rel_' + Ember.String.underscore(key);
83460        }
83461      });
83462      ```
83463      @method keyForRelationship
83464     @param {String} key
83465     @param {String} typeClass
83466     @param {String} method
83467     @return {String} normalized key
83468    */
83469    keyForRelationship: function keyForRelationship(key, typeClass, method) {
83470      return key;
83471    },
83472
83473    /**
83474     `keyForLink` can be used to define a custom key when deserializing link
83475     properties.
83476      @method keyForLink
83477     @param {String} key
83478     @param {String} kind `belongsTo` or `hasMany`
83479     @return {String} normalized key
83480    */
83481    keyForLink: function keyForLink(key, kind) {
83482      return key;
83483    },
83484
83485    // HELPERS
83486
83487    /**
83488     @method transformFor
83489     @private
83490     @param {String} attributeType
83491     @param {Boolean} skipAssertion
83492     @return {DS.Transform} transform
83493    */
83494    transformFor: function transformFor(attributeType, skipAssertion) {
83495      var transform = (0, _emberDataPrivateUtils.getOwner)(this).lookup('transform:' + attributeType);
83496
83497      (0, _emberDataPrivateDebug.assert)("Unable to find transform for '" + attributeType + "'", skipAssertion || !!transform);
83498
83499      return transform;
83500    }
83501  });
83502
83503  if (false) {
83504
83505    JSONSerializer.reopen({
83506
83507      /**
83508        @method modelNameFromPayloadType
83509        @public
83510        @param {String} type
83511        @return {String} the model's modelName
83512        */
83513      modelNameFromPayloadType: function modelNameFromPayloadType(type) {
83514        return (0, _emberDataPrivateSystemNormalizeModelName['default'])(type);
83515      },
83516
83517      _hasCustomModelNameFromPayloadKey: function _hasCustomModelNameFromPayloadKey() {
83518        return this.modelNameFromPayloadKey !== JSONSerializer.prototype.modelNameFromPayloadKey;
83519      }
83520
83521    });
83522  }
83523
83524  exports['default'] = JSONSerializer;
83525});
83526define("ember-data/serializers/rest", ["exports", "ember", "ember-data/-private/debug", "ember-data/serializers/json", "ember-data/-private/system/normalize-model-name", "ember-inflector", "ember-data/-private/system/coerce-id", "ember-data/-private/utils", "ember-data/-private/features"], function (exports, _ember, _emberDataPrivateDebug, _emberDataSerializersJson, _emberDataPrivateSystemNormalizeModelName, _emberInflector, _emberDataPrivateSystemCoerceId, _emberDataPrivateUtils, _emberDataPrivateFeatures) {
83527  "use strict";
83528
83529  function _toConsumableArray(arr) {
83530    if (Array.isArray(arr)) {
83531      for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];return arr2;
83532    } else {
83533      return Array.from(arr);
83534    }
83535  }
83536
83537  /**
83538    @module ember-data
83539  */
83540
83541  var camelize = _ember["default"].String.camelize;
83542
83543  /**
83544    Normally, applications will use the `RESTSerializer` by implementing
83545    the `normalize` method.
83546  
83547    This allows you to do whatever kind of munging you need, and is
83548    especially useful if your server is inconsistent and you need to
83549    do munging differently for many different kinds of responses.
83550  
83551    See the `normalize` documentation for more information.
83552  
83553    ## Across the Board Normalization
83554  
83555    There are also a number of hooks that you might find useful to define
83556    across-the-board rules for your payload. These rules will be useful
83557    if your server is consistent, or if you're building an adapter for
83558    an infrastructure service, like Firebase, and want to encode service
83559    conventions.
83560  
83561    For example, if all of your keys are underscored and all-caps, but
83562    otherwise consistent with the names you use in your models, you
83563    can implement across-the-board rules for how to convert an attribute
83564    name in your model to a key in your JSON.
83565  
83566    ```app/serializers/application.js
83567    import DS from 'ember-data';
83568  
83569    export default DS.RESTSerializer.extend({
83570      keyForAttribute: function(attr, method) {
83571        return Ember.String.underscore(attr).toUpperCase();
83572      }
83573    });
83574    ```
83575  
83576    You can also implement `keyForRelationship`, which takes the name
83577    of the relationship as the first parameter, the kind of
83578    relationship (`hasMany` or `belongsTo`) as the second parameter, and
83579    the method (`serialize` or `deserialize`) as the third parameter.
83580  
83581    @class RESTSerializer
83582    @namespace DS
83583    @extends DS.JSONSerializer
83584  */
83585  var RESTSerializer = _emberDataSerializersJson["default"].extend({
83586
83587    /**
83588     `keyForPolymorphicType` can be used to define a custom key when
83589     serializing and deserializing a polymorphic type. By default, the
83590     returned key is `${key}Type`.
83591      Example
83592       ```app/serializers/post.js
83593      import DS from 'ember-data';
83594       export default DS.RESTSerializer.extend({
83595        keyForPolymorphicType: function(key, relationship) {
83596          var relationshipKey = this.keyForRelationship(key);
83597           return 'type-' + relationshipKey;
83598        }
83599      });
83600      ```
83601      @method keyForPolymorphicType
83602     @param {String} key
83603     @param {String} typeClass
83604     @param {String} method
83605     @return {String} normalized key
83606    */
83607    keyForPolymorphicType: function keyForPolymorphicType(key, typeClass, method) {
83608      var relationshipKey = this.keyForRelationship(key);
83609
83610      return relationshipKey + "Type";
83611    },
83612
83613    /**
83614      Normalizes a part of the JSON payload returned by
83615      the server. You should override this method, munge the hash
83616      and call super if you have generic normalization to do.
83617       It takes the type of the record that is being normalized
83618      (as a DS.Model class), the property where the hash was
83619      originally found, and the hash to normalize.
83620       For example, if you have a payload that looks like this:
83621       ```js
83622      {
83623        "post": {
83624          "id": 1,
83625          "title": "Rails is omakase",
83626          "comments": [ 1, 2 ]
83627        },
83628        "comments": [{
83629          "id": 1,
83630          "body": "FIRST"
83631        }, {
83632          "id": 2,
83633          "body": "Rails is unagi"
83634        }]
83635      }
83636      ```
83637       The `normalize` method will be called three times:
83638       * With `App.Post`, `"posts"` and `{ id: 1, title: "Rails is omakase", ... }`
83639      * With `App.Comment`, `"comments"` and `{ id: 1, body: "FIRST" }`
83640      * With `App.Comment`, `"comments"` and `{ id: 2, body: "Rails is unagi" }`
83641       You can use this method, for example, to normalize underscored keys to camelized
83642      or other general-purpose normalizations. You will only need to implement
83643      `normalize` and manipulate the payload as desired.
83644       For example, if the `IDs` under `"comments"` are provided as `_id` instead of
83645      `id`, you can specify how to normalize just the comments:
83646       ```app/serializers/post.js
83647      import DS from 'ember-data';
83648       export default DS.RESTSerializer.extend({
83649        normalize(model, hash, prop) {
83650          if (prop === 'comments') {
83651            hash.id = hash._id;
83652            delete hash._id;
83653          }
83654           return this._super(...arguments);
83655        }
83656      });
83657      ```
83658       On each call to the `normalize` method, the third parameter (`prop`) is always
83659      one of the keys that were in the original payload or in the result of another
83660      normalization as `normalizeResponse`.
83661       @method normalize
83662      @param {DS.Model} modelClass
83663      @param {Object} resourceHash
83664      @param {String} prop
83665      @return {Object}
83666    */
83667    normalize: function normalize(modelClass, resourceHash, prop) {
83668      if (this.normalizeHash && this.normalizeHash[prop]) {
83669        (0, _emberDataPrivateDebug.deprecate)('`RESTSerializer.normalizeHash` has been deprecated. Please use `serializer.normalize` to modify the payload of single resources.', false, {
83670          id: 'ds.serializer.normalize-hash-deprecated',
83671          until: '3.0.0'
83672        });
83673        this.normalizeHash[prop](resourceHash);
83674      }
83675      return this._super(modelClass, resourceHash);
83676    },
83677
83678    /**
83679      Normalizes an array of resource payloads and returns a JSON-API Document
83680      with primary data and, if any, included data as `{ data, included }`.
83681       @method _normalizeArray
83682      @param {DS.Store} store
83683      @param {String} modelName
83684      @param {Object} arrayHash
83685      @param {String} prop
83686      @return {Object}
83687      @private
83688    */
83689    _normalizeArray: function _normalizeArray(store, modelName, arrayHash, prop) {
83690      var _this = this;
83691
83692      var documentHash = {
83693        data: [],
83694        included: []
83695      };
83696
83697      var modelClass = store.modelFor(modelName);
83698      var serializer = store.serializerFor(modelName);
83699
83700      _ember["default"].makeArray(arrayHash).forEach(function (hash) {
83701        var _normalizePolymorphicRecord2 = _this._normalizePolymorphicRecord(store, hash, prop, modelClass, serializer);
83702
83703        var data = _normalizePolymorphicRecord2.data;
83704        var included = _normalizePolymorphicRecord2.included;
83705
83706        documentHash.data.push(data);
83707        if (included) {
83708          var _documentHash$included;
83709
83710          (_documentHash$included = documentHash.included).push.apply(_documentHash$included, _toConsumableArray(included));
83711        }
83712      });
83713
83714      return documentHash;
83715    },
83716
83717    _normalizePolymorphicRecord: function _normalizePolymorphicRecord(store, hash, prop, primaryModelClass, primarySerializer) {
83718      var serializer = primarySerializer;
83719      var modelClass = primaryModelClass;
83720
83721      var primaryHasTypeAttribute = (0, _emberDataPrivateUtils.modelHasAttributeOrRelationshipNamedType)(primaryModelClass);
83722
83723      if (!primaryHasTypeAttribute && hash.type) {
83724        // Support polymorphic records in async relationships
83725        var modelName = undefined;
83726        if (false) {
83727          modelName = this.modelNameFromPayloadType(hash.type);
83728          var deprecatedModelNameLookup = this.modelNameFromPayloadKey(hash.type);
83729
83730          if (modelName !== deprecatedModelNameLookup && !this._hasCustomModelNameFromPayloadType() && this._hasCustomModelNameFromPayloadKey()) {
83731            (0, _emberDataPrivateDebug.deprecate)("You are using modelNameFromPayloadKey to normalize the type for a polymorphic relationship. This is has been deprecated in favor of modelNameFromPayloadType", false, {
83732              id: 'ds.rest-serializer.deprecated-model-name-for-polymorphic-type',
83733              until: '3.0.0'
83734            });
83735
83736            modelName = deprecatedModelNameLookup;
83737          }
83738        } else {
83739          modelName = this.modelNameFromPayloadKey(hash.type);
83740        }
83741
83742        if (store._hasModelFor(modelName)) {
83743          serializer = store.serializerFor(modelName);
83744          modelClass = store.modelFor(modelName);
83745        }
83746      }
83747
83748      return serializer.normalize(modelClass, hash, prop);
83749    },
83750
83751    /*
83752      @method _normalizeResponse
83753      @param {DS.Store} store
83754      @param {DS.Model} primaryModelClass
83755      @param {Object} payload
83756      @param {String|Number} id
83757      @param {String} requestType
83758      @param {Boolean} isSingle
83759      @return {Object} JSON-API Document
83760      @private
83761    */
83762    _normalizeResponse: function _normalizeResponse(store, primaryModelClass, payload, id, requestType, isSingle) {
83763      var documentHash = {
83764        data: null,
83765        included: []
83766      };
83767
83768      var meta = this.extractMeta(store, primaryModelClass, payload);
83769      if (meta) {
83770        (0, _emberDataPrivateDebug.assert)('The `meta` returned from `extractMeta` has to be an object, not "' + _ember["default"].typeOf(meta) + '".', _ember["default"].typeOf(meta) === 'object');
83771        documentHash.meta = meta;
83772      }
83773
83774      var keys = Object.keys(payload);
83775
83776      for (var i = 0, _length = keys.length; i < _length; i++) {
83777        var prop = keys[i];
83778        var modelName = prop;
83779        var forcedSecondary = false;
83780
83781        /*
83782          If you want to provide sideloaded records of the same type that the
83783          primary data you can do that by prefixing the key with `_`.
83784           Example
83785           ```
83786          {
83787            users: [
83788              { id: 1, title: 'Tom', manager: 3 },
83789              { id: 2, title: 'Yehuda', manager: 3 }
83790            ],
83791            _users: [
83792              { id: 3, title: 'Tomster' }
83793            ]
83794          }
83795          ```
83796           This forces `_users` to be added to `included` instead of `data`.
83797         */
83798        if (prop.charAt(0) === '_') {
83799          forcedSecondary = true;
83800          modelName = prop.substr(1);
83801        }
83802
83803        var typeName = this.modelNameFromPayloadKey(modelName);
83804        if (!store.modelFactoryFor(typeName)) {
83805          (0, _emberDataPrivateDebug.warn)(this.warnMessageNoModelForKey(modelName, typeName), false, {
83806            id: 'ds.serializer.model-for-key-missing'
83807          });
83808          continue;
83809        }
83810
83811        var isPrimary = !forcedSecondary && this.isPrimaryType(store, typeName, primaryModelClass);
83812        var value = payload[prop];
83813
83814        if (value === null) {
83815          continue;
83816        }
83817
83818        (0, _emberDataPrivateDebug.runInDebug)(function () {
83819          var isQueryRecordAnArray = requestType === 'queryRecord' && isPrimary && Array.isArray(value);
83820          var message = "The adapter returned an array for the primary data of a `queryRecord` response. This is deprecated as `queryRecord` should return a single record.";
83821
83822          (0, _emberDataPrivateDebug.deprecate)(message, !isQueryRecordAnArray, {
83823            id: 'ds.serializer.rest.queryRecord-array-response',
83824            until: '3.0'
83825          });
83826        });
83827
83828        /*
83829          Support primary data as an object instead of an array.
83830           Example
83831           ```
83832          {
83833            user: { id: 1, title: 'Tom', manager: 3 }
83834          }
83835          ```
83836         */
83837        if (isPrimary && _ember["default"].typeOf(value) !== 'array') {
83838          var _normalizePolymorphicRecord3 = this._normalizePolymorphicRecord(store, value, prop, primaryModelClass, this);
83839
83840          var _data = _normalizePolymorphicRecord3.data;
83841          var _included = _normalizePolymorphicRecord3.included;
83842
83843          documentHash.data = _data;
83844          if (_included) {
83845            var _documentHash$included2;
83846
83847            (_documentHash$included2 = documentHash.included).push.apply(_documentHash$included2, _toConsumableArray(_included));
83848          }
83849          continue;
83850        }
83851
83852        var _normalizeArray2 = this._normalizeArray(store, typeName, value, prop);
83853
83854        var data = _normalizeArray2.data;
83855        var included = _normalizeArray2.included;
83856
83857        if (included) {
83858          var _documentHash$included3;
83859
83860          (_documentHash$included3 = documentHash.included).push.apply(_documentHash$included3, _toConsumableArray(included));
83861        }
83862
83863        if (isSingle) {
83864          data.forEach(function (resource) {
83865
83866            /*
83867              Figures out if this is the primary record or not.
83868               It's either:
83869               1. The record with the same ID as the original request
83870              2. If it's a newly created record without an ID, the first record
83871                 in the array
83872             */
83873            var isUpdatedRecord = isPrimary && (0, _emberDataPrivateSystemCoerceId["default"])(resource.id) === id;
83874            var isFirstCreatedRecord = isPrimary && !id && !documentHash.data;
83875
83876            if (isFirstCreatedRecord || isUpdatedRecord) {
83877              documentHash.data = resource;
83878            } else {
83879              documentHash.included.push(resource);
83880            }
83881          });
83882        } else {
83883          if (isPrimary) {
83884            documentHash.data = data;
83885          } else {
83886            if (data) {
83887              var _documentHash$included4;
83888
83889              (_documentHash$included4 = documentHash.included).push.apply(_documentHash$included4, _toConsumableArray(data));
83890            }
83891          }
83892        }
83893      }
83894
83895      return documentHash;
83896    },
83897
83898    isPrimaryType: function isPrimaryType(store, typeName, primaryTypeClass) {
83899      var typeClass = store.modelFor(typeName);
83900      return typeClass.modelName === primaryTypeClass.modelName;
83901    },
83902
83903    /**
83904      This method allows you to push a payload containing top-level
83905      collections of records organized per type.
83906       ```js
83907      {
83908        "posts": [{
83909          "id": "1",
83910          "title": "Rails is omakase",
83911          "author", "1",
83912          "comments": [ "1" ]
83913        }],
83914        "comments": [{
83915          "id": "1",
83916          "body": "FIRST"
83917        }],
83918        "users": [{
83919          "id": "1",
83920          "name": "@d2h"
83921        }]
83922      }
83923      ```
83924       It will first normalize the payload, so you can use this to push
83925      in data streaming in from your server structured the same way
83926      that fetches and saves are structured.
83927       @method pushPayload
83928      @param {DS.Store} store
83929      @param {Object} payload
83930    */
83931    pushPayload: function pushPayload(store, payload) {
83932      var documentHash = {
83933        data: [],
83934        included: []
83935      };
83936
83937      for (var prop in payload) {
83938        var modelName = this.modelNameFromPayloadKey(prop);
83939        if (!store.modelFactoryFor(modelName)) {
83940          (0, _emberDataPrivateDebug.warn)(this.warnMessageNoModelForKey(prop, modelName), false, {
83941            id: 'ds.serializer.model-for-key-missing'
83942          });
83943          continue;
83944        }
83945        var type = store.modelFor(modelName);
83946        var typeSerializer = store.serializerFor(type.modelName);
83947
83948        _ember["default"].makeArray(payload[prop]).forEach(function (hash) {
83949          var _typeSerializer$normalize = typeSerializer.normalize(type, hash, prop);
83950
83951          var data = _typeSerializer$normalize.data;
83952          var included = _typeSerializer$normalize.included;
83953
83954          documentHash.data.push(data);
83955          if (included) {
83956            var _documentHash$included5;
83957
83958            (_documentHash$included5 = documentHash.included).push.apply(_documentHash$included5, _toConsumableArray(included));
83959          }
83960        });
83961      }
83962
83963      if (false) {
83964        return store.push(documentHash);
83965      } else {
83966        store.push(documentHash);
83967      }
83968    },
83969
83970    /**
83971      This method is used to convert each JSON root key in the payload
83972      into a modelName that it can use to look up the appropriate model for
83973      that part of the payload.
83974       For example, your server may send a model name that does not correspond with
83975      the name of the model in your app. Let's take a look at an example model,
83976      and an example payload:
83977       ```app/models/post.js
83978      import DS from 'ember-data';
83979       export default DS.Model.extend({
83980      });
83981      ```
83982       ```javascript
83983        {
83984          "blog/post": {
83985            "id": "1
83986          }
83987        }
83988      ```
83989       Ember Data is going to normalize the payload's root key for the modelName. As a result,
83990      it will try to look up the "blog/post" model. Since we don't have a model called "blog/post"
83991      (or a file called app/models/blog/post.js in ember-cli), Ember Data will throw an error
83992      because it cannot find the "blog/post" model.
83993       Since we want to remove this namespace, we can define a serializer for the application that will
83994      remove "blog/" from the payload key whenver it's encountered by Ember Data:
83995       ```app/serializers/application.js
83996      import DS from 'ember-data';
83997       export default DS.RESTSerializer.extend({
83998        modelNameFromPayloadKey: function(payloadKey) {
83999          if (payloadKey === 'blog/post') {
84000            return this._super(payloadKey.replace('blog/', ''));
84001          } else {
84002           return this._super(payloadKey);
84003          }
84004        }
84005      });
84006      ```
84007       After refreshing, Ember Data will appropriately look up the "post" model.
84008       By default the modelName for a model is its
84009      name in dasherized form. This means that a payload key like "blogPost" would be
84010      normalized to "blog-post" when Ember Data looks up the model. Usually, Ember Data
84011      can use the correct inflection to do this for you. Most of the time, you won't
84012      need to override `modelNameFromPayloadKey` for this purpose.
84013       @method modelNameFromPayloadKey
84014      @param {String} key
84015      @return {String} the model's modelName
84016    */
84017    modelNameFromPayloadKey: function modelNameFromPayloadKey(key) {
84018      return (0, _emberInflector.singularize)((0, _emberDataPrivateSystemNormalizeModelName["default"])(key));
84019    },
84020
84021    // SERIALIZE
84022
84023    /**
84024      Called when a record is saved in order to convert the
84025      record into JSON.
84026       By default, it creates a JSON object with a key for
84027      each attribute and belongsTo relationship.
84028       For example, consider this model:
84029       ```app/models/comment.js
84030      import DS from 'ember-data';
84031       export default DS.Model.extend({
84032        title: DS.attr(),
84033        body: DS.attr(),
84034         author: DS.belongsTo('user')
84035      });
84036      ```
84037       The default serialization would create a JSON object like:
84038       ```js
84039      {
84040        "title": "Rails is unagi",
84041        "body": "Rails? Omakase? O_O",
84042        "author": 12
84043      }
84044      ```
84045       By default, attributes are passed through as-is, unless
84046      you specified an attribute type (`DS.attr('date')`). If
84047      you specify a transform, the JavaScript value will be
84048      serialized when inserted into the JSON hash.
84049       By default, belongs-to relationships are converted into
84050      IDs when inserted into the JSON hash.
84051       ## IDs
84052       `serialize` takes an options hash with a single option:
84053      `includeId`. If this option is `true`, `serialize` will,
84054      by default include the ID in the JSON object it builds.
84055       The adapter passes in `includeId: true` when serializing
84056      a record for `createRecord`, but not for `updateRecord`.
84057       ## Customization
84058       Your server may expect a different JSON format than the
84059      built-in serialization format.
84060       In that case, you can implement `serialize` yourself and
84061      return a JSON hash of your choosing.
84062       ```app/serializers/post.js
84063      import DS from 'ember-data';
84064       export default DS.RESTSerializer.extend({
84065        serialize: function(snapshot, options) {
84066          var json = {
84067            POST_TTL: snapshot.attr('title'),
84068            POST_BDY: snapshot.attr('body'),
84069            POST_CMS: snapshot.hasMany('comments', { ids: true })
84070          }
84071           if (options.includeId) {
84072            json.POST_ID_ = snapshot.id;
84073          }
84074           return json;
84075        }
84076      });
84077      ```
84078       ## Customizing an App-Wide Serializer
84079       If you want to define a serializer for your entire
84080      application, you'll probably want to use `eachAttribute`
84081      and `eachRelationship` on the record.
84082       ```app/serializers/application.js
84083      import DS from 'ember-data';
84084       export default DS.RESTSerializer.extend({
84085        serialize: function(snapshot, options) {
84086          var json = {};
84087           snapshot.eachAttribute(function(name) {
84088            json[serverAttributeName(name)] = snapshot.attr(name);
84089          })
84090           snapshot.eachRelationship(function(name, relationship) {
84091            if (relationship.kind === 'hasMany') {
84092              json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
84093            }
84094          });
84095           if (options.includeId) {
84096            json.ID_ = snapshot.id;
84097          }
84098           return json;
84099        }
84100      });
84101       function serverAttributeName(attribute) {
84102        return attribute.underscore().toUpperCase();
84103      }
84104       function serverHasManyName(name) {
84105        return serverAttributeName(name.singularize()) + "_IDS";
84106      }
84107      ```
84108       This serializer will generate JSON that looks like this:
84109       ```js
84110      {
84111        "TITLE": "Rails is omakase",
84112        "BODY": "Yep. Omakase.",
84113        "COMMENT_IDS": [ 1, 2, 3 ]
84114      }
84115      ```
84116       ## Tweaking the Default JSON
84117       If you just want to do some small tweaks on the default JSON,
84118      you can call super first and make the tweaks on the returned
84119      JSON.
84120       ```app/serializers/post.js
84121      import DS from 'ember-data';
84122       export default DS.RESTSerializer.extend({
84123        serialize: function(snapshot, options) {
84124          var json = this._super(snapshot, options);
84125           json.subject = json.title;
84126          delete json.title;
84127           return json;
84128        }
84129      });
84130      ```
84131       @method serialize
84132      @param {DS.Snapshot} snapshot
84133      @param {Object} options
84134      @return {Object} json
84135    */
84136    serialize: function serialize(snapshot, options) {
84137      return this._super.apply(this, arguments);
84138    },
84139
84140    /**
84141      You can use this method to customize the root keys serialized into the JSON.
84142      The hash property should be modified by reference (possibly using something like _.extend)
84143      By default the REST Serializer sends the modelName of a model, which is a camelized
84144      version of the name.
84145       For example, your server may expect underscored root objects.
84146       ```app/serializers/application.js
84147      import DS from 'ember-data';
84148       export default DS.RESTSerializer.extend({
84149        serializeIntoHash: function(data, type, record, options) {
84150          var root = Ember.String.decamelize(type.modelName);
84151          data[root] = this.serialize(record, options);
84152        }
84153      });
84154      ```
84155       @method serializeIntoHash
84156      @param {Object} hash
84157      @param {DS.Model} typeClass
84158      @param {DS.Snapshot} snapshot
84159      @param {Object} options
84160    */
84161    serializeIntoHash: function serializeIntoHash(hash, typeClass, snapshot, options) {
84162      var normalizedRootKey = this.payloadKeyFromModelName(typeClass.modelName);
84163      hash[normalizedRootKey] = this.serialize(snapshot, options);
84164    },
84165
84166    /**
84167      You can use `payloadKeyFromModelName` to override the root key for an outgoing
84168      request. By default, the RESTSerializer returns a camelized version of the
84169      model's name.
84170       For a model called TacoParty, its `modelName` would be the string `taco-party`. The RESTSerializer
84171      will send it to the server with `tacoParty` as the root key in the JSON payload:
84172       ```js
84173      {
84174        "tacoParty": {
84175          "id": "1",
84176          "location": "Matthew Beale's House"
84177        }
84178      }
84179      ```
84180       For example, your server may expect dasherized root objects:
84181       ```app/serializers/application.js
84182      import DS from 'ember-data';
84183       export default DS.RESTSerializer.extend({
84184        payloadKeyFromModelName: function(modelName) {
84185          return Ember.String.dasherize(modelName);
84186        }
84187      });
84188      ```
84189       Given a `TacoParty` model, calling `save` on it would produce an outgoing
84190      request like:
84191       ```js
84192      {
84193        "taco-party": {
84194          "id": "1",
84195          "location": "Matthew Beale's House"
84196        }
84197      }
84198      ```
84199       @method payloadKeyFromModelName
84200      @param {String} modelName
84201      @return {String}
84202    */
84203    payloadKeyFromModelName: function payloadKeyFromModelName(modelName) {
84204      return camelize(modelName);
84205    },
84206
84207    /**
84208      You can use this method to customize how polymorphic objects are serialized.
84209      By default the REST Serializer creates the key by appending `Type` to
84210      the attribute and value from the model's camelcased model name.
84211       @method serializePolymorphicType
84212      @param {DS.Snapshot} snapshot
84213      @param {Object} json
84214      @param {Object} relationship
84215    */
84216    serializePolymorphicType: function serializePolymorphicType(snapshot, json, relationship) {
84217      var key = relationship.key;
84218      var belongsTo = snapshot.belongsTo(key);
84219      var typeKey = this.keyForPolymorphicType(key, relationship.type, 'serialize');
84220
84221      // old way of getting the key for the polymorphic type
84222      key = this.keyForAttribute ? this.keyForAttribute(key, "serialize") : key;
84223      key = key + "Type";
84224
84225      // The old way of serializing the type of a polymorphic record used
84226      // `keyForAttribute`, which is not correct. The next code checks if the old
84227      // way is used and if it differs from the new way of using
84228      // `keyForPolymorphicType`. If this is the case, a deprecation warning is
84229      // logged and the old way is restored (so nothing breaks).
84230      if (key !== typeKey && this.keyForPolymorphicType === RESTSerializer.prototype.keyForPolymorphicType) {
84231        (0, _emberDataPrivateDebug.deprecate)("The key to serialize the type of a polymorphic record is created via keyForAttribute which has been deprecated. Use the keyForPolymorphicType hook instead.", false, {
84232          id: 'ds.rest-serializer.deprecated-key-for-polymorphic-type',
84233          until: '3.0.0'
84234        });
84235
84236        typeKey = key;
84237      }
84238
84239      if (_ember["default"].isNone(belongsTo)) {
84240        json[typeKey] = null;
84241      } else {
84242        if (false) {
84243          json[typeKey] = this.payloadTypeFromModelName(belongsTo.modelName);
84244        } else {
84245          json[typeKey] = camelize(belongsTo.modelName);
84246        }
84247      }
84248    },
84249
84250    /**
84251      You can use this method to customize how a polymorphic relationship should
84252      be extracted.
84253       @method extractPolymorphicRelationship
84254      @param {Object} relationshipType
84255      @param {Object} relationshipHash
84256      @param {Object} relationshipOptions
84257      @return {Object}
84258     */
84259    extractPolymorphicRelationship: function extractPolymorphicRelationship(relationshipType, relationshipHash, relationshipOptions) {
84260      var key = relationshipOptions.key;
84261      var resourceHash = relationshipOptions.resourceHash;
84262      var relationshipMeta = relationshipOptions.relationshipMeta;
84263
84264      // A polymorphic belongsTo relationship can be present in the payload
84265      // either in the form where the `id` and the `type` are given:
84266      //
84267      //   {
84268      //     message: { id: 1, type: 'post' }
84269      //   }
84270      //
84271      // or by the `id` and a `<relationship>Type` attribute:
84272      //
84273      //   {
84274      //     message: 1,
84275      //     messageType: 'post'
84276      //   }
84277      //
84278      // The next code checks if the latter case is present and returns the
84279      // corresponding JSON-API representation. The former case is handled within
84280      // the base class JSONSerializer.
84281      var isPolymorphic = relationshipMeta.options.polymorphic;
84282      var typeProperty = this.keyForPolymorphicType(key, relationshipType, 'deserialize');
84283
84284      if (isPolymorphic && resourceHash[typeProperty] !== undefined && typeof relationshipHash !== 'object') {
84285
84286        if (false) {
84287
84288          var payloadType = resourceHash[typeProperty];
84289          var type = this.modelNameFromPayloadType(payloadType);
84290          var deprecatedTypeLookup = this.modelNameFromPayloadKey(payloadType);
84291
84292          if (payloadType !== deprecatedTypeLookup && !this._hasCustomModelNameFromPayloadType() && this._hasCustomModelNameFromPayloadKey()) {
84293            (0, _emberDataPrivateDebug.deprecate)("You are using modelNameFromPayloadKey to normalize the type for a polymorphic relationship. This has been deprecated 
84293in favor of modelNameFromPayloadType", false, {
84294              id: 'ds.rest-serializer.deprecated-model-name-for-polymorphic-type',
84295              until: '3.0.0'
84296            });
84297
84298            type = deprecatedTypeLookup;
84299          }
84300
84301          return {
84302            id: relationshipHash,
84303            type: type
84304          };
84305        } else {
84306
84307          var type = this.modelNameFromPayloadKey(resourceHash[typeProperty]);
84308          return {
84309            id: relationshipHash,
84310            type: type
84311          };
84312        }
84313      }
84314
84315      return this._super.apply(this, arguments);
84316    }
84317  });
84318
84319  if (false) {
84320
84321    RESTSerializer.reopen({
84322
84323      /**
84324        `modelNameFromPayloadType` can be used to change the mapping for a DS model
84325        name, taken from the value in the payload.
84326         Say your API namespaces the type of a model and returns the following
84327        payload for the `post` model, which has a polymorphic `user` relationship:
84328         ```javascript
84329        // GET /api/posts/1
84330        {
84331          "post": {
84332            "id": 1,
84333            "user": 1,
84334            "userType: "api::v1::administrator"
84335          }
84336        }
84337        ```
84338         By overwriting `modelNameFromPayloadType` you can specify that the
84339        `administrator` model should be used:
84340         ```app/serializers/application.js
84341        import DS from "ember-data";
84342         export default DS.RESTSerializer.extend({
84343          modelNameFromPayloadType(payloadType) {
84344            return payloadType.replace('api::v1::', '');
84345          }
84346        });
84347        ```
84348         By default the modelName for a model is its name in dasherized form.
84349        Usually, Ember Data can use the correct inflection to do this for you. Most
84350        of the time, you won't need to override `modelNameFromPayloadType` for this
84351        purpose.
84352         Also take a look at
84353        [payloadTypeFromModelName](#method_payloadTypeFromModelName) to customize
84354        how the type of a record should be serialized.
84355         @method modelNameFromPayloadType
84356        @public
84357        @param {String} payloadType type from payload
84358        @return {String} modelName
84359      */
84360      modelNameFromPayloadType: function modelNameFromPayloadType(payloadType) {
84361        return (0, _emberInflector.singularize)((0, _emberDataPrivateSystemNormalizeModelName["default"])(payloadType));
84362      },
84363
84364      /**
84365        `payloadTypeFromModelName` can be used to change the mapping for the type in
84366        the payload, taken from the model name.
84367         Say your API namespaces the type of a model and expects the following
84368        payload when you update the `post` model, which has a polymorphic `user`
84369        relationship:
84370         ```javascript
84371        // POST /api/posts/1
84372        {
84373          "post": {
84374            "id": 1,
84375            "user": 1,
84376            "userType": "api::v1::administrator"
84377          }
84378        }
84379        ```
84380         By overwriting `payloadTypeFromModelName` you can specify that the
84381        namespaces model name for the `administrator` should be used:
84382         ```app/serializers/application.js
84383        import DS from "ember-data";
84384         export default DS.RESTSerializer.extend({
84385          payloadTypeFromModelName(modelName) {
84386            return "api::v1::" + modelName;
84387          }
84388        });
84389        ```
84390         By default the payload type is the camelized model name. Usually, Ember
84391        Data can use the correct inflection to do this for you. Most of the time,
84392        you won't need to override `payloadTypeFromModelName` for this purpose.
84393         Also take a look at
84394        [modelNameFromPayloadType](#method_modelNameFromPayloadType) to customize
84395        how the model name from should be mapped from the payload.
84396         @method payloadTypeFromModelName
84397        @public
84398        @param {String} modelname modelName from the record
84399        @return {String} payloadType
84400      */
84401      payloadTypeFromModelName: function payloadTypeFromModelName(modelName) {
84402        return camelize(modelName);
84403      },
84404
84405      _hasCustomModelNameFromPayloadKey: function _hasCustomModelNameFromPayloadKey() {
84406        return this.modelNameFromPayloadKey !== RESTSerializer.prototype.modelNameFromPayloadKey;
84407      },
84408
84409      _hasCustomModelNameFromPayloadType: function _hasCustomModelNameFromPayloadType() {
84410        return this.modelNameFromPayloadType !== RESTSerializer.prototype.modelNameFromPayloadType;
84411      },
84412
84413      _hasCustomPayloadTypeFromModelName: function _hasCustomPayloadTypeFromModelName() {
84414        return this.payloadTypeFromModelName !== RESTSerializer.prototype.payloadTypeFromModelName;
84415      },
84416
84417      _hasCustomPayloadKeyFromModelName: function _hasCustomPayloadKeyFromModelName() {
84418        return this.payloadKeyFromModelName !== RESTSerializer.prototype.payloadKeyFromModelName;
84419      }
84420
84421    });
84422  }
84423
84424  (0, _emberDataPrivateDebug.runInDebug)(function () {
84425    RESTSerializer.reopen({
84426      warnMessageNoModelForKey: function warnMessageNoModelForKey(prop, typeKey) {
84427        return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + typeKey + '" (resolved model name using ' + this.constructor.toString() + '.modelNameFromPayloadKey("' + prop + '"))';
84428      }
84429    });
84430  });
84431
84432  exports["default"] = RESTSerializer;
84433});
84434define('ember-data/setup-container', ['exports', 'ember-data/-private/initializer
84434s/store', 'ember-data/-private/initializers/transforms', 'ember-data/-private/initializers/store-injections', 'ember-data/-private/initializers/data-adapter'], function (exports, _emberDataPrivateInitializersStore, _emberDataPrivateInitializersTransforms, _emberDataPrivateInitializersStoreInjections, _emberDataPrivateInitializersDataAdapter) {
84435  'use strict';
84436
84437  exports['default'] = setupContainer;
84438
84439  function setupContainer(application) {
84440    (0, _emberDataPrivateInitializersDataAdapter['default'])(application);
84441    (0, _emberDataPrivateInitializersTransforms['default'])(application);
84442    (0, _emberDataPrivateInitializersStoreInjections['default'])(application);
84443    (0, _emberDataPrivateInitializersStore['default'])(application);
84444  }
84445});
84446define("ember-data/store", ["exports", "ember-data/-private/system/store"], function (exports, _emberDataPrivateSystemStore) {
84447  "use strict";
84448
84449  exports["default"] = _emberDataPrivateSystemStore["default"];
84450});
84451define('ember-data/transform', ['exports', 'ember'], function (exports, _ember) {
84452  'use strict';
84453
84454  /**
84455    The `DS.Transform` class is used to serialize and deserialize model
84456    attributes when they are saved or loaded from an
84457    adapter. Subclassing `DS.Transform` is useful for creating custom
84458    attributes. All subclasses of `DS.Transform` must implement a
84459    `serialize` and a `deserialize` method.
84460  
84461    Example
84462  
84463    ```app/transforms/temperature.js
84464    import DS from 'ember-data';
84465  
84466    // Converts centigrade in the JSON to fahrenheit in the app
84467    export default DS.Transform.extend({
84468      deserialize: function(serialized) {
84469        return (serialized *  1.8) + 32;
84470      },
84471      serialize: function(deserialized) {
84472        return (deserialized - 32) / 1.8;
84473      }
84474    });
84475    ```
84476  
84477    Usage
84478  
84479    ```app/models/requirement.js
84480    import DS from 'ember-data';
84481  
84482    export default DS.Model.extend({
84483      name: DS.attr('string'),
84484      temperature: DS.attr('temperature')
84485    });
84486    ```
84487  
84488    @class Transform
84489    @namespace DS
84490   */
84491  exports['default'] = _ember['default'].Object.extend({
84492    /**
84493      When given a deserialized value from a record attribute this
84494      method must return the serialized value.
84495       Example
84496       ```javascript
84497      serialize: function(deserialized, options) {
84498        return Ember.isEmpty(deserialized) ? null : Number(deserialized);
84499      }
84500      ```
84501       @method serialize
84502      @param deserialized The deserialized value
84503      @param options hash of options passed to `DS.attr`
84504      @return The serialized value
84505    */
84506    serialize: null,
84507
84508    /**
84509      When given a serialize value from a JSON object this method must
84510      return the deserialized value for the record attribute.
84511       Example
84512       ```javascript
84513      deserialize: function(serialized, options) {
84514        return empty(serialized) ? null : Number(serialized);
84515      }
84516      ```
84517       @method deserialize
84518      @param serialized The serialized value
84519      @param options hash of options passed to `DS.attr`
84520      @return The deserialized value
84521    */
84522    deserialize: null
84523  });
84524});
84525define("ember-data/version", ["exports"], function (exports) {
84526  "use strict";
84527
84528  exports["default"] = "2.7.0";
84529});
84530define("ember-inflector/index", ["exports", "ember", "ember-inflector/lib/system", "ember-inflector/lib/ext/string"], function (exports, _ember, _emberInflectorLibSystem, _emberInflectorLibExtString) {
84531  /* global define, module */
84532
84533  "use strict";
84534
84535  _emberInflectorLibSystem.Inflector.defaultRules = _emberInflectorLibSystem.defaultRules;
84536  _ember["default"].Inflector = _emberInflectorLibSystem.Inflector;
84537
84538  _ember["default"].String.pluralize = _emberInflectorLibSystem.pluralize;
84539  _ember["default"].String.singularize = _emberInflectorLibSystem.singularize;exports["default"] = _emberInflectorLibSystem.Inflector;
84540  exports.pluralize = _emberInflectorLibSystem.pluralize;
84541  exports.singularize = _emberInflectorLibSystem.singularize;
84542  exports.defaultRules = _emberInflectorLibSystem.defaultRules;
84543
84544  if (typeof define !== 'undefined' && define.amd) {
84545    define('ember-inflector', ['exports'], function (__exports__) {
84546      __exports__['default'] = _emberInflectorLibSystem.Inflector;
84547      return _emberInflectorLibSystem.Inflector;
84548    });
84549  } else if (typeof module !== 'undefined' && module['exports']) {
84550    module['exports'] = _emberInflectorLibSystem.Inflector;
84551  }
84552});
84553define('ember-inflector/lib/ext/string', ['exports', 'ember', 'ember-inflector/lib/system/string'], function (exports, _ember, _emberInflectorLibSystemString) {
84554  'use strict';
84555
84556  if (_ember['default'].EXTEND_PROTOTYPES === true || _ember['default'].EXTEND_PROTOTYPES.String) {
84557    /**
84558      See {{#crossLink "Ember.String/pluralize"}}{{/crossLink}}
84559       @method pluralize
84560      @for String
84561    */
84562    String.prototype.pluralize = function () {
84563      return (0, _emberInflectorLibSystemString.pluralize)(this);
84564    };
84565
84566    /**
84567      See {{#crossLink "Ember.String/singularize"}}{{/crossLink}}
84568       @method singularize
84569      @for String
84570    */
84571    String.prototype.singularize = function () {
84572      return (0, _emberInflectorLibSystemString.singularize)(this);
84573    };
84574  }
84575});
84576define('ember-inflector/lib/helpers/pluralize', ['exports', 'ember-inflector', 'ember-inflector/lib/utils/make-helper'], function (exports, _emberInflector, _emberInflectorLibUtilsMakeHelper) {
84577  'use strict';
84578
84579  /**
84580   *
84581   * If you have Ember Inflector (such as if Ember Data is present),
84582   * pluralize a word. For example, turn "ox" into "oxen".
84583   *
84584   * Example:
84585   *
84586   * {{pluralize count myProperty}}
84587   * {{pluralize 1 "oxen"}}
84588   * {{pluralize myProperty}}
84589   * {{pluralize "ox"}}
84590   *
84591   * @for Ember.HTMLBars.helpers
84592   * @method pluralize
84593   * @param {Number|Property} [count] count of objects
84594   * @param {String|Property} word word to pluralize
84595  */
84596  exports['default'] = (0, _emberInflectorLibUtilsMakeHelper['default'])(function (params) {
84597    var count = undefined,
84598        word = undefined;
84599
84600    if (params.length === 1) {
84601      word = params[0];
84602      return (0, _emberInflector.pluralize)(word);
84603    } else {
84604      count = params[0];
84605      word = params[1];
84606
84607      if (parseFloat(count) !== 1) {
84608        word = (0, _emberInflector.pluralize)(word);
84609      }
84610
84611      return count + " " + word;
84612    }
84613  });
84614});
84615define('ember-inflector/lib/helpers/singularize', ['exports', 'ember-inflector', 'ember-inflector/lib/utils/make-helper'], function (exports, _emberInflector, _emberInflectorLibUtilsMakeHelper) {
84616  'use strict';
84617
84618  /**
84619   *
84620   * If you have Ember Inflector (such as if Ember Data is present),
84621   * singularize a word. For example, turn "oxen" into "ox".
84622   *
84623   * Example:
84624   *
84625   * {{singularize myProperty}}
84626   * {{singularize "oxen"}}
84627   *
84628   * @for Ember.HTMLBars.helpers
84629   * @method singularize
84630   * @param {String|Property} word word to singularize
84631  */
84632  exports['default'] = (0, _emberInflectorLibUtilsMakeHelper['default'])(function (params) {
84633    return (0, _emberInflector.singularize)(params[0]);
84634  });
84635});
84636define("ember-inflector/lib/system", ["exports", "ember-inflector/lib/system/inflector", "ember-inflector/lib/system/string", "ember-inflector/lib/system/inflections"], function (exports, _emberInflectorLibSystemInflector, _emberInflectorLibSystemString, _emberInflectorLibSystemInflections) {
84637  "use strict";
84638
84639  _emberInflectorLibSystemInflector["default"].inflector = new _emberInflectorLibSystemInflector["default"](_emberInflectorLibSystemInflections["default"]);
84640
84641  exports.Inflector = _emberInflectorLibSystemInflector["default"];
84642  exports.singularize = _emberInflectorLibSystemString.singularize;
84643  exports.pluralize = _emberInflectorLibSystemString.pluralize;
84644  exports.defaultRules = _emberInflectorLibSystemInflections["default"];
84645});
84646define('ember-inflector/lib/system/inflections', ['exports'], function (exports) {
84647  'use strict';
84648
84649  exports['default'] = {
84650    plurals: [[/$/, 's'], [/s$/i, 's'], [/^(ax|test)is$/i, '$1es'], [/(octop|vir)us$/i, '$1i'], [/(octop|vir)i$/i, '$1i'], [/(alias|status|bonus)$/i, '$1es'], [/(bu)s$/i, '$1ses'], [/(buffal|tomat)o$/i, '$1oes'], [/([ti])um$/i, '$1a'], [/([ti])a$/i, '$1a'], [/sis$/i, 'ses'], [/(?:([^f])fe|([lr])f)$/i, '$1$2ves'], [/(hive)$/i, '$1s'], [/([^aeiouy]|qu)y$/i, '$1ies'], [/(x|ch|ss|sh)$/i, '$1es'], [/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'], [/^(m|l)ouse$/i, '$1ice'], [/^(m|l)ice$/i, '$1ice'], [/^(ox)$/i, '$1en'], [/^(oxen)$/i, '$1'], [/(quiz)$/i, '$1zes']],
84651
84652    singular: [[/s$/i, ''], [/(ss)$/i, '$1'], [/(n)ews$/i, '$1ews'], [/([ti])a$/i, '$1um'], [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis'], [/(^anal
84652y)(sis|ses)$/i, '$1sis'], [/([^f])ves$/i, '$1fe'], [/(hive)s$/i, '$1'], [/(tive)s$/i, '$1'], [/([lr])ves$/i, '$1f'], [/([^aeiouy]|qu)ies$/i, '$1y'], [/(s)eries$/i, '$1eries'], [/(m)ovies$/i, '$1ovie'], [/(x|ch|ss|sh)es$/i, '$1'], [/^(m|l)ice$/i, '$1ouse'], [/(bus)(es)?$/i, '$1'], [/(o)es$/i, '$1'], [/(shoe)s$/i, '$1'], [/(cris|test)(is|es)$/i, '$1is'], [/^(a)x[ie]s$/i, '$1xis'], [/(octop|vir)(us|i)$/i, '$1us'], [/(alias|status|bonus)(es)?$/i, '$1'], [/^(ox)en/i, '$1'], [/(vert|ind)ices$/i, '$1ex'], [/(matr)ices$/i, '$1ix'], [/(quiz)zes$/i, '$1'], [/(database)s$/i, '$1']],
84653
84654    irregularPairs: [['person', 'people'], ['man', 'men'], ['child', 'children'], ['sex', 'sexes'], ['move', 'moves'], ['cow', 'kine'], ['zombie', 'zombies']],
84655
84656    uncountable: ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'jeans', 'police']
84657  };
84658});
84659define('ember-inflector/lib/system/inflector', ['exports', 'ember'], function (exports, _ember) {
84660  'use strict';
84661
84662  var capitalize = _ember['default'].String.capitalize;
84663
84664  var BLANK_REGEX = /^\s*$/;
84665  var LAST_WORD_DASHED_REGEX = /([\w/-]+[_/\s-])([a-z\d]+$)/;
84666  var LAST_WORD_CAMELIZED_REGEX = /([\w/\s-]+)([A-Z][a-z\d]*$)/;
84667  var CAMELIZED_REGEX = /[A-Z][a-z\d]*$/;
84668
84669  function loadUncountable(rules, uncountable) {
84670    for (var i = 0, length = uncountable.length; i < length; i++) {
84671      rules.uncountable[uncountable[i].toLowerCase()] = true;
84672    }
84673  }
84674
84675  function loadIrregular(rules, irregularPairs) {
84676    var pair;
84677
84678    for (var i = 0, length = irregularPairs.length; i < length; i++) {
84679      pair = irregularPairs[i];
84680
84681      //pluralizing
84682      rules.irregular[pair[0].toLowerCase()] = pair[1];
84683      rules.irregular[pair[1].toLowerCase()] = pair[1];
84684
84685      //singularizing
84686      rules.irregularInverse[pair[1].toLowerCase()] = pair[0];
84687      rules.irregularInverse[pair[0].toLowerCase()] = pair[0];
84688    }
84689  }
84690
84691  /**
84692    Inflector.Ember provides a mechanism for supplying inflection rules for your
84693    application. Ember includes a default set of inflection rules, and provides an
84694    API for providing additional rules.
84695  
84696    Examples:
84697  
84698    Creating an inflector with no rules.
84699  
84700    ```js
84701    var inflector = new Ember.Inflector();
84702    ```
84703  
84704    Creating an inflector with the default ember ruleset.
84705  
84706    ```js
84707    var inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
84708  
84709    inflector.pluralize('cow'); //=> 'kine'
84710    inflector.singularize('kine'); //=> 'cow'
84711    ```
84712  
84713    Creating an inflector and adding rules later.
84714  
84715    ```javascript
84716    var inflector = Ember.Inflector.inflector;
84717  
84718    inflector.pluralize('advice'); // => 'advices'
84719    inflector.uncountable('advice');
84720    inflector.pluralize('advice'); // => 'advice'
84721  
84722    inflector.pluralize('formula'); // => 'formulas'
84723    inflector.irregular('formula', 'formulae');
84724    inflector.pluralize('formula'); // => 'formulae'
84725  
84726    // you would not need to add these as they are the default rules
84727    inflector.plural(/$/, 's');
84728    inflector.singular(/s$/i, '');
84729    ```
84730  
84731    Creating an inflector with a nondefault ruleset.
84732  
84733    ```javascript
84734    var rules = {
84735      plurals:  [ /$/, 's' ],
84736      singular: [ /\s$/, '' ],
84737      irregularPairs: [
84738        [ 'cow', 'kine' ]
84739      ],
84740      uncountable: [ 'fish' ]
84741    };
84742  
84743    var inflector = new Ember.Inflector(rules);
84744    ```
84745  
84746    @class Inflector
84747    @namespace Ember
84748  */
84749  function Inflector(ruleSet) {
84750    ruleSet = ruleSet || {};
84751    ruleSet.uncountable = ruleSet.uncountable || makeDictionary();
84752    ruleSet.irregularPairs = ruleSet.irregularPairs || makeDictionary();
84753
84754    var rules = this.rules = {
84755      plurals: ruleSet.plurals || [],
84756      singular: ruleSet.singular || [],
84757      irregular: makeDictionary(),
84758      irregularInverse: makeDictionary(),
84759      uncountable: makeDictionary()
84760    };
84761
84762    loadUncountable(rules, ruleSet.uncountable);
84763    loadIrregular(rules, ruleSet.irregularPairs);
84764
84765    this.enableCache();
84766  }
84767
84768  if (!Object.create && !Object.create(null).hasOwnProperty) {
84769    throw new Error("This browser does not support Object.create(null), please polyfil with es5-sham: http://git.io/yBU2rg");
84770  }
84771
84772  function makeDictionary() {
84773    var cache = Object.create(null);
84774    cache['_dict'] = null;
84775    delete cache['_dict'];
84776    return cache;
84777  }
84778
84779  Inflector.prototype = {
84780    /**
84781      @public
84782       As inflections can be costly, and commonly the same subset of words are repeatedly
84783      inflected an optional cache is provided.
84784       @method enableCache
84785    */
84786    enableCache: function enableCache() {
84787      this.purgeCache();
84788
84789      this.singularize = function (word) {
84790        this._cacheUsed = true;
84791        return this._sCache[word] || (this._sCache[word] = this._singularize(word));
84792      };
84793
84794      this.pluralize = function (word) {
84795        this._cacheUsed = true;
84796        return this._pCache[word] || (this._pCache[word] = this._pluralize(word));
84797      };
84798    },
84799
84800    /**
84801      @public
84802       @method purgedCache
84803    */
84804    purgeCache: function purgeCache() {
84805      this._cacheUsed = false;
84806      this._sCache = makeDictionary();
84807      this._pCache = makeDictionary();
84808    },
84809
84810    /**
84811      @public
84812      disable caching
84813       @method disableCache;
84814    */
84815    disableCache: function disableCache() {
84816      this._sCache = null;
84817      this._pCache = null;
84818      this.singularize = function (word) {
84819        return this._singularize(word);
84820      };
84821
84822      this.pluralize = function (word) {
84823        return this._pluralize(word);
84824      };
84825    },
84826
84827    /**
84828      @method plural
84829      @param {RegExp} regex
84830      @param {String} string
84831    */
84832    plural: function plural(regex, string) {
84833      if (this._cacheUsed) {
84834        this.purgeCache();
84835      }
84836      this.rules.plurals.push([regex, string.toLowerCase()]);
84837    },
84838
84839    /**
84840      @method singular
84841      @param {RegExp} regex
84842      @param {String} string
84843    */
84844    singular: function singular(regex, string) {
84845      if (this._cacheUsed) {
84846        this.purgeCache();
84847      }
84848      this.rules.singular.push([regex, string.toLowerCase()]);
84849    },
84850
84851    /**
84852      @method uncountable
84853      @param {String} regex
84854    */
84855    uncountable: function uncountable(string) {
84856      if (this._cacheUsed) {
84857        this.purgeCache();
84858      }
84859      loadUncountable(this.rules, [string.toLowerCase()]);
84860    },
84861
84862    /**
84863      @method irregular
84864      @param {String} singular
84865      @param {String} plural
84866    */
84867    irregular: function irregular(singular, plural) {
84868      if (this._cacheUsed) {
84869        this.purgeCache();
84870      }
84871      loadIrregular(this.rules, [[singular, plural]]);
84872    },
84873
84874    /**
84875      @method pluralize
84876      @param {String} word
84877    */
84878    pluralize: function pluralize(word) {
84879      return this._pluralize(word);
84880    },
84881
84882    _pluralize: function _pluralize(word) {
84883      return this.inflect(word, this.rules.plurals, this.rules.irregular);
84884    },
84885    /**
84886      @method singularize
84887      @param {String} word
84888    */
84889    singularize: function singularize(word) {
84890      return this._singularize(word);
84891    },
84892
84893    _singularize: function _singularize(word) {
84894      return this.inflect(word, this.rules.singular, this.rules.irregularInverse);
84895    },
84896
84897    /**
84898      @protected
84899       @method inflect
84900      @param {String} word
84901      @param {Object} typeRules
84902      @param {Object} irregular
84903    */
84904    inflect: function inflect(word, typeRules, irregular) {
84905      var inflection, substitution, result, lowercase, wordSplit, firstPhrase, lastWord, isBlank, isCamelized, rule, isUncountable;
84906
84907      isBlank = !word || BLANK_REGEX.test(word);
84908
84909      isCamelized = CAMELIZED_REGEX.test(word);
84910      firstPhrase = "";
84911
84912      if (isBlank) {
84913        return word;
84914      }
84915
84916      lowercase = word.toLowerCase();
84917      wordSplit = LAST_WORD_DASHED_REGEX.exec(word) || LAST_WORD_CAMELIZED_REGEX.exec(word);
84918
84919      if (wordSplit) {
84920        firstPhrase = wordSplit[1];
84921        lastWord = wordSplit[2].toLowerCase();
84922      }
84923
84924      isUncountable = this.rules.uncountable[lowercase] || this.rules.uncountable[lastWord];
84925
84926      if (isUncountable) {
84927        return word;
84928      }
84929
84930      for (rule in irregular) {
84931        if (lowercase.match(rule + "$")) {
84932          substitution = irregular[rule];
84933
84934          if (isCamelized && irregular[lastWord]) {
84935            substitution = capitalize(substitution);
84936            rule = capitalize(rule);
84937          }
84938
84939          return word.replace(new RegExp(rule, 'i'), substitution);
84940        }
84941      }
84942
84943      for (var i = typeRules.length, min = 0; i > min; i--) {
84944        inflection = typeRules[i - 1];
84945        rule = inflection[0];
84946
84947        if (rule.test(word)) {
84948          break;
84949        }
84950      }
84951
84952      inflection = inflection || [];
84953
84954      rule = inflection[0];
84955      substitution = inflection[1];
84956
84957      result = word.replace(rule, substitution);
84958
84959      return result;
84960    }
84961  };
84962
84963  exports['default'] = Inflector;
84964});
84965define('ember-inflector/lib/system/string', ['exports', 'ember-inflector/lib/system/inflector'], function (exports, _emberInflectorLibSystemInflector) {
84966  'use strict';
84967
84968  function pluralize(word) {
84969    return _emberInflectorLibSystemInflector['default'].inflector.pluralize(word);
84970  }
84971
84972  function singularize(word) {
84973    return _emberInflectorLibSystemInflector['default'].inflector.singularize(word);
84974  }
84975
84976  exports.pluralize = pluralize;
84977  exports.singularize = singularize;
84978});
84979define('ember-inflector/lib/utils/make-helper', ['exports', 'ember'], function (exports, _ember) {
84980  'use strict';
84981
84982  exports['default'] = makeHelper;
84983
84984  function makeHelper(helperFunction) {
84985    if (_ember['default'].Helper) {
84986      return _ember['default'].Helper.helper(helperFunction);
84987    }
84988    if (_ember['default'].HTMLBars) {
84989      return _ember['default'].HTMLBars.makeBoundHelper(helperFunction);
84990    }
84991    return _ember['default'].Handlebars.makeBoundHelper(helperFunction);
84992  }
84993});
84994define('ember-load-initializers/index', ['exports', 'ember'], function (exports, _ember) {
84995  'use strict';
84996
84997  exports['default'] = function (app, prefix) {
84998    var regex = new RegExp('^' + prefix + '\/((?:instance-)?initializers)\/');
84999    var getKeys = Object.keys || _ember['default'].keys;
85000
85001    getKeys(requirejs._eak_seen).map(function (moduleName) {
85002      return {
85003        moduleName: moduleName,
85004        matches: regex.exec(moduleName)
85005      };
85006    }).filter(function (dep) {
85007      return dep.matches && dep.matches.length === 2;
85008    }).forEach(function (dep) {
85009      var moduleName = dep.moduleName;
85010
85011      var module = require(moduleName, null, null, true);
85012      if (!module) {
85013        throw new Error(moduleName + ' must export an initializer.');
85014      }
85015
85016      var initializerType = _ember['default'].String.camelize(dep.matches[1].substring(0, dep.matches[1].length - 1));
85017      var initializer = module['default'];
85018      if (!initializer.name) {
85019        var initializerName = moduleName.match(/[^\/]+\/?$/)[0];
85020        initializer.name = initializerName;
85021      }
85022
85023      if (app[initializerType]) {
85024        app[initializerType](initializer);
85025      }
85026    });
85027  };
85028});
85029define('ember-resolver/container-debug-adapter', ['exports', 'ember', 'ember-resolver/utils/module-registry'], function (exports, _ember, _emberResolverUtilsModuleRegistry) {
85030  'use strict';
85031
85032  var ContainerDebugAdapter = _ember['default'].ContainerDebugAdapter;
85033
85034  var ModulesContainerDebugAdapter = null;
85035
85036  function getPod(type, key, prefix) {
85037    var match = key.match(new RegExp('^/?' + prefix + '/(.+)/' + type + '$'));
85038    if (match) {
85039      return match[1];
85040    }
85041  }
85042
85043  // Support Ember < 1.5-beta.4
85044  // TODO: Remove this after 1.5.0 is released
85045  if (typeof ContainerDebugAdapter !== 'undefined') {
85046
85047    /*
85048     * This module defines a subclass of Ember.ContainerDebugAdapter that adds two
85049     * important features:
85050     *
85051     *  1) is able provide injections to classes that implement `extend`
85052     *     (as is typical with Ember).
85053     */
85054
85055    ModulesContainerDebugAdapter = ContainerDebugAdapter.extend({
85056      _moduleRegistry: null,
85057
85058      init: function init() {
85059        this._super.apply(this, arguments);
85060
85061        if (!this._moduleRegistry) {
85062          this._moduleRegistry = new _emberResolverUtilsModuleRegistry['default']();
85063        }
85064      },
85065
85066      /**
85067        The container of the application being debugged.
85068        This property will be injected
85069        on creation.
85070         @property container
85071        @default null
85072      */
85073
85074      /**
85075        The resolver instance of the application
85076        being debugged. This property will be injected
85077        on creation.
85078         @property resolver
85079        @default null
85080      */
85081
85082      /**
85083        Returns true if it is possible to catalog a list of available
85084        classes in the resolver for a given type.
85085         @method canCatalogEntriesByType
85086        @param {string} type The type. e.g. "model", "controller", "route"
85087        @return {boolean} whether a list is available for this type.
85088      */
85089      canCatalogEntriesByType: function canCatalogEntriesByType() /* type */{
85090        return true;
85091      },
85092
85093      /**
85094        Returns the available classes a given type.
85095         @method catalogEntriesByType
85096        @param {string} type The type. e.g. "model", "controller", "route"
85097        @return {Array} An array of classes.
85098      */
85099      catalogEntriesByType: function catalogEntriesByType(type) {
85100        var moduleNames = this._moduleRegistry.moduleNames();
85101        var types = _ember['default'].A();
85102
85103        var prefix = this.namespace.modulePrefix;
85104
85105        for (var i = 0, l = moduleNames.length; i < l; i++) {
85106          var key = moduleNames[i];
85107
85108          if (key.indexOf(type) !== -1) {
85109            // Check if it's a pod module
85110            var name = getPod(type, key, this.namespace.podModulePrefix || prefix);
85111            if (!name) {
85112              // Not pod
85113              name = key.split(type + 's/').pop();
85114
85115              // Support for different prefix (such as ember-cli addons).
85116              // Uncomment the code below when
85117              // https://github.com/ember-cli/ember-resolver/pull/80 is merged.
85118
85119              //var match = key.match('^/?(.+)/' + type);
85120              //if (match && match[1] !== prefix) {
85121              // Different prefix such as an addon
85122              //name = match[1] + '@' + name;
85123              //}
85124            }
85125            types.addObject(name);
85126          }
85127        }
85128        return types;
85129      }
85130    });
85131  }
85132
85133  exports['default'] = ModulesContainerDebugAdapter;
85134});
85135define('ember-resolver/index', ['exports', 'ember-resolver/resolver'], function (exports, _emberResolverResolver) {
85136  'use strict';
85137
85138  Object.defineProperty(exports, 'default', {
85139    enumerable: true,
85140    get: function get() {
85141      return _emberResolverResolver['default'];
85142    }
85143  });
85144});
85145define('ember-resolver/resolver', ['exports', 'ember', 'ember-resolver/utils/module-registry', 'ember-resolver/utils/class-factory', 'ember-resolver/utils/make-dictionary'], function (exports, _ember, _emberResolverUtilsModuleRegistry, _emberResolverUtilsClassFactory, _emberResolverUtilsMakeDictionary) {
85146  /*globals require */
85147
85148  'use strict';
85149
85150  /*
85151   * This module defines a subclass of Ember.DefaultResolver that adds two
85152   * important features:
85153   *
85154   *  1) The resolver makes the container aware of es6 modules via the AMD
85155   *     output. The loader's _moduleEntries is consulted so that classes can be
85156   *     resolved directly via the module loader, without needing a manual
85157   *     `import`.
85158   *  2) is able to provide injections to classes that implement `extend`
85159   *     (as is typical with Ember).
85160   */
85161
85162  var _Ember$String = _ember['default'].String;
85163  var underscore = _Ember$String.underscore;
85164  var classify = _Ember$String.classify;
85165  var get = _ember['default'].get;
85166  var DefaultResolver = _ember['default'].DefaultResolver;
85167
85168  function parseName(fullName) {
85169    /*jshint validthis:true */
85170
85171    if (fullName.parsedName === true) {
85172      return fullName;
85173    }
85174
85175    var prefix, type, name;
85176    var fullNameParts = fullName.split('@');
85177
85178    // HTMLBars uses helper:@content-helper which collides
85179    // with ember-cli namespace detection.
85180    // This will be removed in a future release of HTMLBars.
85181    if (fullName !== 'helper:@content-helper' && fullNameParts.length === 2) {
85182      var prefixParts = fullNameParts[0].split(':');
85183
85184      if (prefixParts.length === 2) {
85185        prefix = prefixParts[1];
85186        type = prefixParts[0];
85187        name = fullNameParts[1];
85188      } else {
85189        var nameParts = fullNameParts[1].split(':');
85190
85191        prefix = fullNameParts[0];
85192        type = nameParts[0];
85193        name = nameParts[1];
85194      }
85195    } else {
85196      fullNameParts = fullName.split(':');
85197      type = fullNameParts[0];
85198      name = fullNameParts[1];
85199    }
85200
85201    var fullNameWithoutType = name;
85202    var namespace = get(this, 'namespace');
85203    var root = namespace;
85204
85205    return {
85206      parsedName: true,
85207      fullName: fullName,
85208      prefix: prefix || this.prefix({ type: type }),
85209      type: type,
85210      fullNameWithoutType: fullNameWithoutType,
85211      name: name,
85212      root: root,
85213      resolveMethodName: "resolve" + classify(type)
85214    };
85215  }
85216
85217  function resolveOther(parsedName) {
85218    /*jshint validthis:true */
85219
85220    _ember['default'].assert('`modulePrefix` must be defined', this.namespace.modulePrefix);
85221
85222    var normalizedModuleName = this.findModuleName(parsedName);
85223
85224    if (normalizedModuleName) {
85225      var defaultExport = this._extractDefaultExport(normalizedModuleName, parsedName);
85226
85227      if (defaultExport === undefined) {
85228        throw new Error(" Expected to find: '" + parsedName.fullName + "' within '" + normalizedModuleName + "' but got 'undefined'. Did you forget to `export default` within '" + normalizedModuleName + "'?");
85229      }
85230
85231      if (this.shouldWrapInClassFactory(defaultExport, parsedName)) {
85232        defaultExport = (0, _emberResolverUtilsClassFactory['default'])(defaultExport);
85233      }
85234
85235      return defaultExport;
85236    } else {
85237      return this._super(parsedName);
85238    }
85239  }
85240
85241  // Ember.DefaultResolver docs:
85242  //   https://github.com/emberjs/ember.js/blob/master/packages/ember-application/lib/system/resolver.js
85243  var Resolver = DefaultResolver.extend({
85244    resolveOther: resolveOther,
85245    parseName: parseName,
85246    resolveTemplate: resolveOther,
85247    pluralizedTypes: null,
85248    moduleRegistry: null,
85249
85250    makeToString: function makeToString(factory, fullName) {
85251      return '' + this.namespace.modulePrefix + '@' + fullName + ':';
85252    },
85253
85254    shouldWrapInClassFactory: function shouldWrapInClassFactory() /* module, parsedName */{
85255      return false;
85256    },
85257
85258    init: function init() {
85259      this._super();
85260      this.moduleBasedResolver = true;
85261
85262      if (!this._moduleRegistry) {
85263        this._moduleRegistry = new _emberResolverUtilsModuleRegistry['default']();
85264      }
85265
85266      this._normalizeCache = (0, _emberResolverUtilsMakeDictionary['default'])();
85267
85268      this.pluralizedTypes = this.pluralizedTypes || (0, _emberResolverUtilsMakeDictionary['default'])();
85269
85270      if (!this.pluralizedTypes.config) {
85271        this.pluralizedTypes.config = 'config';
85272      }
85273
85274      this._deprecatedPodModulePrefix = false;
85275    },
85276
85277    normalize: function normalize(fullName) {
85278      return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this._normalize(fullName));
85279    },
85280
85281    _normalize: function _normalize(fullName) {
85282      // replace `.` with `/` in order to make nested controllers work in the following cases
85283      // 1. `needs: ['posts/post']`
85284      // 2. `{{render "posts/post"}}`
85285      // 3. `this.render('posts/post')` from Route
85286      var split = fullName.split(':');
85287      if (split.length > 1) {
85288        return split[0] + ':' + _ember['default'].String.dasherize(split[1].replace(/\./g, '/'));
85289      } else {
85290        return fullName;
85291      }
85292    },
85293
85294    pluralize: function pluralize(type) {
85295      return this.pluralizedTypes[type] || (this.pluralizedTypes[type] = type + 's');
85296    },
85297
85298    podBasedLookupWithPrefix: function podBasedLookupWithPrefix(podPrefix, parsedName) {
85299      var fullNameWithoutType = parsedName.fullNameWithoutType;
85300
85301      if (parsedName.type === 'template') {
85302        fullNameWithoutType = fullNameWithoutType.replace(/^components\//, '');
85303      }
85304
85305      return podPrefix + '/' + fullNameWithoutType + '/' + parsedName.type;
85306    },
85307
85308    podBasedModuleName: function podBasedModuleName(parsedName) {
85309      var podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix;
85310
85311      return this.podBasedLookupWithPrefix(podPrefix, parsedName);
85312    },
85313
85314    podBasedComponentsInSubdir: function podBasedComponentsInSubdir(parsedName) {
85315      var podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix;
85316      podPrefix = podPrefix + '/components';
85317
85318      if (parsedName.type === 'component' || parsedName.fullNameWithoutType.match(/^components/)) {
85319        return this.podBasedLookupWithPrefix(podPrefix, parsedName);
85320      }
85321    },
85322
85323    mainModuleName: function mainModuleName(parsedName) {
85324      // if router:main or adapter:main look for a module with just the type first
85325      var tmpModuleName = parsedName.prefix + '/' + parsedName.type;
85326
85327      if (parsedName.fullNameWithoutType === 'main') {
85328        return tmpModuleName;
85329      }
85330    },
85331
85332    defaultModuleName: function defaultModuleName(parsedName) {
85333      return parsedName.prefix + '/' + this.pluralize(parsedName.type) + '/' + parsedName.fullNameWithoutType;
85334    },
85335
85336    prefix: function prefix(parsedName) {
85337      var tmpPrefix = this.namespace.modulePrefix;
85338
85339      if (this.namespace[parsedName.type + 'Prefix']) {
85340        tmpPrefix = this.namespace[parsedName.type + 'Prefix'];
85341      }
85342
85343      return tmpPrefix;
85344    },
85345
85346    /**
85347      A listing of functions to test for moduleName's based on the provided
85348     `parsedName`. This allows easy customization of additional module based
85349     lookup patterns.
85350      @property moduleNameLookupPatterns
85351     @returns {Ember.Array}
85352     */
85353    moduleNameLookupPatterns: _ember['default'].computed(function () {
85354      return [this.podBasedModuleName, this.podBasedComponentsInSubdir, this.mainModuleName, this.defaultModuleName];
85355    }),
85356
85357    findModuleName: function findModuleName(parsedName, loggingDisabled) {
85358      var moduleNameLookupPatterns = this.get('moduleNameLookupPatterns');
85359      var moduleName;
85360
85361      for (var index = 0, _length = moduleNameLookupPatterns.length; index < _length; index++) {
85362        var item = moduleNameLookupPatterns[index];
85363
85364        var tmpModuleName = item.call(this, parsedName);
85365
85366        // allow treat all dashed and all underscored as the same thing
85367        // supports components with dashes and other stuff with underscores.
85368        if (tmpModuleName) {
85369          tmpModuleName = this.chooseModuleName(tmpModuleName);
85370        }
85371
85372        if (tmpModuleName && this._moduleRegistry.has(tmpModuleName)) {
85373          moduleName = tmpModuleName;
85374        }
85375
85376        if (!loggingDisabled) {
85377          this._logLookup(moduleName, parsedName, tmpModuleName);
85378        }
85379
85380        if (moduleName) {
85381          return moduleName;
85382        }
85383      }
85384    },
85385
85386    chooseModuleName: function chooseModuleName(moduleName) {
85387      var underscoredModuleName = underscore(moduleName);
85388
85389      if (moduleName !== underscoredModuleName && this._moduleRegistry.has(moduleName) && this._moduleRegistry.has(underscoredModuleName)) {
85390        throw new TypeError("Ambiguous module names: `" + moduleName + "` and `" + underscoredModuleName + "`");
85391      }
85392
85393      if (this._moduleRegistry.has(moduleName)) {
85394        return moduleName;
85395      } else if (this._moduleRegistry.has(underscoredModuleName)) {
85396        return underscoredModuleName;
85397      } else {
85398        // workaround for dasherized partials:
85399        // something/something/-something => something/something/_something
85400        var partializedModuleName = moduleName.replace(/\/-([^\/]*)$/, '/_$1');
85401
85402        if (this._moduleRegistry.has(partializedModuleName)) {
85403          _ember['default'].deprecate('Modules should not contain underscores. ' + 'Attempted to lookup "' + moduleName + '" which ' + 'was not found. Please rename "' + partializedModuleName + '" ' + 'to "' + moduleName + '" instead.', false);
85404
85405          return partializedModuleName;
85406        } else {
85407          return moduleName;
85408        }
85409      }
85410    },
85411
85412    // used by Ember.DefaultResolver.prototype._logLookup
85413    lookupDescription: function lookupDescription(fullName) {
85414      var parsedName = this.parseName(fullName);
85415
85416      var moduleName = this.findModuleName(parsedName, true);
85417
85418      return moduleName;
85419    },
85420
85421    // only needed until 1.6.0-beta.2 can be required
85422    _logLookup: function _logLookup(found, parsedName, description) {
85423      if (!_ember['default'].ENV.LOG_MODULE_RESOLVER && !parsedName.root.LOG_RESOLVER) {
85424        return;
85425      }
85426
85427      var symbol, padding;
85428
85429      if (found) {
85430        symbol = '[✓]';
85431      } else {
85432        symbol = '[ ]';
85433      }
85434
85435      if (parsedName.fullName.length > 60) {
85436        padding = '.';
85437      } else {
85438        padding = new Array(60 - parsedName.fullName.length).join('.');
85439      }
85440
85441      if (!description) {
85442        description = this.lookupDescription(parsedName);
85443      }
85444
85445      _ember['default'].Logger.info(symbol, parsedName.fullName, padding, description);
85446    },
85447
85448    knownForType: function knownForType(type) {
85449      var moduleKeys = this._moduleRegistry.moduleNames();
85450
85451      var items = (0, _emberResolverUtilsMakeDictionary['default'])();
85452      for (var index = 0, length = moduleKeys.length; index < length; index++) {
85453        var moduleName = moduleKeys[index];
85454        var fullname = this.translateToContainerFullname(type, moduleName);
85455
85456        if (fullname) {
85457          items[fullname] = true;
85458        }
85459      }
85460
85461      return items;
85462    },
85463
85464    translateToContainerFullname: function translateToContainerFullname(type, moduleName) {
85465      var prefix = this.prefix({ type: type });
85466
85467      // Note: using string manipulation here rather than regexes for better performance.
85468      // pod modules
85469      // '^' + prefix + '/(.+)/' + type + '$'
85470      var podPrefix = prefix + '/';
85471      var podSuffix = '/' + type;
85472      var start = moduleName.indexOf(podPrefix);
85473      var end = moduleName.indexOf(podSuffix);
85474
85475      if (start === 0 && end === moduleName.length - podSuffix.length && moduleName.length > podPrefix.length + podSuffix.length) {
85476        return type + ':' + moduleName.slice(start + podPrefix.length, end);
85477      }
85478
85479      // non-pod modules
85480      // '^' + prefix + '/' + pluralizedType + '/(.+)$'
85481      var pluralizedType = this.pluralize(type);
85482      var nonPodPrefix = prefix + '/' + pluralizedType + '/';
85483
85484      if (moduleName.indexOf(nonPodPrefix) === 0 && moduleName.length > nonPodPrefix.length) {
85485        return type + ':' + moduleName.slice(nonPodPrefix.length);
85486      }
85487    },
85488
85489    _extractDefaultExport: function _extractDefaultExport(normalizedModuleName) {
85490      var module = require(normalizedModuleName, null, null, true /* force sync */);
85491
85492      if (module && module['default']) {
85493        module = module['default'];
85494      }
85495
85496      return module;
85497    }
85498  });
85499
85500  Resolver.reopenClass({
85501    moduleBasedResolver: true
85502  });
85503
85504  exports['default'] = Resolver;
85505});
85506define('ember-resolver/utils/class-factory', ['exports'], function (exports) {
85507  'use strict';
85508
85509  exports['default'] = classFactory;
85510
85511  function classFactory(klass) {
85512    return {
85513      create: function create(injections) {
85514        if (typeof klass.extend === 'function') {
85515          return klass.extend(injections);
85516        } else {
85517          return klass;
85518        }
85519      }
85520    };
85521  }
85522});
85523define("ember-resolver/utils/create", ["exports", "ember"], function (exports, _ember) {
85524  "use strict";
85525
85526  var create = Object.create || _ember["default"].create;
85527  if (!(create && !create(null).hasOwnProperty)) {
85528    throw new Error("This browser does not support Object.create(null), please polyfil with es5-sham: http://git.io/yBU2rg");
85529  }
85530
85531  exports["default"] = create;
85532});
85533define('ember-resolver/utils/make-dictionary', ['exports', 'ember-resolver/utils/create'], function (exports, _emberResolverUtilsCreate) {
85534  'use strict';
85535
85536  exports['default'] = makeDictionary;
85537
85538  function makeDictionary() {
85539    var cache = (0, _emberResolverUtilsCreate['default'])(null);
85540    cache['_dict'] = null;
85541    delete cache['_dict'];
85542    return cache;
85543  }
85544});
85545define('ember-resolver/utils/module-registry', ['exports', 'ember'], function (exports, _ember) {
85546  /*globals requirejs, require */
85547
85548  'use strict';
85549
85550  if (typeof requirejs.entries === 'undefined') {
85551    requirejs.entries = requirejs._eak_seen;
85552  }
85553
85554  function ModuleRegistry(entries) {
85555    this._entries = entries || requirejs.entries;
85556  }
85557
85558  ModuleRegistry.prototype.moduleNames = function ModuleRegistry_moduleNames() {
85559    return (Object.keys || _ember['default'].keys)(this._entries);
85560  };
85561
85562  ModuleRegistry.prototype.has = function ModuleRegistry_has(moduleName) {
85563    return moduleName in this._entries;
85564  };
85565
85566  ModuleRegistry.prototype.get = function ModuleRegistry_get(moduleName) {
85567    var exportName = arguments.length <= 1 || arguments[1] === undefined ? 'default' : arguments[1];
85568
85569    var module = require(moduleName);
85570    return module && module[exportName];
85571  };
85572
85573  exports['default'] = ModuleRegistry;
85574});
85575define('ember-youtube/components/ember-youtube', ['exports', 'ember'], function (exports, _ember) {
85576	/* global YT, window */
85577	'use strict';
85578
85579	var computed = _ember['default'].computed;
85580	var debug = _ember['default'].debug;
85581	var observer = _ember['default'].observer;
85582	var on = _ember['default'].on;
85583	var run = _ember['default'].run;
85584	var RSVP = _ember['default'].RSVP;
85585	var $ = _ember['default'].$;
85586
85587	exports['default'] = _ember['default'].Component.extend({
85588		classNames: ['EmberYoutube'],
85589		ytid: null,
85590		player: null,
85591		playerState: 'loading',
85592		showDebug: false,
85593		showControls: false,
85594		showProgress: false,
85595		lazyload: false,
85596		showExtras: computed.or('showControls', 'showProgress', 'showDebug'),
85597
85598		// YouTube's embedded player can take a number of optional parameters.
85599		// https://developers.google.com/youtube/player_parameters#Parameters
85600		// https://developers.google.com/youtube/youtube_player_demo
85601		playerVars: {},
85602
85603		startSeconds: undefined,
85604		endSeconds: undefined,
85605		suggestedQuality: undefined,
85606		height: 360,
85607		width: 270,
85608
85609		// from YT.PlayerState
85610		stateNames: {
85611			'-1': 'ready', // READY
85612			0: 'ended', // YT.Player.ENDED
85613			1: 'playing', // YT.PlayerState.PLAYING
85614			2: 'paused', // YT.PlayerState.PAUSED
85615			3: 'buffering', // YT.PlayerState.BUFFERING
85616			5: 'queued' // YT.PlayerState.CUED
85617		},
85618
85619		// Expose the component to the outside world.
85620		_register: on('init', function () {
85621			var _this = this;
85622
85623			var delegate = this.get('delegate');
85624			var delegateAs = this.get('delegate-as');
85625			run.schedule('afterRender', function () {
85626				if (!delegate) {
85627					return;
85628				}
85629				delegate.set(delegateAs || 'emberYoutubePlayer', _this);
85630			});
85631		}),
85632
85633		didInsertElement: function didInsertElement() {
85634			this._super.apply(this, arguments);
85635			if (this.get('lazyload') && !this.get('ytid')) {
85636				// If "lazyload" is enabled and we don't have an ID,
85637				// we can defer loading and creating the player. As soon as an `ytid` is available it'll run the `loadVideo` observer.
85638				return;
85639			}
85640			this.loadAndCreatePlayer();
85641		},
85642
85643		loadAndCreatePlayer: function loadAndCreatePlayer() {
85644			var _this2 = this;
85645
85646			var promise = new RSVP.Promise(function (resolve, reject) {
85647				_this2.loadYouTubeApi().then(function () {
85648					_this2.createPlayer().then(function (player) {
85649						if (!player) {
85650							reject();
85651						}
85652						_this2.setProperties({
85653							player: player,
85654							playerState: 'ready'
85655						});
85656						_this2.loadVideo();
85657						resolve();
85658					});
85659				});
85660			});
85661			// The `wait` helper waits for this run loop,
85662			// but not the above promise, which is what i want.
85663			if (_ember['default'].testing) {
85664				run.later(function () {}, 5000);
85665			}
85666			return promise;
85667		},
85668
85669		// A promise that is resolved when window.onYouTubeIframeAPIReady is called.
85670		// The promise is resolved with a reference to window.YT object.
85671		loadYouTubeApi: function loadYouTubeApi() {
85672			return new RSVP.Promise(function (resolve) {
85673				var previous = undefined;
85674				previous = window.onYouTubeIframeAPIReady;
85675
85676				// The API will call this function when page has finished downloading
85677				// the JavaScript for the player API.
85678				window.onYouTubeIframeAPIReady = function () {
85679					if (previous) {
85680						previous();
85681					}
85682					resolve(window.YT);
85683				};
85684
85685				if (window.YT && window.YT.loaded) {
85686					// If already loaded, make sure not to load the script again.
85687					resolve(window.YT);
85688				} else {
85689					$.getScript('https://www.youtube.com/iframe_api');
85690				}
85691			});
85692		},
85693
85694		// A promise that is immediately resolved with a YouTube player object.
85695		createPlayer: function createPlayer() {
85696			var _this3 = this;
85697
85698			var playerVars = this.get('playerVars');
85699			var width = this.get('width');
85700			var height = this.get('height');
85701			// const iframe = this.element.querySelector('#EmberYoutube-player');
85702			var iframe = this.$('#EmberYoutube-player');
85703			var player = undefined;
85704			return new RSVP.Promise(function (resolve) {
85705				if (!iframe) {
85706					// reject(`Couldn't find the iframe element to create a YouTube player`);
85707					resolve(false);
85708				}
85709				player = new YT.Player(iframe.get(0), {
85710					width: width,
85711					height: height,
85712					playerVars: playerVars,
85713					events: {
85714						onReady: function onReady() {
85715							resolve(player);
85716						},
85717						onStateChange: _this3.onPlayerStateChange.bind(_this3),
85718						onError: _this3.onPlayerError.bind(_this3)
85719					}
85720				});
85721			});
85722		},
85723
85724		// Gets called by the YouTube player.
85725		onPlayerStateChange: function onPlayerStateChange(event) {
85726			// Set a readable state name
85727			var state = this.get('stateNames.' + event.data.toString());
85728			this.set('playerState', state);
85729			if (this.get('showDebug')) {
85730				debug(state);
85731			}
85732			// send actions outside
85733			this.sendAction(state);
85734			// send actions inside
85735			this.send(state);
85736		},
85737
85738		// Gets called by the YouTube player.
85739		onPlayerError: function onPlayerError(event) {
85740			var errorCode = event.data;
85741			this.set('playerState', 'error');
85742			debug('error' + errorCode);
85743			// Send the event to the controller
85744			this.sendAction('error', errorCode);
85745			// switch(errorCode) {
85746			// 	case 2:
85747			// 		debug('Invalid parameter');
85748			// 		break;
85749			// 	case 100:
85750			// 		debug('Not found/private');
85751			// 		this.send('playNext');
85752			// 		break;
85753			// 	case 101:
85754			// 	case 150:
85755			// 		debug('Embed not allowed');
85756			// 		this.send('playNext');
85757			// 		break;
85758			// 	default:
85759			// 		break;
85760			// }
85761		},
85762
85763		// Returns a boolean that indicates playback status
85764		// by looking at the player state.
85765		isPlaying: computed('playerState', {
85766			get: function get() {
85767				var player = this.get('player');
85768				if (!player || this.get('playerState') === 'loading') {
85769					return false;
85770				}
85771				return player.getPlayerState() === 1;
85772			},
85773			set: function set(name, paused) {
85774				var player = this.get('player');
85775				// Stop without player or when loading.
85776				if (!player || this.get('playerState') === 'loading') {
85777					return;
85778				}
85779				if (paused) {
85780					this.send('play');
85781				} else {
85782					this.send('pause');
85783				}
85784			}
85785		}),
85786
85787		// Load (and plays) a video every time ytid changes.
85788		loadVideo: observer('ytid', function () {
85789			var _this4 = this;
85790
85791			var player = this.get('player');
85792			var videoId = this.get('ytid');
85793			var startSeconds = this.get('startSeconds');
85794			var endSeconds = this.get('endSeconds');
85795			var suggestedQuality = this.get('suggestedQuality');
85796			// Make sure we have access to the functions we need otherwise the player might die.
85797			if (!videoId || !player || !player.loadVideoById || !player.cueVideoById) {
85798				this.loadAndCreatePlayer().then(function () {
85799					_this4.loadVideo();
85800				});
85801				return;
85802			}
85803			// Set parameters for the video to be played.
85804			var options = {
85805				videoId: videoId,
85806				startSeconds: startSeconds,
85807				endSeconds: endSeconds,
85808				suggestedQuality: suggestedQuality
85809			};
85810			// Check mute status and set it.
85811			this.set('isMuted', player.isMuted());
85812			// Either load or cue depending on `autoplay`.
85813			if (this.playerVars.autoplay) {
85814				player.loadVideoById(options);
85815			} else {
85816				player.cueVideoById(options);
85817			}
85818		}),
85819
85820		volume: computed({
85821			get: function get() {
85822				return this.get('player').getVolume();
85823			},
85824			set: function set(name, volume) {
85825				var player = this.get('player');
85826				// Clamp between 0 and 100
85827				if (volume > 100) {
85828					volume = 100;
85829				} else if (volume < 0) {
85830					volume = 0;
85831				}
85832				if (player) {
85833					player.setVolume(volume);
85834				}
85835			}
85836		}),
85837
85838		startTimer: function startTimer() {
85839			var player = this.get('player');
85840			var interval = 1000;
85841			// set initial times
85842			this.setProperties({
85843				currentTime: player.getCurrentTime(),
85844				duration: player.getDuration()
85845			});
85846			// stop any previously started timer we forgot to clear
85847			this.stopTimer();
85848			// every second update current time
85849			var timer = window.setInterval((function () {
85850				this.set('currentTime', player.getCurrentTime());
85851			}).bind(this), interval);
85852			// save the timer so we can stop it later
85853			this.set('timer', timer);
85854		},
85855
85856		stopTimer: function stopTimer() {
85857			window.clearInterval(this.get('timer'));
85858		},
85859
85860		// avoids 'undefined' value for the <progress> element.
85861		currentTimeValue: computed('currentTime', function () {
85862			var time = this.get('currentTime');
85863			return time ? time : 0;
85864		}),
85865
85866		// avoids 'undefined' value for the <progress> element.
85867		durationValue: computed('duration', function () {
85868			var duration = this.get('duration');
85869			return duration ? duration : 0;
85870		}),
85871
85872		// OK, this is stupid but couldn't access the "event" inside
85873		// an ember action so here's a manual click handler instead.
85874		progressBarClick: on('didInsertElement', function () {
85875			var self = this;
85876			this.$().on('click', 'progress', function (event) {
85877				// get the x position of the click inside our progress el
85878				var x = event.pageX - _ember['default'].$(this).position().left;
85879				// convert it to a value relative to the duration (max)
85880				var clickedValue = x * this.max / this.offsetWidth;
85881				// 250 = 0.25 seconds into player
85882				self.send('seekTo', clickedValue);
85883			});
85884		}),
85885
85886		// clean up when element will be destroyed.
85887		willDestroyElement: function willDestroyElement() {
85888			// clear the timer
85889			this.stopTimer();
85890			// destroy video player
85891			var player = this.get('player');
85892			if (player) {
85893				player.destroy();
85894				this.set('player', null);
85895			}
85896		},
85897
85898		actions: {
85899			play: function play() {
85900				if (this.get('player')) {
85901					this.get('player').playVideo();
85902				}
85903			},
85904			pause: function pause() {
85905				if (this.get('player')) {
85906					this.get('player').pauseVideo();
85907				}
85908			},
85909			togglePlay: function togglePlay() {
85910				this.toggleProperty('isPlaying');
85911			},
85912			mute: function mute() {
85913				if (this.get('player')) {
85914					this.get('player').mute();
85915					this.set('isMuted', true);
85916				}
85917			},
85918			unMute: function unMute() {
85919				if (this.get('player')) {
85920					this.get('player').unMute();
85921					this.set('isMuted', false);
85922				}
85923			},
85924			toggleVolume: function toggleVolume() {
85925				if (this.get('player').isMuted()) {
85926					this.send('unMute');
85927				} else {
85928					this.send('mute');
85929				}
85930			},
85931			seekTo: function seekTo(seconds) {
85932				if (this.get('player')) {
85933					this.get('player').seekTo(seconds);
85934				}
85935			},
85936			// youtube events
85937			ready: function ready() {},
85938			ended: function ended() {},
85939			playing: function playing() {
85940				this.startTimer();
85941			},
85942			paused: function paused() {
85943				this.stopTimer();
85944			},
85945			buffering: function buffering() {},
85946			queued: function queued() {}
85947		}
85948	});
85949});
85950;/* jshint ignore:start */
85951
85952
85953
85954/* jshint ignore:end */
85955//# sourceMappingURL=vendor.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.