/** * @license AngularJS v1.6.4 * (c) 2010-2017 Google, Inc. http://angularjs.org * License: MIT */ (function(window) { 'use strict'; /** * @description * * This object provides a utility for producing rich Error messages within * Angular. It can be called as follows: * * var exampleMinErr = minErr('example'); * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); * * The above creates an instance of minErr in the example namespace. The * resulting error will have a namespaced error code of example.one. The * resulting error will replace {0} with the value of foo, and {1} with the * value of bar. The object is not restricted in the number of arguments it can * take. * * If fewer arguments are specified than necessary for interpolation, the extra * interpolation markers will be preserved in the final string. * * Since data will be parsed statically during a build step, some restrictions * are applied with respect to how minErr instances are created and called. * Instances should have names of the form namespaceMinErr for a minErr created * using minErr('namespace') . Error codes, namespaces and template strings * should all be static strings, not variables or general expressions. * * @param {string} module The namespace to use for the new minErr instance. * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning * error from returned function, for cases when a particular type of error is useful. * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance */ function minErr(module, ErrorConstructor) { ErrorConstructor = ErrorConstructor || Error; return function() { var code = arguments[0], template = arguments[1], message = '[' + (module ? module + ':' : '') + code + '] ', templateArgs = sliceArgs(arguments, 2).map(function(arg) { return toDebugString(arg, minErrConfig.objectMaxDepth); }), paramPrefix, i; message += template.replace(/\{\d+\}/g, function(match) { var index = +match.slice(1, -1); if (index < templateArgs.length) { return templateArgs[index]; } return match; }); message += '\nhttp://errors.angularjs.org/1.6.4/' + (module ? module + '/' : '') + code; for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]); } return new ErrorConstructor(message); }; } /* We need to tell ESLint what variables are being exported */ /* exported angular, msie, jqLite, jQuery, slice, splice, push, toString, minErrConfig, errorHandlingConfig, isValidObjectMaxDepth, ngMinErr, angularModule, uid, REGEX_STRING_REGEXP, VALIDITY_STATE_PROPERTY, lowercase, uppercase, manualLowercase, manualUppercase, nodeName_, isArrayLike, forEach, forEachSorted, reverseParams, nextUid, setHashKey, extend, toInt, inherit, merge, noop, identity, valueFn, isUndefined, isDefined, isObject, isBlankObject, isString, isNumber, isNumberNaN, isDate, isArray, isFunction, isRegExp, isWindow, isScope, isFile, isFormData, isBlob, isBoolean, isPromiseLike, trim, escapeForRegexp, isElement, makeMap, includes, arrayRemove, copy, simpleCompare, equals, csp, jq, concat, sliceArgs, bind, toJsonReplacer, toJson, fromJson, convertTimezoneToLocal, timezoneToOffset, startingTag, tryDecodeURIComponent, parseKeyValue, toKeyValue, encodeUriSegment, encodeUriQuery, angularInit, bootstrap, getTestability, snake_case, bindJQuery, assertArg, assertArgFn, assertNotHasOwnProperty, getter, getBlockNodes, hasOwnProperty, createMap, stringify, NODE_TYPE_ELEMENT, NODE_TYPE_ATTRIBUTE, NODE_TYPE_TEXT, NODE_TYPE_COMMENT, NODE_TYPE_DOCUMENT, NODE_TYPE_DOCUMENT_FRAGMENT */ //////////////////////////////////// /** * @ngdoc module * @name ng * @module ng * @installation * @description * * # ng (core module) * The ng module is loaded by default when an AngularJS application is started. The module itself * contains the essential components for an AngularJS application to function. The table below * lists a high level breakdown of each of the services/factories, filters, directives and testing * components available within this core module. * *
*/ var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/; // The name of a form control's ValidityState property. // This is used so that it's possible for internal tests to create mock ValidityStates. var VALIDITY_STATE_PROPERTY = 'validity'; var hasOwnProperty = Object.prototype.hasOwnProperty; var minErrConfig = { objectMaxDepth: 5 }; /** * @ngdoc function * @name angular.errorHandlingConfig * @module ng * @kind function * * @description * Configure several aspects of error handling in AngularJS if used as a setter or return the * current configuration if used as a getter. The following options are supported: * * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages. * * Omitted or undefined options will leave the corresponding configuration values unchanged. * * @param {Object=} config - The configuration object. May only contain the options that need to be * updated. Supported keys: * * * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a * non-positive or non-numeric value, removes the max depth limit. * Default: 5 */ function errorHandlingConfig(config) { if (isObject(config)) { if (isDefined(config.objectMaxDepth)) { minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN; } } else { return minErrConfig; } } /** * @private * @param {Number} maxDepth * @return {boolean} */ function isValidObjectMaxDepth(maxDepth) { return isNumber(maxDepth) && maxDepth > 0; } /** * @ngdoc function * @name angular.lowercase * @module ng * @kind function * * @deprecated * sinceVersion="1.5.0" * removeVersion="1.7.0" * Use [String.prototype.toLowerCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) instead. * * @description Converts the specified string to lowercase. * @param {string} string String to be converted to lowercase. * @returns {string} Lowercased string. */ var lowercase = function(string) { return isString(string) ? string.toLowerCase() : string; }; /** * @ngdoc function * @name angular.uppercase * @module ng * @kind function * * @deprecated * sinceVersion="1.5.0" * removeVersion="1.7.0" * Use [String.prototype.toUpperCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) instead. * * @description Converts the specified string to uppercase. * @param {string} string String to be converted to uppercase. * @returns {string} Uppercased string. */ var uppercase = function(string) { return isString(string) ? string.toUpperCase() : string; }; var manualLowercase = function(s) { /* eslint-disable no-bitwise */ return isString(s) ? s.replace(/[A-Z]/g, function(ch) { return String.fromCharCode(ch.charCodeAt(0) | 32); }) : s; /* eslint-enable */ }; var manualUppercase = function(s) { /* eslint-disable no-bitwise */ return isString(s) ? s.replace(/[a-z]/g, function(ch) { return String.fromCharCode(ch.charCodeAt(0) & ~32); }) : s; /* eslint-enable */ }; // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods // with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387 if ('i' !== 'I'.toLowerCase()) { lowercase = manualLowercase; uppercase = manualUppercase; } var msie, // holds major version number for IE, or NaN if UA is not IE. jqLite, // delay binding since jQuery could be loaded after us. jQuery, // delay binding slice = [].slice, splice = [].splice, push = [].push, toString = Object.prototype.toString, getPrototypeOf = Object.getPrototypeOf, ngMinErr = minErr('ng'), /** @name angular */ angular = window.angular || (window.angular = {}), angularModule, uid = 0; // Support: IE 9-11 only /** * documentMode is an IE-only property * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx */ msie = window.document.documentMode; /** * @private * @param {*} obj * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, * String ...) */ function isArrayLike(obj) { // `null`, `undefined` and `window` are not array-like if (obj == null || isWindow(obj)) return false; // arrays, strings and jQuery/jqLite objects are array like // * jqLite is either the jQuery or jqLite constructor function // * we have to check the existence of jqLite first as this method is called // via the forEach method when constructing the jqLite object in the first place if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true; // Support: iOS 8.2 (not reproducible in simulator) // "length" in obj used to prevent JIT error (gh-11508) var length = 'length' in Object(obj) && obj.length; // NodeList objects (with `item` method) and // other objects with suitable length characteristics are array-like return isNumber(length) && (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function'); } /** * @ngdoc function * @name angular.forEach * @module ng * @kind function * * @description * Invokes the `iterator` function once for each item in `obj` collection, which can be either an * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value` * is the value of an object property or an array element, `key` is the object property key or * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional. * * It is worth noting that `.forEach` does not iterate over inherited properties because it filters * using the `hasOwnProperty` method. * * Unlike ES262's * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18), * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just * return the value provided. * ```js var values = {name: 'misko', gender: 'male'}; var log = []; angular.forEach(values, function(value, key) { this.push(key + ': ' + value); }, log); expect(log).toEqual(['name: misko', 'gender: male']); ``` * * @param {Object|Array} obj Object to iterate over. * @param {Function} iterator Iterator function. * @param {Object=} context Object to become context (`this`) for the iterator function. * @returns {Object|Array} Reference to `obj`. */ function forEach(obj, iterator, context) { var key, length; if (obj) { if (isFunction(obj)) { for (key in obj) { if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) { iterator.call(context, obj[key], key, obj); } } } else if (isArray(obj) || isArrayLike(obj)) { var isPrimitive = typeof obj !== 'object'; for (key = 0, length = obj.length; key < length; key++) { if (isPrimitive || key in obj) { iterator.call(context, obj[key], key, obj); } } } else if (obj.forEach && obj.forEach !== forEach) { obj.forEach(iterator, context, obj); } else if (isBlankObject(obj)) { // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty for (key in obj) { iterator.call(context, obj[key], key, obj); } } else if (typeof obj.hasOwnProperty === 'function') { // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed for (key in obj) { if (obj.hasOwnProperty(key)) { iterator.call(context, obj[key], key, obj); } } } else { // Slow path for objects which do not have a method `hasOwnProperty` for (key in obj) { if (hasOwnProperty.call(obj, key)) { iterator.call(context, obj[key], key, obj); } } } } return obj; } function forEachSorted(obj, iterator, context) { var keys = Object.keys(obj).sort(); for (var i = 0; i < keys.length; i++) { iterator.call(context, obj[keys[i]], keys[i]); } return keys; } /** * when using forEach the params are value, key, but it is often useful to have key, value. * @param {function(string, *)} iteratorFn * @returns {function(*, string)} */ function reverseParams(iteratorFn) { return function(value, key) { iteratorFn(key, value); }; } /** * A consistent way of creating unique IDs in angular. * * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before * we hit number precision issues in JavaScript. * * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M * * @returns {number} an unique alpha-numeric string */ function nextUid() { return ++uid; } /** * Set or clear the hashkey for an object. * @param obj object * @param h the hashkey (!truthy to delete the hashkey) */ function setHashKey(obj, h) { if (h) { obj.$$hashKey = h; } else { delete obj.$$hashKey; } } function baseExtend(dst, objs, deep) { var h = dst.$$hashKey; for (var i = 0, ii = objs.length; i < ii; ++i) { var obj = objs[i]; if (!isObject(obj) && !isFunction(obj)) continue; var keys = Object.keys(obj); for (var j = 0, jj = keys.length; j < jj; j++) { var key = keys[j]; var src = obj[key]; if (deep && isObject(src)) { if (isDate(src)) { dst[key] = new Date(src.valueOf()); } else if (isRegExp(src)) { dst[key] = new RegExp(src); } else if (src.nodeName) { dst[key] = src.cloneNode(true); } else if (isElement(src)) { dst[key] = src.clone(); } else { if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {}; baseExtend(dst[key], [src], true); } } else { dst[key] = src; } } } setHashKey(dst, h); return dst; } /** * @ngdoc function * @name angular.extend * @module ng * @kind function * * @description * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s) * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`. * * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use * {@link angular.merge} for this. * * @param {Object} dst Destination object. * @param {...Object} src Source object(s). * @returns {Object} Reference to `dst`. */ function extend(dst) { return baseExtend(dst, slice.call(arguments, 1), false); } /** * @ngdoc function * @name angular.merge * @module ng * @kind function * * @description * Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s) * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so * by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`. * * Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source * objects, performing a deep copy. * * @param {Object} dst Destination object. * @param {...Object} src Source object(s). * @returns {Object} Reference to `dst`. */ function merge(dst) { return baseExtend(dst, slice.call(arguments, 1), true); } function toInt(str) { return parseInt(str, 10); } var isNumberNaN = Number.isNaN || function isNumberNaN(num) { // eslint-disable-next-line no-self-compare return num !== num; }; function inherit(parent, extra) { return extend(Object.create(parent), extra); } /** * @ngdoc function * @name angular.noop * @module ng * @kind function * * @description * A function that performs no operations. This function can be useful when writing code in the * functional style. ```js function foo(callback) { var result = calculateResult(); (callback || angular.noop)(result); } ``` */ function noop() {} noop.$inject = []; /** * @ngdoc function * @name angular.identity * @module ng * @kind function * * @description * A function that returns its first argument. This function is useful when writing code in the * functional style. * ```js function transformer(transformationFn, value) { return (transformationFn || angular.identity)(value); }; // E.g. function getResult(fn, input) { return (fn || angular.identity)(input); }; getResult(function(n) { return n * 2; }, 21); // returns 42 getResult(null, 21); // returns 21 getResult(undefined, 21); // returns 21 ``` * * @param {*} value to be returned. * @returns {*} the value passed in. */ function identity($) { return $; } identity.$inject = []; function valueFn(value) { return function valueRef() { return value; }; } function hasCustomToString(obj) { return isFunction(obj.toString) && obj.toString !== toString; } /** * @ngdoc function * @name angular.isUndefined * @module ng * @kind function * * @description * Determines if a reference is undefined. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is undefined. */ function isUndefined(value) { return typeof value === 'undefined'; } /** * @ngdoc function * @name angular.isDefined * @module ng * @kind function * * @description * Determines if a reference is defined. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is defined. */ function isDefined(value) { return typeof value !== 'undefined'; } /** * @ngdoc function * @name angular.isObject * @module ng * @kind function * * @description * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not * considered to be objects. Note that JavaScript arrays are objects. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Object` but not `null`. */ function isObject(value) { // http://jsperf.com/isobject4 return value !== null && typeof value === 'object'; } /** * Determine if a value is an object with a null prototype * * @returns {boolean} True if `value` is an `Object` with a null prototype */ function isBlankObject(value) { return value !== null && typeof value === 'object' && !getPrototypeOf(value); } /** * @ngdoc function * @name angular.isString * @module ng * @kind function * * @description * Determines if a reference is a `String`. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `String`. */ function isString(value) { return typeof value === 'string'; } /** * @ngdoc function * @name angular.isNumber * @module ng * @kind function * * @description * Determines if a reference is a `Number`. * * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`. * * If you wish to exclude these then you can use the native * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite) * method. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Number`. */ function isNumber(value) { return typeof value === 'number'; } /** * @ngdoc function * @name angular.isDate * @module ng * @kind function * * @description * Determines if a value is a date. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Date`. */ function isDate(value) { return toString.call(value) === '[object Date]'; } /** * @ngdoc function * @name angular.isArray * @module ng * @kind function * * @description * Determines if a reference is an `Array`. Alias of Array.isArray. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Array`. */ var isArray = Array.isArray; /** * @ngdoc function * @name angular.isFunction * @module ng * @kind function * * @description * Determines if a reference is a `Function`. * * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Function`. */ function isFunction(value) { return typeof value === 'function'; } /** * Determines if a value is a regular expression object. * * @private * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `RegExp`. */ function isRegExp(value) { return toString.call(value) === '[object RegExp]'; } /** * Checks if `obj` is a window object. * * @private * @param {*} obj Object to check * @returns {boolean} True if `obj` is a window obj. */ function isWindow(obj) { return obj && obj.window === obj; } function isScope(obj) { return obj && obj.$evalAsync && obj.$watch; } function isFile(obj) { return toString.call(obj) === '[object File]'; } function isFormData(obj) { return toString.call(obj) === '[object FormData]'; } function isBlob(obj) { return toString.call(obj) === '[object Blob]'; } function isBoolean(value) { return typeof value === 'boolean'; } function isPromiseLike(obj) { return obj && isFunction(obj.then); } var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/; function isTypedArray(value) { return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value)); } function isArrayBuffer(obj) { return toString.call(obj) === '[object ArrayBuffer]'; } var trim = function(value) { return isString(value) ? value.trim() : value; }; // Copied from: // http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021 // Prereq: s is a string. var escapeForRegexp = function(s) { return s .replace(/([-()[\]{}+?*.$^|,:#= 0) { array.splice(index, 1); } return index; } /** * @ngdoc function * @name angular.copy * @module ng * @kind function * * @description * Creates a deep copy of `source`, which should be an object or an array. * * * If no destination is supplied, a copy of the object or array is created. * * If a destination is provided, all of its elements (for arrays) or properties (for objects) * are deleted and then all elements/properties from the source are copied to it. * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. * * If `source` is identical to `destination` an exception will be thrown. * *form = {{user | json}}
master = {{master | json}}
This renders because the controller does not fail to instantiate, by using explicit annotation style (see script.js for details)
This renders because the controller does not fail to instantiate, by using explicit annotation style (see script.js for details)
The controller could not be instantiated, due to relying on automatic function annotations (which are disabled in strict mode). As such, the content of this section is not interpolated, and there should be an error in your web console.
Cached Values
Cache Info
{{ $ctrl.log | json }}', * controller: function() { * var previousValue; * this.log = []; * this.$doCheck = function() { * var currentValue = this.date && this.date.valueOf(); * if (previousValue !== currentValue) { * this.log.push('doCheck: date mutated: ' + this.date); * previousValue = currentValue; * } * }; * } * }); *
{{ items }}*
{{ $ctrl.log | json }}', * controller: function() { * this.log = []; * * this.$doCheck = function() { * if (this.items_ref !== this.items) { * this.log.push('doCheck: items changed'); * this.items_ref = this.items; * } * if (!angular.equals(this.items_clone, this.items)) { * this.log.push('doCheck: items mutated'); * this.items_clone = angular.copy(this.items); * } * }; * } * }); *