f7442c0b031cc8afab578e779f9adda096d7eb47
[WebKit-https.git] / PerformanceTests / Speedometer / resources / todomvc / architecture-examples / angularjs / node_modules / angular / angular.js
1 /**
2  * @license AngularJS v1.4.3
3  * (c) 2010-2015 Google, Inc. http://angularjs.org
4  * License: MIT
5  */
6 (function(window, document, undefined) {'use strict';
7
8 /**
9  * @description
10  *
11  * This object provides a utility for producing rich Error messages within
12  * Angular. It can be called as follows:
13  *
14  * var exampleMinErr = minErr('example');
15  * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
16  *
17  * The above creates an instance of minErr in the example namespace. The
18  * resulting error will have a namespaced error code of example.one.  The
19  * resulting error will replace {0} with the value of foo, and {1} with the
20  * value of bar. The object is not restricted in the number of arguments it can
21  * take.
22  *
23  * If fewer arguments are specified than necessary for interpolation, the extra
24  * interpolation markers will be preserved in the final string.
25  *
26  * Since data will be parsed statically during a build step, some restrictions
27  * are applied with respect to how minErr instances are created and called.
28  * Instances should have names of the form namespaceMinErr for a minErr created
29  * using minErr('namespace') . Error codes, namespaces and template strings
30  * should all be static strings, not variables or general expressions.
31  *
32  * @param {string} module The namespace to use for the new minErr instance.
33  * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
34  *   error from returned function, for cases when a particular type of error is useful.
35  * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
36  */
37
38 function minErr(module, ErrorConstructor) {
39   ErrorConstructor = ErrorConstructor || Error;
40   return function() {
41     var SKIP_INDEXES = 2;
42
43     var templateArgs = arguments,
44       code = templateArgs[0],
45       message = '[' + (module ? module + ':' : '') + code + '] ',
46       template = templateArgs[1],
47       paramPrefix, i;
48
49     message += template.replace(/\{\d+\}/g, function(match) {
50       var index = +match.slice(1, -1),
51         shiftedIndex = index + SKIP_INDEXES;
52
53       if (shiftedIndex < templateArgs.length) {
54         return toDebugString(templateArgs[shiftedIndex]);
55       }
56
57       return match;
58     });
59
60     message += '\nhttp://errors.angularjs.org/1.4.3/' +
61       (module ? module + '/' : '') + code;
62
63     for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
64       message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' +
65         encodeURIComponent(toDebugString(templateArgs[i]));
66     }
67
68     return new ErrorConstructor(message);
69   };
70 }
71
72 /* We need to tell jshint what variables are being exported */
73 /* global angular: true,
74   msie: true,
75   jqLite: true,
76   jQuery: true,
77   slice: true,
78   splice: true,
79   push: true,
80   toString: true,
81   ngMinErr: true,
82   angularModule: true,
83   uid: true,
84   REGEX_STRING_REGEXP: true,
85   VALIDITY_STATE_PROPERTY: true,
86
87   lowercase: true,
88   uppercase: true,
89   manualLowercase: true,
90   manualUppercase: true,
91   nodeName_: true,
92   isArrayLike: true,
93   forEach: true,
94   forEachSorted: true,
95   reverseParams: true,
96   nextUid: true,
97   setHashKey: true,
98   extend: true,
99   toInt: true,
100   inherit: true,
101   merge: true,
102   noop: true,
103   identity: true,
104   valueFn: true,
105   isUndefined: true,
106   isDefined: true,
107   isObject: true,
108   isBlankObject: true,
109   isString: true,
110   isNumber: true,
111   isDate: true,
112   isArray: true,
113   isFunction: true,
114   isRegExp: true,
115   isWindow: true,
116   isScope: true,
117   isFile: true,
118   isFormData: true,
119   isBlob: true,
120   isBoolean: true,
121   isPromiseLike: true,
122   trim: true,
123   escapeForRegexp: true,
124   isElement: true,
125   makeMap: true,
126   includes: true,
127   arrayRemove: true,
128   copy: true,
129   shallowCopy: true,
130   equals: true,
131   csp: true,
132   jq: true,
133   concat: true,
134   sliceArgs: true,
135   bind: true,
136   toJsonReplacer: true,
137   toJson: true,
138   fromJson: true,
139   convertTimezoneToLocal: true,
140   timezoneToOffset: true,
141   startingTag: true,
142   tryDecodeURIComponent: true,
143   parseKeyValue: true,
144   toKeyValue: true,
145   encodeUriSegment: true,
146   encodeUriQuery: true,
147   angularInit: true,
148   bootstrap: true,
149   getTestability: true,
150   snake_case: true,
151   bindJQuery: true,
152   assertArg: true,
153   assertArgFn: true,
154   assertNotHasOwnProperty: true,
155   getter: true,
156   getBlockNodes: true,
157   hasOwnProperty: true,
158   createMap: true,
159
160   NODE_TYPE_ELEMENT: true,
161   NODE_TYPE_ATTRIBUTE: true,
162   NODE_TYPE_TEXT: true,
163   NODE_TYPE_COMMENT: true,
164   NODE_TYPE_DOCUMENT: true,
165   NODE_TYPE_DOCUMENT_FRAGMENT: true,
166 */
167
168 ////////////////////////////////////
169
170 /**
171  * @ngdoc module
172  * @name ng
173  * @module ng
174  * @description
175  *
176  * # ng (core module)
177  * The ng module is loaded by default when an AngularJS application is started. The module itself
178  * contains the essential components for an AngularJS application to function. The table below
179  * lists a high level breakdown of each of the services/factories, filters, directives and testing
180  * components available within this core module.
181  *
182  * <div doc-module-components="ng"></div>
183  */
184
185 var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
186
187 // The name of a form control's ValidityState property.
188 // This is used so that it's possible for internal tests to create mock ValidityStates.
189 var VALIDITY_STATE_PROPERTY = 'validity';
190
191 /**
192  * @ngdoc function
193  * @name angular.lowercase
194  * @module ng
195  * @kind function
196  *
197  * @description Converts the specified string to lowercase.
198  * @param {string} string String to be converted to lowercase.
199  * @returns {string} Lowercased string.
200  */
201 var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
202 var hasOwnProperty = Object.prototype.hasOwnProperty;
203
204 /**
205  * @ngdoc function
206  * @name angular.uppercase
207  * @module ng
208  * @kind function
209  *
210  * @description Converts the specified string to uppercase.
211  * @param {string} string String to be converted to uppercase.
212  * @returns {string} Uppercased string.
213  */
214 var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
215
216
217 var manualLowercase = function(s) {
218   /* jshint bitwise: false */
219   return isString(s)
220       ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
221       : s;
222 };
223 var manualUppercase = function(s) {
224   /* jshint bitwise: false */
225   return isString(s)
226       ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
227       : s;
228 };
229
230
231 // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
232 // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
233 // with correct but slower alternatives.
234 if ('i' !== 'I'.toLowerCase()) {
235   lowercase = manualLowercase;
236   uppercase = manualUppercase;
237 }
238
239
240 var
241     msie,             // holds major version number for IE, or NaN if UA is not IE.
242     jqLite,           // delay binding since jQuery could be loaded after us.
243     jQuery,           // delay binding
244     slice             = [].slice,
245     splice            = [].splice,
246     push              = [].push,
247     toString          = Object.prototype.toString,
248     getPrototypeOf    = Object.getPrototypeOf,
249     ngMinErr          = minErr('ng'),
250
251     /** @name angular */
252     angular           = window.angular || (window.angular = {}),
253     angularModule,
254     uid               = 0;
255
256 /**
257  * documentMode is an IE-only property
258  * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
259  */
260 msie = document.documentMode;
261
262
263 /**
264  * @private
265  * @param {*} obj
266  * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
267  *                   String ...)
268  */
269 function isArrayLike(obj) {
270   if (obj == null || isWindow(obj)) {
271     return false;
272   }
273
274   // Support: iOS 8.2 (not reproducible in simulator)
275   // "length" in obj used to prevent JIT error (gh-11508)
276   var length = "length" in Object(obj) && obj.length;
277
278   if (obj.nodeType === NODE_TYPE_ELEMENT && length) {
279     return true;
280   }
281
282   return isString(obj) || isArray(obj) || length === 0 ||
283          typeof length === 'number' && length > 0 && (length - 1) in obj;
284 }
285
286 /**
287  * @ngdoc function
288  * @name angular.forEach
289  * @module ng
290  * @kind function
291  *
292  * @description
293  * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
294  * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
295  * is the value of an object property or an array element, `key` is the object property key or
296  * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
297  *
298  * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
299  * using the `hasOwnProperty` method.
300  *
301  * Unlike ES262's
302  * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
303  * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
304  * return the value provided.
305  *
306    ```js
307      var values = {name: 'misko', gender: 'male'};
308      var log = [];
309      angular.forEach(values, function(value, key) {
310        this.push(key + ': ' + value);
311      }, log);
312      expect(log).toEqual(['name: misko', 'gender: male']);
313    ```
314  *
315  * @param {Object|Array} obj Object to iterate over.
316  * @param {Function} iterator Iterator function.
317  * @param {Object=} context Object to become context (`this`) for the iterator function.
318  * @returns {Object|Array} Reference to `obj`.
319  */
320
321 function forEach(obj, iterator, context) {
322   var key, length;
323   if (obj) {
324     if (isFunction(obj)) {
325       for (key in obj) {
326         // Need to check if hasOwnProperty exists,
327         // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
328         if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
329           iterator.call(context, obj[key], key, obj);
330         }
331       }
332     } else if (isArray(obj) || isArrayLike(obj)) {
333       var isPrimitive = typeof obj !== 'object';
334       for (key = 0, length = obj.length; key < length; key++) {
335         if (isPrimitive || key in obj) {
336           iterator.call(context, obj[key], key, obj);
337         }
338       }
339     } else if (obj.forEach && obj.forEach !== forEach) {
340         obj.forEach(iterator, context, obj);
341     } else if (isBlankObject(obj)) {
342       // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
343       for (key in obj) {
344         iterator.call(context, obj[key], key, obj);
345       }
346     } else if (typeof obj.hasOwnProperty === 'function') {
347       // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
348       for (key in obj) {
349         if (obj.hasOwnProperty(key)) {
350           iterator.call(context, obj[key], key, obj);
351         }
352       }
353     } else {
354       // Slow path for objects which do not have a method `hasOwnProperty`
355       for (key in obj) {
356         if (hasOwnProperty.call(obj, key)) {
357           iterator.call(context, obj[key], key, obj);
358         }
359       }
360     }
361   }
362   return obj;
363 }
364
365 function forEachSorted(obj, iterator, context) {
366   var keys = Object.keys(obj).sort();
367   for (var i = 0; i < keys.length; i++) {
368     iterator.call(context, obj[keys[i]], keys[i]);
369   }
370   return keys;
371 }
372
373
374 /**
375  * when using forEach the params are value, key, but it is often useful to have key, value.
376  * @param {function(string, *)} iteratorFn
377  * @returns {function(*, string)}
378  */
379 function reverseParams(iteratorFn) {
380   return function(value, key) { iteratorFn(key, value); };
381 }
382
383 /**
384  * A consistent way of creating unique IDs in angular.
385  *
386  * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
387  * we hit number precision issues in JavaScript.
388  *
389  * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
390  *
391  * @returns {number} an unique alpha-numeric string
392  */
393 function nextUid() {
394   return ++uid;
395 }
396
397
398 /**
399  * Set or clear the hashkey for an object.
400  * @param obj object
401  * @param h the hashkey (!truthy to delete the hashkey)
402  */
403 function setHashKey(obj, h) {
404   if (h) {
405     obj.$$hashKey = h;
406   } else {
407     delete obj.$$hashKey;
408   }
409 }
410
411
412 function baseExtend(dst, objs, deep) {
413   var h = dst.$$hashKey;
414
415   for (var i = 0, ii = objs.length; i < ii; ++i) {
416     var obj = objs[i];
417     if (!isObject(obj) && !isFunction(obj)) continue;
418     var keys = Object.keys(obj);
419     for (var j = 0, jj = keys.length; j < jj; j++) {
420       var key = keys[j];
421       var src = obj[key];
422
423       if (deep && isObject(src)) {
424         if (isDate(src)) {
425           dst[key] = new Date(src.valueOf());
426         } else {
427           if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
428           baseExtend(dst[key], [src], true);
429         }
430       } else {
431         dst[key] = src;
432       }
433     }
434   }
435
436   setHashKey(dst, h);
437   return dst;
438 }
439
440 /**
441  * @ngdoc function
442  * @name angular.extend
443  * @module ng
444  * @kind function
445  *
446  * @description
447  * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
448  * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
449  * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
450  *
451  * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
452  * {@link angular.merge} for this.
453  *
454  * @param {Object} dst Destination object.
455  * @param {...Object} src Source object(s).
456  * @returns {Object} Reference to `dst`.
457  */
458 function extend(dst) {
459   return baseExtend(dst, slice.call(arguments, 1), false);
460 }
461
462
463 /**
464 * @ngdoc function
465 * @name angular.merge
466 * @module ng
467 * @kind function
468 *
469 * @description
470 * Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
471 * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
472 * by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
473 *
474 * Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
475 * objects, performing a deep copy.
476 *
477 * @param {Object} dst Destination object.
478 * @param {...Object} src Source object(s).
479 * @returns {Object} Reference to `dst`.
480 */
481 function merge(dst) {
482   return baseExtend(dst, slice.call(arguments, 1), true);
483 }
484
485
486
487 function toInt(str) {
488   return parseInt(str, 10);
489 }
490
491
492 function inherit(parent, extra) {
493   return extend(Object.create(parent), extra);
494 }
495
496 /**
497  * @ngdoc function
498  * @name angular.noop
499  * @module ng
500  * @kind function
501  *
502  * @description
503  * A function that performs no operations. This function can be useful when writing code in the
504  * functional style.
505    ```js
506      function foo(callback) {
507        var result = calculateResult();
508        (callback || angular.noop)(result);
509      }
510    ```
511  */
512 function noop() {}
513 noop.$inject = [];
514
515
516 /**
517  * @ngdoc function
518  * @name angular.identity
519  * @module ng
520  * @kind function
521  *
522  * @description
523  * A function that returns its first argument. This function is useful when writing code in the
524  * functional style.
525  *
526    ```js
527      function transformer(transformationFn, value) {
528        return (transformationFn || angular.identity)(value);
529      };
530    ```
531   * @param {*} value to be returned.
532   * @returns {*} the value passed in.
533  */
534 function identity($) {return $;}
535 identity.$inject = [];
536
537
538 function valueFn(value) {return function() {return value;};}
539
540 function hasCustomToString(obj) {
541   return isFunction(obj.toString) && obj.toString !== Object.prototype.toString;
542 }
543
544
545 /**
546  * @ngdoc function
547  * @name angular.isUndefined
548  * @module ng
549  * @kind function
550  *
551  * @description
552  * Determines if a reference is undefined.
553  *
554  * @param {*} value Reference to check.
555  * @returns {boolean} True if `value` is undefined.
556  */
557 function isUndefined(value) {return typeof value === 'undefined';}
558
559
560 /**
561  * @ngdoc function
562  * @name angular.isDefined
563  * @module ng
564  * @kind function
565  *
566  * @description
567  * Determines if a reference is defined.
568  *
569  * @param {*} value Reference to check.
570  * @returns {boolean} True if `value` is defined.
571  */
572 function isDefined(value) {return typeof value !== 'undefined';}
573
574
575 /**
576  * @ngdoc function
577  * @name angular.isObject
578  * @module ng
579  * @kind function
580  *
581  * @description
582  * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
583  * considered to be objects. Note that JavaScript arrays are objects.
584  *
585  * @param {*} value Reference to check.
586  * @returns {boolean} True if `value` is an `Object` but not `null`.
587  */
588 function isObject(value) {
589   // http://jsperf.com/isobject4
590   return value !== null && typeof value === 'object';
591 }
592
593
594 /**
595  * Determine if a value is an object with a null prototype
596  *
597  * @returns {boolean} True if `value` is an `Object` with a null prototype
598  */
599 function isBlankObject(value) {
600   return value !== null && typeof value === 'object' && !getPrototypeOf(value);
601 }
602
603
604 /**
605  * @ngdoc function
606  * @name angular.isString
607  * @module ng
608  * @kind function
609  *
610  * @description
611  * Determines if a reference is a `String`.
612  *
613  * @param {*} value Reference to check.
614  * @returns {boolean} True if `value` is a `String`.
615  */
616 function isString(value) {return typeof value === 'string';}
617
618
619 /**
620  * @ngdoc function
621  * @name angular.isNumber
622  * @module ng
623  * @kind function
624  *
625  * @description
626  * Determines if a reference is a `Number`.
627  *
628  * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
629  *
630  * If you wish to exclude these then you can use the native
631  * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
632  * method.
633  *
634  * @param {*} value Reference to check.
635  * @returns {boolean} True if `value` is a `Number`.
636  */
637 function isNumber(value) {return typeof value === 'number';}
638
639
640 /**
641  * @ngdoc function
642  * @name angular.isDate
643  * @module ng
644  * @kind function
645  *
646  * @description
647  * Determines if a value is a date.
648  *
649  * @param {*} value Reference to check.
650  * @returns {boolean} True if `value` is a `Date`.
651  */
652 function isDate(value) {
653   return toString.call(value) === '[object Date]';
654 }
655
656
657 /**
658  * @ngdoc function
659  * @name angular.isArray
660  * @module ng
661  * @kind function
662  *
663  * @description
664  * Determines if a reference is an `Array`.
665  *
666  * @param {*} value Reference to check.
667  * @returns {boolean} True if `value` is an `Array`.
668  */
669 var isArray = Array.isArray;
670
671 /**
672  * @ngdoc function
673  * @name angular.isFunction
674  * @module ng
675  * @kind function
676  *
677  * @description
678  * Determines if a reference is a `Function`.
679  *
680  * @param {*} value Reference to check.
681  * @returns {boolean} True if `value` is a `Function`.
682  */
683 function isFunction(value) {return typeof value === 'function';}
684
685
686 /**
687  * Determines if a value is a regular expression object.
688  *
689  * @private
690  * @param {*} value Reference to check.
691  * @returns {boolean} True if `value` is a `RegExp`.
692  */
693 function isRegExp(value) {
694   return toString.call(value) === '[object RegExp]';
695 }
696
697
698 /**
699  * Checks if `obj` is a window object.
700  *
701  * @private
702  * @param {*} obj Object to check
703  * @returns {boolean} True if `obj` is a window obj.
704  */
705 function isWindow(obj) {
706   return obj && obj.window === obj;
707 }
708
709
710 function isScope(obj) {
711   return obj && obj.$evalAsync && obj.$watch;
712 }
713
714
715 function isFile(obj) {
716   return toString.call(obj) === '[object File]';
717 }
718
719
720 function isFormData(obj) {
721   return toString.call(obj) === '[object FormData]';
722 }
723
724
725 function isBlob(obj) {
726   return toString.call(obj) === '[object Blob]';
727 }
728
729
730 function isBoolean(value) {
731   return typeof value === 'boolean';
732 }
733
734
735 function isPromiseLike(obj) {
736   return obj && isFunction(obj.then);
737 }
738
739
740 var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/;
741 function isTypedArray(value) {
742   return TYPED_ARRAY_REGEXP.test(toString.call(value));
743 }
744
745
746 var trim = function(value) {
747   return isString(value) ? value.trim() : value;
748 };
749
750 // Copied from:
751 // http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
752 // Prereq: s is a string.
753 var escapeForRegexp = function(s) {
754   return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
755            replace(/\x08/g, '\\x08');
756 };
757
758
759 /**
760  * @ngdoc function
761  * @name angular.isElement
762  * @module ng
763  * @kind function
764  *
765  * @description
766  * Determines if a reference is a DOM element (or wrapped jQuery element).
767  *
768  * @param {*} value Reference to check.
769  * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
770  */
771 function isElement(node) {
772   return !!(node &&
773     (node.nodeName  // we are a direct element
774     || (node.prop && node.attr && node.find)));  // we have an on and find method part of jQuery API
775 }
776
777 /**
778  * @param str 'key1,key2,...'
779  * @returns {object} in the form of {key1:true, key2:true, ...}
780  */
781 function makeMap(str) {
782   var obj = {}, items = str.split(","), i;
783   for (i = 0; i < items.length; i++) {
784     obj[items[i]] = true;
785   }
786   return obj;
787 }
788
789
790 function nodeName_(element) {
791   return lowercase(element.nodeName || (element[0] && element[0].nodeName));
792 }
793
794 function includes(array, obj) {
795   return Array.prototype.indexOf.call(array, obj) != -1;
796 }
797
798 function arrayRemove(array, value) {
799   var index = array.indexOf(value);
800   if (index >= 0) {
801     array.splice(index, 1);
802   }
803   return index;
804 }
805
806 /**
807  * @ngdoc function
808  * @name angular.copy
809  * @module ng
810  * @kind function
811  *
812  * @description
813  * Creates a deep copy of `source`, which should be an object or an array.
814  *
815  * * If no destination is supplied, a copy of the object or array is created.
816  * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
817  *   are deleted and then all elements/properties from the source are copied to it.
818  * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
819  * * If `source` is identical to 'destination' an exception will be thrown.
820  *
821  * @param {*} source The source that will be used to make a copy.
822  *                   Can be any type, including primitives, `null`, and `undefined`.
823  * @param {(Object|Array)=} destination Destination into which the source is copied. If
824  *     provided, must be of the same type as `source`.
825  * @returns {*} The copy or updated `destination`, if `destination` was specified.
826  *
827  * @example
828  <example module="copyExample">
829  <file name="index.html">
830  <div ng-controller="ExampleController">
831  <form novalidate class="simple-form">
832  Name: <input type="text" ng-model="user.name" /><br />
833  E-mail: <input type="email" ng-model="user.email" /><br />
834  Gender: <input type="radio" ng-model="user.gender" value="male" />male
835  <input type="radio" ng-model="user.gender" value="female" />female<br />
836  <button ng-click="reset()">RESET</button>
837  <button ng-click="update(user)">SAVE</button>
838  </form>
839  <pre>form = {{user | json}}</pre>
840  <pre>master = {{master | json}}</pre>
841  </div>
842
843  <script>
844   angular.module('copyExample', [])
845     .controller('ExampleController', ['$scope', function($scope) {
846       $scope.master= {};
847
848       $scope.update = function(user) {
849         // Example with 1 argument
850         $scope.master= angular.copy(user);
851       };
852
853       $scope.reset = function() {
854         // Example with 2 arguments
855         angular.copy($scope.master, $scope.user);
856       };
857
858       $scope.reset();
859     }]);
860  </script>
861  </file>
862  </example>
863  */
864 function copy(source, destination, stackSource, stackDest) {
865   if (isWindow(source) || isScope(source)) {
866     throw ngMinErr('cpws',
867       "Can't copy! Making copies of Window or Scope instances is not supported.");
868   }
869   if (isTypedArray(destination)) {
870     throw ngMinErr('cpta',
871       "Can't copy! TypedArray destination cannot be mutated.");
872   }
873
874   if (!destination) {
875     destination = source;
876     if (isObject(source)) {
877       var index;
878       if (stackSource && (index = stackSource.indexOf(source)) !== -1) {
879         return stackDest[index];
880       }
881
882       // TypedArray, Date and RegExp have specific copy functionality and must be
883       // pushed onto the stack before returning.
884       // Array and other objects create the base object and recurse to copy child
885       // objects. The array/object will be pushed onto the stack when recursed.
886       if (isArray(source)) {
887         return copy(source, [], stackSource, stackDest);
888       } else if (isTypedArray(source)) {
889         destination = new source.constructor(source);
890       } else if (isDate(source)) {
891         destination = new Date(source.getTime());
892       } else if (isRegExp(source)) {
893         destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
894         destination.lastIndex = source.lastIndex;
895       } else {
896         var emptyObject = Object.create(getPrototypeOf(source));
897         return copy(source, emptyObject, stackSource, stackDest);
898       }
899
900       if (stackDest) {
901         stackSource.push(source);
902         stackDest.push(destination);
903       }
904     }
905   } else {
906     if (source === destination) throw ngMinErr('cpi',
907       "Can't copy! Source and destination are identical.");
908
909     stackSource = stackSource || [];
910     stackDest = stackDest || [];
911
912     if (isObject(source)) {
913       stackSource.push(source);
914       stackDest.push(destination);
915     }
916
917     var result, key;
918     if (isArray(source)) {
919       destination.length = 0;
920       for (var i = 0; i < source.length; i++) {
921         destination.push(copy(source[i], null, stackSource, stackDest));
922       }
923     } else {
924       var h = destination.$$hashKey;
925       if (isArray(destination)) {
926         destination.length = 0;
927       } else {
928         forEach(destination, function(value, key) {
929           delete destination[key];
930         });
931       }
932       if (isBlankObject(source)) {
933         // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
934         for (key in source) {
935           destination[key] = copy(source[key], null, stackSource, stackDest);
936         }
937       } else if (source && typeof source.hasOwnProperty === 'function') {
938         // Slow path, which must rely on hasOwnProperty
939         for (key in source) {
940           if (source.hasOwnProperty(key)) {
941             destination[key] = copy(source[key], null, stackSource, stackDest);
942           }
943         }
944       } else {
945         // Slowest path --- hasOwnProperty can't be called as a method
946         for (key in source) {
947           if (hasOwnProperty.call(source, key)) {
948             destination[key] = copy(source[key], null, stackSource, stackDest);
949           }
950         }
951       }
952       setHashKey(destination,h);
953     }
954   }
955   return destination;
956 }
957
958 /**
959  * Creates a shallow copy of an object, an array or a primitive.
960  *
961  * Assumes that there are no proto properties for objects.
962  */
963 function shallowCopy(src, dst) {
964   if (isArray(src)) {
965     dst = dst || [];
966
967     for (var i = 0, ii = src.length; i < ii; i++) {
968       dst[i] = src[i];
969     }
970   } else if (isObject(src)) {
971     dst = dst || {};
972
973     for (var key in src) {
974       if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
975         dst[key] = src[key];
976       }
977     }
978   }
979
980   return dst || src;
981 }
982
983
984 /**
985  * @ngdoc function
986  * @name angular.equals
987  * @module ng
988  * @kind function
989  *
990  * @description
991  * Determines if two objects or two values are equivalent. Supports value types, regular
992  * expressions, arrays and objects.
993  *
994  * Two objects or values are considered equivalent if at least one of the following is true:
995  *
996  * * Both objects or values pass `===` comparison.
997  * * Both objects or values are of the same type and all of their properties are equal by
998  *   comparing them with `angular.equals`.
999  * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
1000  * * Both values represent the same regular expression (In JavaScript,
1001  *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
1002  *   representation matches).
1003  *
1004  * During a property comparison, properties of `function` type and properties with names
1005  * that begin with `$` are ignored.
1006  *
1007  * Scope and DOMWindow objects are being compared only by identify (`===`).
1008  *
1009  * @param {*} o1 Object or value to compare.
1010  * @param {*} o2 Object or value to compare.
1011  * @returns {boolean} True if arguments are equal.
1012  */
1013 function equals(o1, o2) {
1014   if (o1 === o2) return true;
1015   if (o1 === null || o2 === null) return false;
1016   if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
1017   var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
1018   if (t1 == t2) {
1019     if (t1 == 'object') {
1020       if (isArray(o1)) {
1021         if (!isArray(o2)) return false;
1022         if ((length = o1.length) == o2.length) {
1023           for (key = 0; key < length; key++) {
1024             if (!equals(o1[key], o2[key])) return false;
1025           }
1026           return true;
1027         }
1028       } else if (isDate(o1)) {
1029         if (!isDate(o2)) return false;
1030         return equals(o1.getTime(), o2.getTime());
1031       } else if (isRegExp(o1)) {
1032         return isRegExp(o2) ? o1.toString() == o2.toString() : false;
1033       } else {
1034         if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
1035           isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
1036         keySet = createMap();
1037         for (key in o1) {
1038           if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1039           if (!equals(o1[key], o2[key])) return false;
1040           keySet[key] = true;
1041         }
1042         for (key in o2) {
1043           if (!(key in keySet) &&
1044               key.charAt(0) !== '$' &&
1045               o2[key] !== undefined &&
1046               !isFunction(o2[key])) return false;
1047         }
1048         return true;
1049       }
1050     }
1051   }
1052   return false;
1053 }
1054
1055 var csp = function() {
1056   if (isDefined(csp.isActive_)) return csp.isActive_;
1057
1058   var active = !!(document.querySelector('[ng-csp]') ||
1059                   document.querySelector('[data-ng-csp]'));
1060
1061   if (!active) {
1062     try {
1063       /* jshint -W031, -W054 */
1064       new Function('');
1065       /* jshint +W031, +W054 */
1066     } catch (e) {
1067       active = true;
1068     }
1069   }
1070
1071   return (csp.isActive_ = active);
1072 };
1073
1074 /**
1075  * @ngdoc directive
1076  * @module ng
1077  * @name ngJq
1078  *
1079  * @element ANY
1080  * @param {string=} ngJq the name of the library available under `window`
1081  * to be used for angular.element
1082  * @description
1083  * Use this directive to force the angular.element library.  This should be
1084  * used to force either jqLite by leaving ng-jq blank or setting the name of
1085  * the jquery variable under window (eg. jQuery).
1086  *
1087  * Since angular looks for this directive when it is loaded (doesn't wait for the
1088  * DOMContentLoaded event), it must be placed on an element that comes before the script
1089  * which loads angular. Also, only the first instance of `ng-jq` will be used and all
1090  * others ignored.
1091  *
1092  * @example
1093  * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
1094  ```html
1095  <!doctype html>
1096  <html ng-app ng-jq>
1097  ...
1098  ...
1099  </html>
1100  ```
1101  * @example
1102  * This example shows how to use a jQuery based library of a different name.
1103  * The library name must be available at the top most 'window'.
1104  ```html
1105  <!doctype html>
1106  <html ng-app ng-jq="jQueryLib">
1107  ...
1108  ...
1109  </html>
1110  ```
1111  */
1112 var jq = function() {
1113   if (isDefined(jq.name_)) return jq.name_;
1114   var el;
1115   var i, ii = ngAttrPrefixes.length, prefix, name;
1116   for (i = 0; i < ii; ++i) {
1117     prefix = ngAttrPrefixes[i];
1118     if (el = document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
1119       name = el.getAttribute(prefix + 'jq');
1120       break;
1121     }
1122   }
1123
1124   return (jq.name_ = name);
1125 };
1126
1127 function concat(array1, array2, index) {
1128   return array1.concat(slice.call(array2, index));
1129 }
1130
1131 function sliceArgs(args, startIndex) {
1132   return slice.call(args, startIndex || 0);
1133 }
1134
1135
1136 /* jshint -W101 */
1137 /**
1138  * @ngdoc function
1139  * @name angular.bind
1140  * @module ng
1141  * @kind function
1142  *
1143  * @description
1144  * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
1145  * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
1146  * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
1147  * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
1148  *
1149  * @param {Object} self Context which `fn` should be evaluated in.
1150  * @param {function()} fn Function to be bound.
1151  * @param {...*} args Optional arguments to be prebound to the `fn` function call.
1152  * @returns {function()} Function that wraps the `fn` with all the specified bindings.
1153  */
1154 /* jshint +W101 */
1155 function bind(self, fn) {
1156   var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
1157   if (isFunction(fn) && !(fn instanceof RegExp)) {
1158     return curryArgs.length
1159       ? function() {
1160           return arguments.length
1161             ? fn.apply(self, concat(curryArgs, arguments, 0))
1162             : fn.apply(self, curryArgs);
1163         }
1164       : function() {
1165           return arguments.length
1166             ? fn.apply(self, arguments)
1167             : fn.call(self);
1168         };
1169   } else {
1170     // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
1171     return fn;
1172   }
1173 }
1174
1175
1176 function toJsonReplacer(key, value) {
1177   var val = value;
1178
1179   if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
1180     val = undefined;
1181   } else if (isWindow(value)) {
1182     val = '$WINDOW';
1183   } else if (value &&  document === value) {
1184     val = '$DOCUMENT';
1185   } else if (isScope(value)) {
1186     val = '$SCOPE';
1187   }
1188
1189   return val;
1190 }
1191
1192
1193 /**
1194  * @ngdoc function
1195  * @name angular.toJson
1196  * @module ng
1197  * @kind function
1198  *
1199  * @description
1200  * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
1201  * stripped since angular uses this notation internally.
1202  *
1203  * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
1204  * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
1205  *    If set to an integer, the JSON output will contain that many spaces per indentation.
1206  * @returns {string|undefined} JSON-ified string representing `obj`.
1207  */
1208 function toJson(obj, pretty) {
1209   if (typeof obj === 'undefined') return undefined;
1210   if (!isNumber(pretty)) {
1211     pretty = pretty ? 2 : null;
1212   }
1213   return JSON.stringify(obj, toJsonReplacer, pretty);
1214 }
1215
1216
1217 /**
1218  * @ngdoc function
1219  * @name angular.fromJson
1220  * @module ng
1221  * @kind function
1222  *
1223  * @description
1224  * Deserializes a JSON string.
1225  *
1226  * @param {string} json JSON string to deserialize.
1227  * @returns {Object|Array|string|number} Deserialized JSON string.
1228  */
1229 function fromJson(json) {
1230   return isString(json)
1231       ? JSON.parse(json)
1232       : json;
1233 }
1234
1235
1236 function timezoneToOffset(timezone, fallback) {
1237   var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
1238   return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
1239 }
1240
1241
1242 function addDateMinutes(date, minutes) {
1243   date = new Date(date.getTime());
1244   date.setMinutes(date.getMinutes() + minutes);
1245   return date;
1246 }
1247
1248
1249 function convertTimezoneToLocal(date, timezone, reverse) {
1250   reverse = reverse ? -1 : 1;
1251   var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset());
1252   return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset()));
1253 }
1254
1255
1256 /**
1257  * @returns {string} Returns the string representation of the element.
1258  */
1259 function startingTag(element) {
1260   element = jqLite(element).clone();
1261   try {
1262     // turns out IE does not let you set .html() on elements which
1263     // are not allowed to have children. So we just ignore it.
1264     element.empty();
1265   } catch (e) {}
1266   var elemHtml = jqLite('<div>').append(element).html();
1267   try {
1268     return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
1269         elemHtml.
1270           match(/^(<[^>]+>)/)[1].
1271           replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
1272   } catch (e) {
1273     return lowercase(elemHtml);
1274   }
1275
1276 }
1277
1278
1279 /////////////////////////////////////////////////
1280
1281 /**
1282  * Tries to decode the URI component without throwing an exception.
1283  *
1284  * @private
1285  * @param str value potential URI component to check.
1286  * @returns {boolean} True if `value` can be decoded
1287  * with the decodeURIComponent function.
1288  */
1289 function tryDecodeURIComponent(value) {
1290   try {
1291     return decodeURIComponent(value);
1292   } catch (e) {
1293     // Ignore any invalid uri component
1294   }
1295 }
1296
1297
1298 /**
1299  * Parses an escaped url query string into key-value pairs.
1300  * @returns {Object.<string,boolean|Array>}
1301  */
1302 function parseKeyValue(/**string*/keyValue) {
1303   var obj = {}, key_value, key;
1304   forEach((keyValue || "").split('&'), function(keyValue) {
1305     if (keyValue) {
1306       key_value = keyValue.replace(/\+/g,'%20').split('=');
1307       key = tryDecodeURIComponent(key_value[0]);
1308       if (isDefined(key)) {
1309         var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
1310         if (!hasOwnProperty.call(obj, key)) {
1311           obj[key] = val;
1312         } else if (isArray(obj[key])) {
1313           obj[key].push(val);
1314         } else {
1315           obj[key] = [obj[key],val];
1316         }
1317       }
1318     }
1319   });
1320   return obj;
1321 }
1322
1323 function toKeyValue(obj) {
1324   var parts = [];
1325   forEach(obj, function(value, key) {
1326     if (isArray(value)) {
1327       forEach(value, function(arrayValue) {
1328         parts.push(encodeUriQuery(key, true) +
1329                    (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
1330       });
1331     } else {
1332     parts.push(encodeUriQuery(key, true) +
1333                (value === true ? '' : '=' + encodeUriQuery(value, true)));
1334     }
1335   });
1336   return parts.length ? parts.join('&') : '';
1337 }
1338
1339
1340 /**
1341  * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
1342  * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
1343  * segments:
1344  *    segment       = *pchar
1345  *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
1346  *    pct-encoded   = "%" HEXDIG HEXDIG
1347  *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
1348  *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
1349  *                     / "*" / "+" / "," / ";" / "="
1350  */
1351 function encodeUriSegment(val) {
1352   return encodeUriQuery(val, true).
1353              replace(/%26/gi, '&').
1354              replace(/%3D/gi, '=').
1355              replace(/%2B/gi, '+');
1356 }
1357
1358
1359 /**
1360  * This method is intended for encoding *key* or *value* parts of query component. We need a custom
1361  * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
1362  * encoded per http://tools.ietf.org/html/rfc3986:
1363  *    query       = *( pchar / "/" / "?" )
1364  *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
1365  *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
1366  *    pct-encoded   = "%" HEXDIG HEXDIG
1367  *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
1368  *                     / "*" / "+" / "," / ";" / "="
1369  */
1370 function encodeUriQuery(val, pctEncodeSpaces) {
1371   return encodeURIComponent(val).
1372              replace(/%40/gi, '@').
1373              replace(/%3A/gi, ':').
1374              replace(/%24/g, '$').
1375              replace(/%2C/gi, ',').
1376              replace(/%3B/gi, ';').
1377              replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
1378 }
1379
1380 var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
1381
1382 function getNgAttribute(element, ngAttr) {
1383   var attr, i, ii = ngAttrPrefixes.length;
1384   for (i = 0; i < ii; ++i) {
1385     attr = ngAttrPrefixes[i] + ngAttr;
1386     if (isString(attr = element.getAttribute(attr))) {
1387       return attr;
1388     }
1389   }
1390   return null;
1391 }
1392
1393 /**
1394  * @ngdoc directive
1395  * @name ngApp
1396  * @module ng
1397  *
1398  * @element ANY
1399  * @param {angular.Module} ngApp an optional application
1400  *   {@link angular.module module} name to load.
1401  * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
1402  *   created in "strict-di" mode. This means that the application will fail to invoke functions which
1403  *   do not use explicit function annotation (and are thus unsuitable for minification), as described
1404  *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
1405  *   tracking down the root of these bugs.
1406  *
1407  * @description
1408  *
1409  * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
1410  * designates the **root element** of the application and is typically placed near the root element
1411  * of the page - e.g. on the `<body>` or `<html>` tags.
1412  *
1413  * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
1414  * found in the document will be used to define the root element to auto-bootstrap as an
1415  * application. To run multiple applications in an HTML document you must manually bootstrap them using
1416  * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
1417  *
1418  * You can specify an **AngularJS module** to be used as the root module for the application.  This
1419  * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
1420  * should contain the application code needed or have dependencies on other modules that will
1421  * contain the code. See {@link angular.module} for more information.
1422  *
1423  * In the example below if the `ngApp` directive were not placed on the `html` element then the
1424  * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
1425  * would not be resolved to `3`.
1426  *
1427  * `ngApp` is the easiest, and most common way to bootstrap an application.
1428  *
1429  <example module="ngAppDemo">
1430    <file name="index.html">
1431    <div ng-controller="ngAppDemoController">
1432      I can add: {{a}} + {{b}} =  {{ a+b }}
1433    </div>
1434    </file>
1435    <file name="script.js">
1436    angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
1437      $scope.a = 1;
1438      $scope.b = 2;
1439    });
1440    </file>
1441  </example>
1442  *
1443  * Using `ngStrictDi`, you would see something like this:
1444  *
1445  <example ng-app-included="true">
1446    <file name="index.html">
1447    <div ng-app="ngAppStrictDemo" ng-strict-di>
1448        <div ng-controller="GoodController1">
1449            I can add: {{a}} + {{b}} =  {{ a+b }}
1450
1451            <p>This renders because the controller does not fail to
1452               instantiate, by using explicit annotation style (see
1453               script.js for details)
1454            </p>
1455        </div>
1456
1457        <div ng-controller="GoodController2">
1458            Name: <input ng-model="name"><br />
1459            Hello, {{name}}!
1460
1461            <p>This renders because the controller does not fail to
1462               instantiate, by using explicit annotation style
1463               (see script.js for details)
1464            </p>
1465        </div>
1466
1467        <div ng-controller="BadController">
1468            I can add: {{a}} + {{b}} =  {{ a+b }}
1469
1470            <p>The controller could not be instantiated, due to relying
1471               on automatic function annotations (which are disabled in
1472               strict mode). As such, the content of this section is not
1473               interpolated, and there should be an error in your web console.
1474            </p>
1475        </div>
1476    </div>
1477    </file>
1478    <file name="script.js">
1479    angular.module('ngAppStrictDemo', [])
1480      // BadController will fail to instantiate, due to relying on automatic function annotation,
1481      // rather than an explicit annotation
1482      .controller('BadController', function($scope) {
1483        $scope.a = 1;
1484        $scope.b = 2;
1485      })
1486      // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
1487      // due to using explicit annotations using the array style and $inject property, respectively.
1488      .controller('GoodController1', ['$scope', function($scope) {
1489        $scope.a = 1;
1490        $scope.b = 2;
1491      }])
1492      .controller('GoodController2', GoodController2);
1493      function GoodController2($scope) {
1494        $scope.name = "World";
1495      }
1496      GoodController2.$inject = ['$scope'];
1497    </file>
1498    <file name="style.css">
1499    div[ng-controller] {
1500        margin-bottom: 1em;
1501        -webkit-border-radius: 4px;
1502        border-radius: 4px;
1503        border: 1px solid;
1504        padding: .5em;
1505    }
1506    div[ng-controller^=Good] {
1507        border-color: #d6e9c6;
1508        background-color: #dff0d8;
1509        color: #3c763d;
1510    }
1511    div[ng-controller^=Bad] {
1512        border-color: #ebccd1;
1513        background-color: #f2dede;
1514        color: #a94442;
1515        margin-bottom: 0;
1516    }
1517    </file>
1518  </example>
1519  */
1520 function angularInit(element, bootstrap) {
1521   var appElement,
1522       module,
1523       config = {};
1524
1525   // The element `element` has priority over any other element
1526   forEach(ngAttrPrefixes, function(prefix) {
1527     var name = prefix + 'app';
1528
1529     if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
1530       appElement = element;
1531       module = element.getAttribute(name);
1532     }
1533   });
1534   forEach(ngAttrPrefixes, function(prefix) {
1535     var name = prefix + 'app';
1536     var candidate;
1537
1538     if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
1539       appElement = candidate;
1540       module = candidate.getAttribute(name);
1541     }
1542   });
1543   if (appElement) {
1544     config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
1545     bootstrap(appElement, module ? [module] : [], config);
1546   }
1547 }
1548
1549 /**
1550  * @ngdoc function
1551  * @name angular.bootstrap
1552  * @module ng
1553  * @description
1554  * Use this function to manually start up angular application.
1555  *
1556  * See: {@link guide/bootstrap Bootstrap}
1557  *
1558  * Note that Protractor based end-to-end tests cannot use this function to bootstrap manually.
1559  * They must use {@link ng.directive:ngApp ngApp}.
1560  *
1561  * Angular will detect if it has been loaded into the browser more than once and only allow the
1562  * first loaded script to be bootstrapped and will report a warning to the browser console for
1563  * each of the subsequent scripts. This prevents strange results in applications, where otherwise
1564  * multiple instances of Angular try to work on the DOM.
1565  *
1566  * ```html
1567  * <!doctype html>
1568  * <html>
1569  * <body>
1570  * <div ng-controller="WelcomeController">
1571  *   {{greeting}}
1572  * </div>
1573  *
1574  * <script src="angular.js"></script>
1575  * <script>
1576  *   var app = angular.module('demo', [])
1577  *   .controller('WelcomeController', function($scope) {
1578  *       $scope.greeting = 'Welcome!';
1579  *   });
1580  *   angular.bootstrap(document, ['demo']);
1581  * </script>
1582  * </body>
1583  * </html>
1584  * ```
1585  *
1586  * @param {DOMElement} element DOM element which is the root of angular application.
1587  * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
1588  *     Each item in the array should be the name of a predefined module or a (DI annotated)
1589  *     function that will be invoked by the injector as a `config` block.
1590  *     See: {@link angular.module modules}
1591  * @param {Object=} config an object for defining configuration options for the application. The
1592  *     following keys are supported:
1593  *
1594  * * `strictDi` - disable automatic function annotation for the application. This is meant to
1595  *   assist in finding bugs which break minified code. Defaults to `false`.
1596  *
1597  * @returns {auto.$injector} Returns the newly created injector for this app.
1598  */
1599 function bootstrap(element, modules, config) {
1600   if (!isObject(config)) config = {};
1601   var defaultConfig = {
1602     strictDi: false
1603   };
1604   config = extend(defaultConfig, config);
1605   var doBootstrap = function() {
1606     element = jqLite(element);
1607
1608     if (element.injector()) {
1609       var tag = (element[0] === document) ? 'document' : startingTag(element);
1610       //Encode angle brackets to prevent input from being sanitized to empty string #8683
1611       throw ngMinErr(
1612           'btstrpd',
1613           "App Already Bootstrapped with this Element '{0}'",
1614           tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
1615     }
1616
1617     modules = modules || [];
1618     modules.unshift(['$provide', function($provide) {
1619       $provide.value('$rootElement', element);
1620     }]);
1621
1622     if (config.debugInfoEnabled) {
1623       // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
1624       modules.push(['$compileProvider', function($compileProvider) {
1625         $compileProvider.debugInfoEnabled(true);
1626       }]);
1627     }
1628
1629     modules.unshift('ng');
1630     var injector = createInjector(modules, config.strictDi);
1631     injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
1632        function bootstrapApply(scope, element, compile, injector) {
1633         scope.$apply(function() {
1634           element.data('$injector', injector);
1635           compile(element)(scope);
1636         });
1637       }]
1638     );
1639     return injector;
1640   };
1641
1642   var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
1643   var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
1644
1645   if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
1646     config.debugInfoEnabled = true;
1647     window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
1648   }
1649
1650   if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
1651     return doBootstrap();
1652   }
1653
1654   window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
1655   angular.resumeBootstrap = function(extraModules) {
1656     forEach(extraModules, function(module) {
1657       modules.push(module);
1658     });
1659     return doBootstrap();
1660   };
1661
1662   if (isFunction(angular.resumeDeferredBootstrap)) {
1663     angular.resumeDeferredBootstrap();
1664   }
1665 }
1666
1667 /**
1668  * @ngdoc function
1669  * @name angular.reloadWithDebugInfo
1670  * @module ng
1671  * @description
1672  * Use this function to reload the current application with debug information turned on.
1673  * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
1674  *
1675  * See {@link ng.$compileProvider#debugInfoEnabled} for more.
1676  */
1677 function reloadWithDebugInfo() {
1678   window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
1679   window.location.reload();
1680 }
1681
1682 /**
1683  * @name angular.getTestability
1684  * @module ng
1685  * @description
1686  * Get the testability service for the instance of Angular on the given
1687  * element.
1688  * @param {DOMElement} element DOM element which is the root of angular application.
1689  */
1690 function getTestability(rootElement) {
1691   var injector = angular.element(rootElement).injector();
1692   if (!injector) {
1693     throw ngMinErr('test',
1694       'no injector found for element argument to getTestability');
1695   }
1696   return injector.get('$$testability');
1697 }
1698
1699 var SNAKE_CASE_REGEXP = /[A-Z]/g;
1700 function snake_case(name, separator) {
1701   separator = separator || '_';
1702   return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
1703     return (pos ? separator : '') + letter.toLowerCase();
1704   });
1705 }
1706
1707 var bindJQueryFired = false;
1708 var skipDestroyOnNextJQueryCleanData;
1709 function bindJQuery() {
1710   var originalCleanData;
1711
1712   if (bindJQueryFired) {
1713     return;
1714   }
1715
1716   // bind to jQuery if present;
1717   var jqName = jq();
1718   jQuery = window.jQuery; // use default jQuery.
1719   if (isDefined(jqName)) { // `ngJq` present
1720     jQuery = jqName === null ? undefined : window[jqName]; // if empty; use jqLite. if not empty, use jQuery specified by `ngJq`.
1721   }
1722
1723   // Use jQuery if it exists with proper functionality, otherwise default to us.
1724   // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
1725   // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
1726   // versions. It will not work for sure with jQuery <1.7, though.
1727   if (jQuery && jQuery.fn.on) {
1728     jqLite = jQuery;
1729     extend(jQuery.fn, {
1730       scope: JQLitePrototype.scope,
1731       isolateScope: JQLitePrototype.isolateScope,
1732       controller: JQLitePrototype.controller,
1733       injector: JQLitePrototype.injector,
1734       inheritedData: JQLitePrototype.inheritedData
1735     });
1736
1737     // All nodes removed from the DOM via various jQuery APIs like .remove()
1738     // are passed through jQuery.cleanData. Monkey-patch this method to fire
1739     // the $destroy event on all removed nodes.
1740     originalCleanData = jQuery.cleanData;
1741     jQuery.cleanData = function(elems) {
1742       var events;
1743       if (!skipDestroyOnNextJQueryCleanData) {
1744         for (var i = 0, elem; (elem = elems[i]) != null; i++) {
1745           events = jQuery._data(elem, "events");
1746           if (events && events.$destroy) {
1747             jQuery(elem).triggerHandler('$destroy');
1748           }
1749         }
1750       } else {
1751         skipDestroyOnNextJQueryCleanData = false;
1752       }
1753       originalCleanData(elems);
1754     };
1755   } else {
1756     jqLite = JQLite;
1757   }
1758
1759   angular.element = jqLite;
1760
1761   // Prevent double-proxying.
1762   bindJQueryFired = true;
1763 }
1764
1765 /**
1766  * throw error if the argument is falsy.
1767  */
1768 function assertArg(arg, name, reason) {
1769   if (!arg) {
1770     throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
1771   }
1772   return arg;
1773 }
1774
1775 function assertArgFn(arg, name, acceptArrayAnnotation) {
1776   if (acceptArrayAnnotation && isArray(arg)) {
1777       arg = arg[arg.length - 1];
1778   }
1779
1780   assertArg(isFunction(arg), name, 'not a function, got ' +
1781       (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
1782   return arg;
1783 }
1784
1785 /**
1786  * throw error if the name given is hasOwnProperty
1787  * @param  {String} name    the name to test
1788  * @param  {String} context the context in which the name is used, such as module or directive
1789  */
1790 function assertNotHasOwnProperty(name, context) {
1791   if (name === 'hasOwnProperty') {
1792     throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context);
1793   }
1794 }
1795
1796 /**
1797  * Return the value accessible from the object by path. Any undefined traversals are ignored
1798  * @param {Object} obj starting object
1799  * @param {String} path path to traverse
1800  * @param {boolean} [bindFnToScope=true]
1801  * @returns {Object} value as accessible by path
1802  */
1803 //TODO(misko): this function needs to be removed
1804 function getter(obj, path, bindFnToScope) {
1805   if (!path) return obj;
1806   var keys = path.split('.');
1807   var key;
1808   var lastInstance = obj;
1809   var len = keys.length;
1810
1811   for (var i = 0; i < len; i++) {
1812     key = keys[i];
1813     if (obj) {
1814       obj = (lastInstance = obj)[key];
1815     }
1816   }
1817   if (!bindFnToScope && isFunction(obj)) {
1818     return bind(lastInstance, obj);
1819   }
1820   return obj;
1821 }
1822
1823 /**
1824  * Return the DOM siblings between the first and last node in the given array.
1825  * @param {Array} array like object
1826  * @returns {jqLite} jqLite collection containing the nodes
1827  */
1828 function getBlockNodes(nodes) {
1829   // TODO(perf): just check if all items in `nodes` are siblings and if they are return the original
1830   //             collection, otherwise update the original collection.
1831   var node = nodes[0];
1832   var endNode = nodes[nodes.length - 1];
1833   var blockNodes = [node];
1834
1835   do {
1836     node = node.nextSibling;
1837     if (!node) break;
1838     blockNodes.push(node);
1839   } while (node !== endNode);
1840
1841   return jqLite(blockNodes);
1842 }
1843
1844
1845 /**
1846  * Creates a new object without a prototype. This object is useful for lookup without having to
1847  * guard against prototypically inherited properties via hasOwnProperty.
1848  *
1849  * Related micro-benchmarks:
1850  * - http://jsperf.com/object-create2
1851  * - http://jsperf.com/proto-map-lookup/2
1852  * - http://jsperf.com/for-in-vs-object-keys2
1853  *
1854  * @returns {Object}
1855  */
1856 function createMap() {
1857   return Object.create(null);
1858 }
1859
1860 var NODE_TYPE_ELEMENT = 1;
1861 var NODE_TYPE_ATTRIBUTE = 2;
1862 var NODE_TYPE_TEXT = 3;
1863 var NODE_TYPE_COMMENT = 8;
1864 var NODE_TYPE_DOCUMENT = 9;
1865 var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
1866
1867 /**
1868  * @ngdoc type
1869  * @name angular.Module
1870  * @module ng
1871  * @description
1872  *
1873  * Interface for configuring angular {@link angular.module modules}.
1874  */
1875
1876 function setupModuleLoader(window) {
1877
1878   var $injectorMinErr = minErr('$injector');
1879   var ngMinErr = minErr('ng');
1880
1881   function ensure(obj, name, factory) {
1882     return obj[name] || (obj[name] = factory());
1883   }
1884
1885   var angular = ensure(window, 'angular', Object);
1886
1887   // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
1888   angular.$$minErr = angular.$$minErr || minErr;
1889
1890   return ensure(angular, 'module', function() {
1891     /** @type {Object.<string, angular.Module>} */
1892     var modules = {};
1893
1894     /**
1895      * @ngdoc function
1896      * @name angular.module
1897      * @module ng
1898      * @description
1899      *
1900      * The `angular.module` is a global place for creating, registering and retrieving Angular
1901      * modules.
1902      * All modules (angular core or 3rd party) that should be available to an application must be
1903      * registered using this mechanism.
1904      *
1905      * When passed two or more arguments, a new module is created.  If passed only one argument, an
1906      * existing module (the name passed as the first argument to `module`) is retrieved.
1907      *
1908      *
1909      * # Module
1910      *
1911      * A module is a collection of services, directives, controllers, filters, and configuration information.
1912      * `angular.module` is used to configure the {@link auto.$injector $injector}.
1913      *
1914      * ```js
1915      * // Create a new module
1916      * var myModule = angular.module('myModule', []);
1917      *
1918      * // register a new service
1919      * myModule.value('appName', 'MyCoolApp');
1920      *
1921      * // configure existing services inside initialization blocks.
1922      * myModule.config(['$locationProvider', function($locationProvider) {
1923      *   // Configure existing providers
1924      *   $locationProvider.hashPrefix('!');
1925      * }]);
1926      * ```
1927      *
1928      * Then you can create an injector and load your modules like this:
1929      *
1930      * ```js
1931      * var injector = angular.injector(['ng', 'myModule'])
1932      * ```
1933      *
1934      * However it's more likely that you'll just use
1935      * {@link ng.directive:ngApp ngApp} or
1936      * {@link angular.bootstrap} to simplify this process for you.
1937      *
1938      * @param {!string} name The name of the module to create or retrieve.
1939      * @param {!Array.<string>=} requires If specified then new module is being created. If
1940      *        unspecified then the module is being retrieved for further configuration.
1941      * @param {Function=} configFn Optional configuration function for the module. Same as
1942      *        {@link angular.Module#config Module#config()}.
1943      * @returns {module} new module with the {@link angular.Module} api.
1944      */
1945     return function module(name, requires, configFn) {
1946       var assertNotHasOwnProperty = function(name, context) {
1947         if (name === 'hasOwnProperty') {
1948           throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
1949         }
1950       };
1951
1952       assertNotHasOwnProperty(name, 'module');
1953       if (requires && modules.hasOwnProperty(name)) {
1954         modules[name] = null;
1955       }
1956       return ensure(modules, name, function() {
1957         if (!requires) {
1958           throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
1959              "the module name or forgot to load it. If registering a module ensure that you " +
1960              "specify the dependencies as the second argument.", name);
1961         }
1962
1963         /** @type {!Array.<Array.<*>>} */
1964         var invokeQueue = [];
1965
1966         /** @type {!Array.<Function>} */
1967         var configBlocks = [];
1968
1969         /** @type {!Array.<Function>} */
1970         var runBlocks = [];
1971
1972         var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
1973
1974         /** @type {angular.Module} */
1975         var moduleInstance = {
1976           // Private state
1977           _invokeQueue: invokeQueue,
1978           _configBlocks: configBlocks,
1979           _runBlocks: runBlocks,
1980
1981           /**
1982            * @ngdoc property
1983            * @name angular.Module#requires
1984            * @module ng
1985            *
1986            * @description
1987            * Holds the list of modules which the injector will load before the current module is
1988            * loaded.
1989            */
1990           requires: requires,
1991
1992           /**
1993            * @ngdoc property
1994            * @name angular.Module#name
1995            * @module ng
1996            *
1997            * @description
1998            * Name of the module.
1999            */
2000           name: name,
2001
2002
2003           /**
2004            * @ngdoc method
2005            * @name angular.Module#provider
2006            * @module ng
2007            * @param {string} name service name
2008            * @param {Function} providerType Construction function for creating new instance of the
2009            *                                service.
2010            * @description
2011            * See {@link auto.$provide#provider $provide.provider()}.
2012            */
2013           provider: invokeLaterAndSetModuleName('$provide', 'provider'),
2014
2015           /**
2016            * @ngdoc method
2017            * @name angular.Module#factory
2018            * @module ng
2019            * @param {string} name service name
2020            * @param {Function} providerFunction Function for creating new instance of the service.
2021            * @description
2022            * See {@link auto.$provide#factory $provide.factory()}.
2023            */
2024           factory: invokeLaterAndSetModuleName('$provide', 'factory'),
2025
2026           /**
2027            * @ngdoc method
2028            * @name angular.Module#service
2029            * @module ng
2030            * @param {string} name service name
2031            * @param {Function} constructor A constructor function that will be instantiated.
2032            * @description
2033            * See {@link auto.$provide#service $provide.service()}.
2034            */
2035           service: invokeLaterAndSetModuleName('$provide', 'service'),
2036
2037           /**
2038            * @ngdoc method
2039            * @name angular.Module#value
2040            * @module ng
2041            * @param {string} name service name
2042            * @param {*} object Service instance object.
2043            * @description
2044            * See {@link auto.$provide#value $provide.value()}.
2045            */
2046           value: invokeLater('$provide', 'value'),
2047
2048           /**
2049            * @ngdoc method
2050            * @name angular.Module#constant
2051            * @module ng
2052            * @param {string} name constant name
2053            * @param {*} object Constant value.
2054            * @description
2055            * Because the constant are fixed, they get applied before other provide methods.
2056            * See {@link auto.$provide#constant $provide.constant()}.
2057            */
2058           constant: invokeLater('$provide', 'constant', 'unshift'),
2059
2060            /**
2061            * @ngdoc method
2062            * @name angular.Module#decorator
2063            * @module ng
2064            * @param {string} The name of the service to decorate.
2065            * @param {Function} This function will be invoked when the service needs to be
2066            *                                    instantiated and should return the decorated service instance.
2067            * @description
2068            * See {@link auto.$provide#decorator $provide.decorator()}.
2069            */
2070           decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
2071
2072           /**
2073            * @ngdoc method
2074            * @name angular.Module#animation
2075            * @module ng
2076            * @param {string} name animation name
2077            * @param {Function} animationFactory Factory function for creating new instance of an
2078            *                                    animation.
2079            * @description
2080            *
2081            * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
2082            *
2083            *
2084            * Defines an animation hook that can be later used with
2085            * {@link $animate $animate} service and directives that use this service.
2086            *
2087            * ```js
2088            * module.animation('.animation-name', function($inject1, $inject2) {
2089            *   return {
2090            *     eventName : function(element, done) {
2091            *       //code to run the animation
2092            *       //once complete, then run done()
2093            *       return function cancellationFunction(element) {
2094            *         //code to cancel the animation
2095            *       }
2096            *     }
2097            *   }
2098            * })
2099            * ```
2100            *
2101            * See {@link ng.$animateProvider#register $animateProvider.register()} and
2102            * {@link ngAnimate ngAnimate module} for more information.
2103            */
2104           animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
2105
2106           /**
2107            * @ngdoc method
2108            * @name angular.Module#filter
2109            * @module ng
2110            * @param {string} name Filter name - this must be a valid angular expression identifier
2111            * @param {Function} filterFactory Factory function for creating new instance of filter.
2112            * @description
2113            * See {@link ng.$filterProvider#register $filterProvider.register()}.
2114            *
2115            * <div class="alert alert-warning">
2116            * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
2117            * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
2118            * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
2119            * (`myapp_subsection_filterx`).
2120            * </div>
2121            */
2122           filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
2123
2124           /**
2125            * @ngdoc method
2126            * @name angular.Module#controller
2127            * @module ng
2128            * @param {string|Object} name Controller name, or an object map of controllers where the
2129            *    keys are the names and the values are the constructors.
2130            * @param {Function} constructor Controller constructor function.
2131            * @description
2132            * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
2133            */
2134           controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
2135
2136           /**
2137            * @ngdoc method
2138            * @name angular.Module#directive
2139            * @module ng
2140            * @param {string|Object} name Directive name, or an object map of directives where the
2141            *    keys are the names and the values are the factories.
2142            * @param {Function} directiveFactory Factory function for creating new instance of
2143            * directives.
2144            * @description
2145            * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
2146            */
2147           directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
2148
2149           /**
2150            * @ngdoc method
2151            * @name angular.Module#config
2152            * @module ng
2153            * @param {Function} configFn Execute this function on module load. Useful for service
2154            *    configuration.
2155            * @description
2156            * Use this method to register work which needs to be performed on module loading.
2157            * For more about how to configure services, see
2158            * {@link providers#provider-recipe Provider Recipe}.
2159            */
2160           config: config,
2161
2162           /**
2163            * @ngdoc method
2164            * @name angular.Module#run
2165            * @module ng
2166            * @param {Function} initializationFn Execute this function after injector creation.
2167            *    Useful for application initialization.
2168            * @description
2169            * Use this method to register work which should be performed when the injector is done
2170            * loading all modules.
2171            */
2172           run: function(block) {
2173             runBlocks.push(block);
2174             return this;
2175           }
2176         };
2177
2178         if (configFn) {
2179           config(configFn);
2180         }
2181
2182         return moduleInstance;
2183
2184         /**
2185          * @param {string} provider
2186          * @param {string} method
2187          * @param {String=} insertMethod
2188          * @returns {angular.Module}
2189          */
2190         function invokeLater(provider, method, insertMethod, queue) {
2191           if (!queue) queue = invokeQueue;
2192           return function() {
2193             queue[insertMethod || 'push']([provider, method, arguments]);
2194             return moduleInstance;
2195           };
2196         }
2197
2198         /**
2199          * @param {string} provider
2200          * @param {string} method
2201          * @returns {angular.Module}
2202          */
2203         function invokeLaterAndSetModuleName(provider, method) {
2204           return function(recipeName, factoryFunction) {
2205             if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
2206             invokeQueue.push([provider, method, arguments]);
2207             return moduleInstance;
2208           };
2209         }
2210       });
2211     };
2212   });
2213
2214 }
2215
2216 /* global: toDebugString: true */
2217
2218 function serializeObject(obj) {
2219   var seen = [];
2220
2221   return JSON.stringify(obj, function(key, val) {
2222     val = toJsonReplacer(key, val);
2223     if (isObject(val)) {
2224
2225       if (seen.indexOf(val) >= 0) return '<<already seen>>';
2226
2227       seen.push(val);
2228     }
2229     return val;
2230   });
2231 }
2232
2233 function toDebugString(obj) {
2234   if (typeof obj === 'function') {
2235     return obj.toString().replace(/ \{[\s\S]*$/, '');
2236   } else if (typeof obj === 'undefined') {
2237     return 'undefined';
2238   } else if (typeof obj !== 'string') {
2239     return serializeObject(obj);
2240   }
2241   return obj;
2242 }
2243
2244 /* global angularModule: true,
2245   version: true,
2246
2247   $LocaleProvider,
2248   $CompileProvider,
2249
2250   htmlAnchorDirective,
2251   inputDirective,
2252   inputDirective,
2253   formDirective,
2254   scriptDirective,
2255   selectDirective,
2256   styleDirective,
2257   optionDirective,
2258   ngBindDirective,
2259   ngBindHtmlDirective,
2260   ngBindTemplateDirective,
2261   ngClassDirective,
2262   ngClassEvenDirective,
2263   ngClassOddDirective,
2264   ngCspDirective,
2265   ngCloakDirective,
2266   ngControllerDirective,
2267   ngFormDirective,
2268   ngHideDirective,
2269   ngIfDirective,
2270   ngIncludeDirective,
2271   ngIncludeFillContentDirective,
2272   ngInitDirective,
2273   ngNonBindableDirective,
2274   ngPluralizeDirective,
2275   ngRepeatDirective,
2276   ngShowDirective,
2277   ngStyleDirective,
2278   ngSwitchDirective,
2279   ngSwitchWhenDirective,
2280   ngSwitchDefaultDirective,
2281   ngOptionsDirective,
2282   ngTranscludeDirective,
2283   ngModelDirective,
2284   ngListDirective,
2285   ngChangeDirective,
2286   patternDirective,
2287   patternDirective,
2288   requiredDirective,
2289   requiredDirective,
2290   minlengthDirective,
2291   minlengthDirective,
2292   maxlengthDirective,
2293   maxlengthDirective,
2294   ngValueDirective,
2295   ngModelOptionsDirective,
2296   ngAttributeAliasDirectives,
2297   ngEventDirectives,
2298
2299   $AnchorScrollProvider,
2300   $AnimateProvider,
2301   $$CoreAnimateQueueProvider,
2302   $$CoreAnimateRunnerProvider,
2303   $BrowserProvider,
2304   $CacheFactoryProvider,
2305   $ControllerProvider,
2306   $DocumentProvider,
2307   $ExceptionHandlerProvider,
2308   $FilterProvider,
2309   $InterpolateProvider,
2310   $IntervalProvider,
2311   $$HashMapProvider,
2312   $HttpProvider,
2313   $HttpParamSerializerProvider,
2314   $HttpParamSerializerJQLikeProvider,
2315   $HttpBackendProvider,
2316   $LocationProvider,
2317   $LogProvider,
2318   $ParseProvider,
2319   $RootScopeProvider,
2320   $QProvider,
2321   $$QProvider,
2322   $$SanitizeUriProvider,
2323   $SceProvider,
2324   $SceDelegateProvider,
2325   $SnifferProvider,
2326   $TemplateCacheProvider,
2327   $TemplateRequestProvider,
2328   $$TestabilityProvider,
2329   $TimeoutProvider,
2330   $$RAFProvider,
2331   $WindowProvider,
2332   $$jqLiteProvider,
2333   $$CookieReaderProvider
2334 */
2335
2336
2337 /**
2338  * @ngdoc object
2339  * @name angular.version
2340  * @module ng
2341  * @description
2342  * An object that contains information about the current AngularJS version. This object has the
2343  * following properties:
2344  *
2345  * - `full` – `{string}` – Full version string, such as "0.9.18".
2346  * - `major` – `{number}` – Major version number, such as "0".
2347  * - `minor` – `{number}` – Minor version number, such as "9".
2348  * - `dot` – `{number}` – Dot version number, such as "18".
2349  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2350  */
2351 var version = {
2352   full: '1.4.3',    // all of these placeholder strings will be replaced by grunt's
2353   major: 1,    // package task
2354   minor: 4,
2355   dot: 3,
2356   codeName: 'foam-acceleration'
2357 };
2358
2359
2360 function publishExternalAPI(angular) {
2361   extend(angular, {
2362     'bootstrap': bootstrap,
2363     'copy': copy,
2364     'extend': extend,
2365     'merge': merge,
2366     'equals': equals,
2367     'element': jqLite,
2368     'forEach': forEach,
2369     'injector': createInjector,
2370     'noop': noop,
2371     'bind': bind,
2372     'toJson': toJson,
2373     'fromJson': fromJson,
2374     'identity': identity,
2375     'isUndefined': isUndefined,
2376     'isDefined': isDefined,
2377     'isString': isString,
2378     'isFunction': isFunction,
2379     'isObject': isObject,
2380     'isNumber': isNumber,
2381     'isElement': isElement,
2382     'isArray': isArray,
2383     'version': version,
2384     'isDate': isDate,
2385     'lowercase': lowercase,
2386     'uppercase': uppercase,
2387     'callbacks': {counter: 0},
2388     'getTestability': getTestability,
2389     '$$minErr': minErr,
2390     '$$csp': csp,
2391     'reloadWithDebugInfo': reloadWithDebugInfo
2392   });
2393
2394   angularModule = setupModuleLoader(window);
2395   try {
2396     angularModule('ngLocale');
2397   } catch (e) {
2398     angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
2399   }
2400
2401   angularModule('ng', ['ngLocale'], ['$provide',
2402     function ngModule($provide) {
2403       // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
2404       $provide.provider({
2405         $$sanitizeUri: $$SanitizeUriProvider
2406       });
2407       $provide.provider('$compile', $CompileProvider).
2408         directive({
2409             a: htmlAnchorDirective,
2410             input: inputDirective,
2411             textarea: inputDirective,
2412             form: formDirective,
2413             script: scriptDirective,
2414             select: selectDirective,
2415             style: styleDirective,
2416             option: optionDirective,
2417             ngBind: ngBindDirective,
2418             ngBindHtml: ngBindHtmlDirective,
2419             ngBindTemplate: ngBindTemplateDirective,
2420             ngClass: ngClassDirective,
2421             ngClassEven: ngClassEvenDirective,
2422             ngClassOdd: ngClassOddDirective,
2423             ngCloak: ngCloakDirective,
2424             ngController: ngControllerDirective,
2425             ngForm: ngFormDirective,
2426             ngHide: ngHideDirective,
2427             ngIf: ngIfDirective,
2428             ngInclude: ngIncludeDirective,
2429             ngInit: ngInitDirective,
2430             ngNonBindable: ngNonBindableDirective,
2431             ngPluralize: ngPluralizeDirective,
2432             ngRepeat: ngRepeatDirective,
2433             ngShow: ngShowDirective,
2434             ngStyle: ngStyleDirective,
2435             ngSwitch: ngSwitchDirective,
2436             ngSwitchWhen: ngSwitchWhenDirective,
2437             ngSwitchDefault: ngSwitchDefaultDirective,
2438             ngOptions: ngOptionsDirective,
2439             ngTransclude: ngTranscludeDirective,
2440             ngModel: ngModelDirective,
2441             ngList: ngListDirective,
2442             ngChange: ngChangeDirective,
2443             pattern: patternDirective,
2444             ngPattern: patternDirective,
2445             required: requiredDirective,
2446             ngRequired: requiredDirective,
2447             minlength: minlengthDirective,
2448             ngMinlength: minlengthDirective,
2449             maxlength: maxlengthDirective,
2450             ngMaxlength: maxlengthDirective,
2451             ngValue: ngValueDirective,
2452             ngModelOptions: ngModelOptionsDirective
2453         }).
2454         directive({
2455           ngInclude: ngIncludeFillContentDirective
2456         }).
2457         directive(ngAttributeAliasDirectives).
2458         directive(ngEventDirectives);
2459       $provide.provider({
2460         $anchorScroll: $AnchorScrollProvider,
2461         $animate: $AnimateProvider,
2462         $$animateQueue: $$CoreAnimateQueueProvider,
2463         $$AnimateRunner: $$CoreAnimateRunnerProvider,
2464         $browser: $BrowserProvider,
2465         $cacheFactory: $CacheFactoryProvider,
2466         $controller: $ControllerProvider,
2467         $document: $DocumentProvider,
2468         $exceptionHandler: $ExceptionHandlerProvider,
2469         $filter: $FilterProvider,
2470         $interpolate: $InterpolateProvider,
2471         $interval: $IntervalProvider,
2472         $http: $HttpProvider,
2473         $httpParamSerializer: $HttpParamSerializerProvider,
2474         $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
2475         $httpBackend: $HttpBackendProvider,
2476         $location: $LocationProvider,
2477         $log: $LogProvider,
2478         $parse: $ParseProvider,
2479         $rootScope: $RootScopeProvider,
2480         $q: $QProvider,
2481         $$q: $$QProvider,
2482         $sce: $SceProvider,
2483         $sceDelegate: $SceDelegateProvider,
2484         $sniffer: $SnifferProvider,
2485         $templateCache: $TemplateCacheProvider,
2486         $templateRequest: $TemplateRequestProvider,
2487         $$testability: $$TestabilityProvider,
2488         $timeout: $TimeoutProvider,
2489         $window: $WindowProvider,
2490         $$rAF: $$RAFProvider,
2491         $$jqLite: $$jqLiteProvider,
2492         $$HashMap: $$HashMapProvider,
2493         $$cookieReader: $$CookieReaderProvider
2494       });
2495     }
2496   ]);
2497 }
2498
2499 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2500  *     Any commits to this file should be reviewed with security in mind.  *
2501  *   Changes to this file can potentially create security vulnerabilities. *
2502  *          An approval from 2 Core members with history of modifying      *
2503  *                         this file is required.                          *
2504  *                                                                         *
2505  *  Does the change somehow allow for arbitrary javascript to be executed? *
2506  *    Or allows for someone to change the prototype of built-in objects?   *
2507  *     Or gives undesired access to variables likes document or window?    *
2508  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2509
2510 /* global JQLitePrototype: true,
2511   addEventListenerFn: true,
2512   removeEventListenerFn: true,
2513   BOOLEAN_ATTR: true,
2514   ALIASED_ATTR: true,
2515 */
2516
2517 //////////////////////////////////
2518 //JQLite
2519 //////////////////////////////////
2520
2521 /**
2522  * @ngdoc function
2523  * @name angular.element
2524  * @module ng
2525  * @kind function
2526  *
2527  * @description
2528  * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
2529  *
2530  * If jQuery is available, `angular.element` is an alias for the
2531  * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`
2532  * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite."
2533  *
2534  * <div class="alert alert-success">jqLite is a tiny, API-compatible subset of jQuery that allows
2535  * Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most
2536  * commonly needed functionality with the goal of having a very small footprint.</div>
2537  *
2538  * To use `jQuery`, simply ensure it is loaded before the `angular.js` file.
2539  *
2540  * <div class="alert">**Note:** all element references in Angular are always wrapped with jQuery or
2541  * jqLite; they are never raw DOM references.</div>
2542  *
2543  * ## Angular's jqLite
2544  * jqLite provides only the following jQuery methods:
2545  *
2546  * - [`addClass()`](http://api.jquery.com/addClass/)
2547  * - [`after()`](http://api.jquery.com/after/)
2548  * - [`append()`](http://api.jquery.com/append/)
2549  * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
2550  * - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
2551  * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
2552  * - [`clone()`](http://api.jquery.com/clone/)
2553  * - [`contents()`](http://api.jquery.com/contents/)
2554  * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. As a setter, does not convert numbers to strings or append 'px'.
2555  * - [`data()`](http://api.jquery.com/data/)
2556  * - [`detach()`](http://api.jquery.com/detach/)
2557  * - [`empty()`](http://api.jquery.com/empty/)
2558  * - [`eq()`](http://api.jquery.com/eq/)
2559  * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name
2560  * - [`hasClass()`](http://api.jquery.com/hasClass/)
2561  * - [`html()`](http://api.jquery.com/html/)
2562  * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
2563  * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
2564  * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
2565  * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
2566  * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
2567  * - [`prepend()`](http://api.jquery.com/prepend/)
2568  * - [`prop()`](http://api.jquery.com/prop/)
2569  * - [`ready()`](http://api.jquery.com/ready/)
2570  * - [`remove()`](http://api.jquery.com/remove/)
2571  * - [`removeAttr()`](http://api.jquery.com/removeAttr/)
2572  * - [`removeClass()`](http://api.jquery.com/removeClass/)
2573  * - [`removeData()`](http://api.jquery.com/removeData/)
2574  * - [`replaceWith()`](http://api.jquery.com/replaceWith/)
2575  * - [`text()`](http://api.jquery.com/text/)
2576  * - [`toggleClass()`](http://api.jquery.com/toggleClass/)
2577  * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
2578  * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
2579  * - [`val()`](http://api.jquery.com/val/)
2580  * - [`wrap()`](http://api.jquery.com/wrap/)
2581  *
2582  * ## jQuery/jqLite Extras
2583  * Angular also provides the following additional methods and events to both jQuery and jqLite:
2584  *
2585  * ### Events
2586  * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
2587  *    on all DOM nodes being removed.  This can be used to clean up any 3rd party bindings to the DOM
2588  *    element before it is removed.
2589  *
2590  * ### Methods
2591  * - `controller(name)` - retrieves the controller of the current element or its parent. By default
2592  *   retrieves controller associated with the `ngController` directive. If `name` is provided as
2593  *   camelCase directive name, then the controller for this directive will be retrieved (e.g.
2594  *   `'ngModel'`).
2595  * - `injector()` - retrieves the injector of the current element or its parent.
2596  * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
2597  *   element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
2598  *   be enabled.
2599  * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
2600  *   current element. This getter should be used only on elements that contain a directive which starts a new isolate
2601  *   scope. Calling `scope()` on this element always returns the original non-isolate scope.
2602  *   Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
2603  * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
2604  *   parent element is reached.
2605  *
2606  * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
2607  * @returns {Object} jQuery object.
2608  */
2609
2610 JQLite.expando = 'ng339';
2611
2612 var jqCache = JQLite.cache = {},
2613     jqId = 1,
2614     addEventListenerFn = function(element, type, fn) {
2615       element.addEventListener(type, fn, false);
2616     },
2617     removeEventListenerFn = function(element, type, fn) {
2618       element.removeEventListener(type, fn, false);
2619     };
2620
2621 /*
2622  * !!! This is an undocumented "private" function !!!
2623  */
2624 JQLite._data = function(node) {
2625   //jQuery always returns an object on cache miss
2626   return this.cache[node[this.expando]] || {};
2627 };
2628
2629 function jqNextId() { return ++jqId; }
2630
2631
2632 var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
2633 var MOZ_HACK_REGEXP = /^moz([A-Z])/;
2634 var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"};
2635 var jqLiteMinErr = minErr('jqLite');
2636
2637 /**
2638  * Converts snake_case to camelCase.
2639  * Also there is special case for Moz prefix starting with upper case letter.
2640  * @param name Name to normalize
2641  */
2642 function camelCase(name) {
2643   return name.
2644     replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
2645       return offset ? letter.toUpperCase() : letter;
2646     }).
2647     replace(MOZ_HACK_REGEXP, 'Moz$1');
2648 }
2649
2650 var SINGLE_TAG_REGEXP = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;
2651 var HTML_REGEXP = /<|&#?\w+;/;
2652 var TAG_NAME_REGEXP = /<([\w:]+)/;
2653 var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi;
2654
2655 var wrapMap = {
2656   'option': [1, '<select multiple="multiple">', '</select>'],
2657
2658   'thead': [1, '<table>', '</table>'],
2659   'col': [2, '<table><colgroup>', '</colgroup></table>'],
2660   'tr': [2, '<table><tbody>', '</tbody></table>'],
2661   'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
2662   '_default': [0, "", ""]
2663 };
2664
2665 wrapMap.optgroup = wrapMap.option;
2666 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
2667 wrapMap.th = wrapMap.td;
2668
2669
2670 function jqLiteIsTextNode(html) {
2671   return !HTML_REGEXP.test(html);
2672 }
2673
2674 function jqLiteAcceptsData(node) {
2675   // The window object can accept data but has no nodeType
2676   // Otherwise we are only interested in elements (1) and documents (9)
2677   var nodeType = node.nodeType;
2678   return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
2679 }
2680
2681 function jqLiteHasData(node) {
2682   for (var key in jqCache[node.ng339]) {
2683     return true;
2684   }
2685   return false;
2686 }
2687
2688 function jqLiteBuildFragment(html, context) {
2689   var tmp, tag, wrap,
2690       fragment = context.createDocumentFragment(),
2691       nodes = [], i;
2692
2693   if (jqLiteIsTextNode(html)) {
2694     // Convert non-html into a text node
2695     nodes.push(context.createTextNode(html));
2696   } else {
2697     // Convert html into DOM nodes
2698     tmp = tmp || fragment.appendChild(context.createElement("div"));
2699     tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
2700     wrap = wrapMap[tag] || wrapMap._default;
2701     tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1></$2>") + wrap[2];
2702
2703     // Descend through wrappers to the right content
2704     i = wrap[0];
2705     while (i--) {
2706       tmp = tmp.lastChild;
2707     }
2708
2709     nodes = concat(nodes, tmp.childNodes);
2710
2711     tmp = fragment.firstChild;
2712     tmp.textContent = "";
2713   }
2714
2715   // Remove wrapper from fragment
2716   fragment.textContent = "";
2717   fragment.innerHTML = ""; // Clear inner HTML
2718   forEach(nodes, function(node) {
2719     fragment.appendChild(node);
2720   });
2721
2722   return fragment;
2723 }
2724
2725 function jqLiteParseHTML(html, context) {
2726   context = context || document;
2727   var parsed;
2728
2729   if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
2730     return [context.createElement(parsed[1])];
2731   }
2732
2733   if ((parsed = jqLiteBuildFragment(html, context))) {
2734     return parsed.childNodes;
2735   }
2736
2737   return [];
2738 }
2739
2740 /////////////////////////////////////////////
2741 function JQLite(element) {
2742   if (element instanceof JQLite) {
2743     return element;
2744   }
2745
2746   var argIsString;
2747
2748   if (isString(element)) {
2749     element = trim(element);
2750     argIsString = true;
2751   }
2752   if (!(this instanceof JQLite)) {
2753     if (argIsString && element.charAt(0) != '<') {
2754       throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
2755     }
2756     return new JQLite(element);
2757   }
2758
2759   if (argIsString) {
2760     jqLiteAddNodes(this, jqLiteParseHTML(element));
2761   } else {
2762     jqLiteAddNodes(this, element);
2763   }
2764 }
2765
2766 function jqLiteClone(element) {
2767   return element.cloneNode(true);
2768 }
2769
2770 function jqLiteDealoc(element, onlyDescendants) {
2771   if (!onlyDescendants) jqLiteRemoveData(element);
2772
2773   if (element.querySelectorAll) {
2774     var descendants = element.querySelectorAll('*');
2775     for (var i = 0, l = descendants.length; i < l; i++) {
2776       jqLiteRemoveData(descendants[i]);
2777     }
2778   }
2779 }
2780
2781 function jqLiteOff(element, type, fn, unsupported) {
2782   if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
2783
2784   var expandoStore = jqLiteExpandoStore(element);
2785   var events = expandoStore && expandoStore.events;
2786   var handle = expandoStore && expandoStore.handle;
2787
2788   if (!handle) return; //no listeners registered
2789
2790   if (!type) {
2791     for (type in events) {
2792       if (type !== '$destroy') {
2793         removeEventListenerFn(element, type, handle);
2794       }
2795       delete events[type];
2796     }
2797   } else {
2798     forEach(type.split(' '), function(type) {
2799       if (isDefined(fn)) {
2800         var listenerFns = events[type];
2801         arrayRemove(listenerFns || [], fn);
2802         if (listenerFns && listenerFns.length > 0) {
2803           return;
2804         }
2805       }
2806
2807       removeEventListenerFn(element, type, handle);
2808       delete events[type];
2809     });
2810   }
2811 }
2812
2813 function jqLiteRemoveData(element, name) {
2814   var expandoId = element.ng339;
2815   var expandoStore = expandoId && jqCache[expandoId];
2816
2817   if (expandoStore) {
2818     if (name) {
2819       delete expandoStore.data[name];
2820       return;
2821     }
2822
2823     if (expandoStore.handle) {
2824       if (expandoStore.events.$destroy) {
2825         expandoStore.handle({}, '$destroy');
2826       }
2827       jqLiteOff(element);
2828     }
2829     delete jqCache[expandoId];
2830     element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
2831   }
2832 }
2833
2834
2835 function jqLiteExpandoStore(element, createIfNecessary) {
2836   var expandoId = element.ng339,
2837       expandoStore = expandoId && jqCache[expandoId];
2838
2839   if (createIfNecessary && !expandoStore) {
2840     element.ng339 = expandoId = jqNextId();
2841     expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};
2842   }
2843
2844   return expandoStore;
2845 }
2846
2847
2848 function jqLiteData(element, key, value) {
2849   if (jqLiteAcceptsData(element)) {
2850
2851     var isSimpleSetter = isDefined(value);
2852     var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
2853     var massGetter = !key;
2854     var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
2855     var data = expandoStore && expandoStore.data;
2856
2857     if (isSimpleSetter) { // data('key', value)
2858       data[key] = value;
2859     } else {
2860       if (massGetter) {  // data()
2861         return data;
2862       } else {
2863         if (isSimpleGetter) { // data('key')
2864           // don't force creation of expandoStore if it doesn't exist yet
2865           return data && data[key];
2866         } else { // mass-setter: data({key1: val1, key2: val2})
2867           extend(data, key);
2868         }
2869       }
2870     }
2871   }
2872 }
2873
2874 function jqLiteHasClass(element, selector) {
2875   if (!element.getAttribute) return false;
2876   return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
2877       indexOf(" " + selector + " ") > -1);
2878 }
2879
2880 function jqLiteRemoveClass(element, cssClasses) {
2881   if (cssClasses && element.setAttribute) {
2882     forEach(cssClasses.split(' '), function(cssClass) {
2883       element.setAttribute('class', trim(
2884           (" " + (element.getAttribute('class') || '') + " ")
2885           .replace(/[\n\t]/g, " ")
2886           .replace(" " + trim(cssClass) + " ", " "))
2887       );
2888     });
2889   }
2890 }
2891
2892 function jqLiteAddClass(element, cssClasses) {
2893   if (cssClasses && element.setAttribute) {
2894     var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
2895                             .replace(/[\n\t]/g, " ");
2896
2897     forEach(cssClasses.split(' '), function(cssClass) {
2898       cssClass = trim(cssClass);
2899       if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
2900         existingClasses += cssClass + ' ';
2901       }
2902     });
2903
2904     element.setAttribute('class', trim(existingClasses));
2905   }
2906 }
2907
2908
2909 function jqLiteAddNodes(root, elements) {
2910   // THIS CODE IS VERY HOT. Don't make changes without benchmarking.
2911
2912   if (elements) {
2913
2914     // if a Node (the most common case)
2915     if (elements.nodeType) {
2916       root[root.length++] = elements;
2917     } else {
2918       var length = elements.length;
2919
2920       // if an Array or NodeList and not a Window
2921       if (typeof length === 'number' && elements.window !== elements) {
2922         if (length) {
2923           for (var i = 0; i < length; i++) {
2924             root[root.length++] = elements[i];
2925           }
2926         }
2927       } else {
2928         root[root.length++] = elements;
2929       }
2930     }
2931   }
2932 }
2933
2934
2935 function jqLiteController(element, name) {
2936   return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
2937 }
2938
2939 function jqLiteInheritedData(element, name, value) {
2940   // if element is the document object work with the html element instead
2941   // this makes $(document).scope() possible
2942   if (element.nodeType == NODE_TYPE_DOCUMENT) {
2943     element = element.documentElement;
2944   }
2945   var names = isArray(name) ? name : [name];
2946
2947   while (element) {
2948     for (var i = 0, ii = names.length; i < ii; i++) {
2949       if ((value = jqLite.data(element, names[i])) !== undefined) return value;
2950     }
2951
2952     // If dealing with a document fragment node with a host element, and no parent, use the host
2953     // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
2954     // to lookup parent controllers.
2955     element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
2956   }
2957 }
2958
2959 function jqLiteEmpty(element) {
2960   jqLiteDealoc(element, true);
2961   while (element.firstChild) {
2962     element.removeChild(element.firstChild);
2963   }
2964 }
2965
2966 function jqLiteRemove(element, keepData) {
2967   if (!keepData) jqLiteDealoc(element);
2968   var parent = element.parentNode;
2969   if (parent) parent.removeChild(element);
2970 }
2971
2972
2973 function jqLiteDocumentLoaded(action, win) {
2974   win = win || window;
2975   if (win.document.readyState === 'complete') {
2976     // Force the action to be run async for consistent behaviour
2977     // from the action's point of view
2978     // i.e. it will definitely not be in a $apply
2979     win.setTimeout(action);
2980   } else {
2981     // No need to unbind this handler as load is only ever called once
2982     jqLite(win).on('load', action);
2983   }
2984 }
2985
2986 //////////////////////////////////////////
2987 // Functions which are declared directly.
2988 //////////////////////////////////////////
2989 var JQLitePrototype = JQLite.prototype = {
2990   ready: function(fn) {
2991     var fired = false;
2992
2993     function trigger() {
2994       if (fired) return;
2995       fired = true;
2996       fn();
2997     }
2998
2999     // check if document is already loaded
3000     if (document.readyState === 'complete') {
3001       setTimeout(trigger);
3002     } else {
3003       this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
3004       // we can not use jqLite since we are not done loading and jQuery could be loaded later.
3005       // jshint -W064
3006       JQLite(window).on('load', trigger); // fallback to window.onload for others
3007       // jshint +W064
3008     }
3009   },
3010   toString: function() {
3011     var value = [];
3012     forEach(this, function(e) { value.push('' + e);});
3013     return '[' + value.join(', ') + ']';
3014   },
3015
3016   eq: function(index) {
3017       return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
3018   },
3019
3020   length: 0,
3021   push: push,
3022   sort: [].sort,
3023   splice: [].splice
3024 };
3025
3026 //////////////////////////////////////////
3027 // Functions iterating getter/setters.
3028 // these functions return self on setter and
3029 // value on get.
3030 //////////////////////////////////////////
3031 var BOOLEAN_ATTR = {};
3032 forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
3033   BOOLEAN_ATTR[lowercase(value)] = value;
3034 });
3035 var BOOLEAN_ELEMENTS = {};
3036 forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
3037   BOOLEAN_ELEMENTS[value] = true;
3038 });
3039 var ALIASED_ATTR = {
3040   'ngMinlength': 'minlength',
3041   'ngMaxlength': 'maxlength',
3042   'ngMin': 'min',
3043   'ngMax': 'max',
3044   'ngPattern': 'pattern'
3045 };
3046
3047 function getBooleanAttrName(element, name) {
3048   // check dom last since we will most likely fail on name
3049   var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
3050
3051   // booleanAttr is here twice to minimize DOM access
3052   return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
3053 }
3054
3055 function getAliasedAttrName(element, name) {
3056   var nodeName = element.nodeName;
3057   return (nodeName === 'INPUT' || nodeName === 'TEXTAREA') && ALIASED_ATTR[name];
3058 }
3059
3060 forEach({
3061   data: jqLiteData,
3062   removeData: jqLiteRemoveData,
3063   hasData: jqLiteHasData
3064 }, function(fn, name) {
3065   JQLite[name] = fn;
3066 });
3067
3068 forEach({
3069   data: jqLiteData,
3070   inheritedData: jqLiteInheritedData,
3071
3072   scope: function(element) {
3073     // Can't use jqLiteData here directly so we stay compatible with jQuery!
3074     return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
3075   },
3076
3077   isolateScope: function(element) {
3078     // Can't use jqLiteData here directly so we stay compatible with jQuery!
3079     return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
3080   },
3081
3082   controller: jqLiteController,
3083
3084   injector: function(element) {
3085     return jqLiteInheritedData(element, '$injector');
3086   },
3087
3088   removeAttr: function(element, name) {
3089     element.removeAttribute(name);
3090   },
3091
3092   hasClass: jqLiteHasClass,
3093
3094   css: function(element, name, value) {
3095     name = camelCase(name);
3096
3097     if (isDefined(value)) {
3098       element.style[name] = value;
3099     } else {
3100       return element.style[name];
3101     }
3102   },
3103
3104   attr: function(element, name, value) {
3105     var nodeType = element.nodeType;
3106     if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) {
3107       return;
3108     }
3109     var lowercasedName = lowercase(name);
3110     if (BOOLEAN_ATTR[lowercasedName]) {
3111       if (isDefined(value)) {
3112         if (!!value) {
3113           element[name] = true;
3114           element.setAttribute(name, lowercasedName);
3115         } else {
3116           element[name] = false;
3117           element.removeAttribute(lowercasedName);
3118         }
3119       } else {
3120         return (element[name] ||
3121                  (element.attributes.getNamedItem(name) || noop).specified)
3122                ? lowercasedName
3123                : undefined;
3124       }
3125     } else if (isDefined(value)) {
3126       element.setAttribute(name, value);
3127     } else if (element.getAttribute) {
3128       // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code
3129       // some elements (e.g. Document) don't have get attribute, so return undefined
3130       var ret = element.getAttribute(name, 2);
3131       // normalize non-existing attributes to undefined (as jQuery)
3132       return ret === null ? undefined : ret;
3133     }
3134   },
3135
3136   prop: function(element, name, value) {
3137     if (isDefined(value)) {
3138       element[name] = value;
3139     } else {
3140       return element[name];
3141     }
3142   },
3143
3144   text: (function() {
3145     getText.$dv = '';
3146     return getText;
3147
3148     function getText(element, value) {
3149       if (isUndefined(value)) {
3150         var nodeType = element.nodeType;
3151         return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
3152       }
3153       element.textContent = value;
3154     }
3155   })(),
3156
3157   val: function(element, value) {
3158     if (isUndefined(value)) {
3159       if (element.multiple && nodeName_(element) === 'select') {
3160         var result = [];
3161         forEach(element.options, function(option) {
3162           if (option.selected) {
3163             result.push(option.value || option.text);
3164           }
3165         });
3166         return result.length === 0 ? null : result;
3167       }
3168       return element.value;
3169     }
3170     element.value = value;
3171   },
3172
3173   html: function(element, value) {
3174     if (isUndefined(value)) {
3175       return element.innerHTML;
3176     }
3177     jqLiteDealoc(element, true);
3178     element.innerHTML = value;
3179   },
3180
3181   empty: jqLiteEmpty
3182 }, function(fn, name) {
3183   /**
3184    * Properties: writes return selection, reads return first value
3185    */
3186   JQLite.prototype[name] = function(arg1, arg2) {
3187     var i, key;
3188     var nodeCount = this.length;
3189
3190     // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
3191     // in a way that survives minification.
3192     // jqLiteEmpty takes no arguments but is a setter.
3193     if (fn !== jqLiteEmpty &&
3194         (((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2) === undefined)) {
3195       if (isObject(arg1)) {
3196
3197         // we are a write, but the object properties are the key/values
3198         for (i = 0; i < nodeCount; i++) {
3199           if (fn === jqLiteData) {
3200             // data() takes the whole object in jQuery
3201             fn(this[i], arg1);
3202           } else {
3203             for (key in arg1) {
3204               fn(this[i], key, arg1[key]);
3205             }
3206           }
3207         }
3208         // return self for chaining
3209         return this;
3210       } else {
3211         // we are a read, so read the first child.
3212         // TODO: do we still need this?
3213         var value = fn.$dv;
3214         // Only if we have $dv do we iterate over all, otherwise it is just the first element.
3215         var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount;
3216         for (var j = 0; j < jj; j++) {
3217           var nodeValue = fn(this[j], arg1, arg2);
3218           value = value ? value + nodeValue : nodeValue;
3219         }
3220         return value;
3221       }
3222     } else {
3223       // we are a write, so apply to all children
3224       for (i = 0; i < nodeCount; i++) {
3225         fn(this[i], arg1, arg2);
3226       }
3227       // return self for chaining
3228       return this;
3229     }
3230   };
3231 });
3232
3233 function createEventHandler(element, events) {
3234   var eventHandler = function(event, type) {
3235     // jQuery specific api
3236     event.isDefaultPrevented = function() {
3237       return event.defaultPrevented;
3238     };
3239
3240     var eventFns = events[type || event.type];
3241     var eventFnsLength = eventFns ? eventFns.length : 0;
3242
3243     if (!eventFnsLength) return;
3244
3245     if (isUndefined(event.immediatePropagationStopped)) {
3246       var originalStopImmediatePropagation = event.stopImmediatePropagation;
3247       event.stopImmediatePropagation = function() {
3248         event.immediatePropagationStopped = true;
3249
3250         if (event.stopPropagation) {
3251           event.stopPropagation();