From 280652cf516ae5fd9dc7f6dd25b22f656c5b313e Mon Sep 17 00:00:00 2001 From: pedrombafonso Date: Thu, 9 Oct 2014 16:58:35 +0100 Subject: [PATCH 1/4] added: onClose function --- angular-notify.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/angular-notify.js b/angular-notify.js index a3328a3..a5d330c 100755 --- a/angular-notify.js +++ b/angular-notify.js @@ -20,11 +20,13 @@ angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile',' args.position = args.position ? args.position : position; args.container = args.container ? args.container : container; args.classes = args.classes ? args.classes : ''; + args.onClose = args.onClose ? args.onClose : function () {return;}; var scope = args.scope ? args.scope.$new() : $rootScope.$new(); scope.$message = args.message; scope.$classes = args.classes; scope.$messageTemplate = args.messageTemplate; + scope.$onClose = args.onClose; $http.get(args.templateUrl,{cache: $templateCache}).success(function(template){ @@ -66,6 +68,7 @@ angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile',' scope.$close = function(){ templateElement.css('opacity',0).attr('data-closing','true'); layoutMessages(); + scope.$onClose(); }; var layoutMessages = function(){ @@ -101,7 +104,7 @@ angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile',' }); var retVal = {}; - + retVal.close = function(){ if (scope.$close){ scope.$close(); From a987614c470fcccbb9a32eb1cda533c8d3538362 Mon Sep 17 00:00:00 2001 From: pedrombafonso Date: Thu, 9 Oct 2014 16:58:51 +0100 Subject: [PATCH 2/4] updated: demo --- demo/demo.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index cbdc439..5d8ef88 100755 --- a/demo/demo.js +++ b/demo/demo.js @@ -26,8 +26,11 @@ angular.module('app').controller('DemoCtrl',function($scope,notify){ messageTemplate: messageTemplate, classes: $scope.classes, scope:$scope, - templateUrl: $scope.template - }); + templateUrl: $scope.template, + onClose: function () { + console.log('closed at', new Date()); + } + }); }; @@ -35,4 +38,4 @@ angular.module('app').controller('DemoCtrl',function($scope,notify){ notify('You clicked a link!'); }; -}); \ No newline at end of file +}); From 2ee6d51a118af0d2ebd714f18156c274ce8000eb Mon Sep 17 00:00:00 2001 From: pedrombafonso Date: Thu, 9 Oct 2014 16:59:16 +0100 Subject: [PATCH 3/4] updated: build --- bower_components/angular/.bower.json | 13 +- bower_components/angular/README.md | 0 bower_components/angular/angular-csp.css | 6 + bower_components/angular/angular.js | 3466 ++++++++++-------- bower_components/angular/angular.min.js | 416 +-- bower_components/angular/angular.min.js.gzip | Bin 39258 -> 39810 bytes bower_components/angular/angular.min.js.map | 6 +- bower_components/angular/bower.json | 2 +- bower_components/angular/package.json | 25 + dist/angular-notify.js | 5 +- dist/angular-notify.min.js | 2 +- 11 files changed, 2273 insertions(+), 1668 deletions(-) mode change 100755 => 100644 bower_components/angular/.bower.json mode change 100755 => 100644 bower_components/angular/README.md mode change 100755 => 100644 bower_components/angular/angular-csp.css mode change 100755 => 100644 bower_components/angular/angular.js mode change 100755 => 100644 bower_components/angular/angular.min.js mode change 100755 => 100644 bower_components/angular/angular.min.js.gzip mode change 100755 => 100644 bower_components/angular/angular.min.js.map mode change 100755 => 100644 bower_components/angular/bower.json create mode 100644 bower_components/angular/package.json diff --git a/bower_components/angular/.bower.json b/bower_components/angular/.bower.json old mode 100755 new mode 100644 index 19b2092..ab0e1cb --- a/bower_components/angular/.bower.json +++ b/bower_components/angular/.bower.json @@ -1,17 +1,16 @@ { "name": "angular", - "version": "1.2.16", + "version": "1.2.26", "main": "./angular.js", "dependencies": {}, "homepage": "https://github.com/angular/bower-angular", - "_release": "1.2.16", + "_release": "1.2.26", "_resolution": { "type": "version", - "tag": "v1.2.16", - "commit": "7ae38b4a0cfced157e3486a0d6e2d299601723bb" + "tag": "v1.2.26", + "commit": "7308d8d650b2b9948796035cbf6f3b175d45efe0" }, "_source": "git://github.com/angular/bower-angular.git", - "_target": "~1.2.16", - "_originalSource": "angular", - "_direct": true + "_target": "~1.2", + "_originalSource": "angular" } \ No newline at end of file diff --git a/bower_components/angular/README.md b/bower_components/angular/README.md old mode 100755 new mode 100644 diff --git a/bower_components/angular/angular-csp.css b/bower_components/angular/angular-csp.css old mode 100755 new mode 100644 index 0d3d3a9..3abb3a0 --- a/bower_components/angular/angular-csp.css +++ b/bower_components/angular/angular-csp.css @@ -16,3 +16,9 @@ ng\:form { transition:0s all!important; -webkit-transition:0s all!important; } + +/* show the element during a show/hide animation when the + * animation is ongoing, but the .ng-hide class is active */ +.ng-hide-add-active, .ng-hide-remove { + display: block!important; +} diff --git a/bower_components/angular/angular.js b/bower_components/angular/angular.js old mode 100755 new mode 100644 index 2f26bee..049cda8 --- a/bower_components/angular/angular.js +++ b/bower_components/angular/angular.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.2.16 + * @license AngularJS v1.2.26 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -68,7 +68,7 @@ function minErr(module) { return match; }); - message = message + '\nhttp://errors.angularjs.org/1.2.16/' + + message = message + '\nhttp://errors.angularjs.org/1.2.26/' + (module ? module + '/' : '') + code; for (i = 2; i < arguments.length; i++) { message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + @@ -80,89 +80,88 @@ function minErr(module) { } /* We need to tell jshint what variables are being exported */ -/* global - -angular, - -msie, - -jqLite, - -jQuery, - -slice, - -push, - -toString, - -ngMinErr, - -_angular, - -angularModule, - -nodeName_, - -uid, - - -lowercase, - -uppercase, - -manualLowercase, - -manualUppercase, - -nodeName_, - -isArrayLike, - -forEach, - -sortedKeys, - -forEachSorted, - -reverseParams, - -nextUid, - -setHashKey, - -extend, - -int, - -inherit, - -noop, - -identity, - -valueFn, - -isUndefined, - -isDefined, - -isObject, - -isString, - -isNumber, - -isDate, - -isArray, - -isFunction, - -isRegExp, - -isWindow, - -isScope, - -isFile, - -isBlob, - -isBoolean, - -trim, - -isElement, - -makeMap, - -map, - -size, - -includes, - -indexOf, - -arrayRemove, - -isLeafNode, - -copy, - -shallowCopy, - -equals, - -csp, - -concat, - -sliceArgs, - -bind, - -toJsonReplacer, - -toJson, - -fromJson, - -toBoolean, - -startingTag, - -tryDecodeURIComponent, - -parseKeyValue, - -toKeyValue, - -encodeUriSegment, - -encodeUriQuery, - -angularInit, - -bootstrap, - -snake_case, - -bindJQuery, - -assertArg, - -assertArgFn, - -assertNotHasOwnProperty, - -getter, - -getBlockElements, - -hasOwnProperty, - +/* global angular: true, + msie: true, + jqLite: true, + jQuery: true, + slice: true, + push: true, + toString: true, + ngMinErr: true, + angularModule: true, + nodeName_: true, + uid: true, + VALIDITY_STATE_PROPERTY: true, + + lowercase: true, + uppercase: true, + manualLowercase: true, + manualUppercase: true, + nodeName_: true, + isArrayLike: true, + forEach: true, + sortedKeys: true, + forEachSorted: true, + reverseParams: true, + nextUid: true, + setHashKey: true, + extend: true, + int: true, + inherit: true, + noop: true, + identity: true, + valueFn: true, + isUndefined: true, + isDefined: true, + isObject: true, + isString: true, + isNumber: true, + isDate: true, + isArray: true, + isFunction: true, + isRegExp: true, + isWindow: true, + isScope: true, + isFile: true, + isBlob: true, + isBoolean: true, + isPromiseLike: true, + trim: true, + isElement: true, + makeMap: true, + map: true, + size: true, + includes: true, + indexOf: true, + arrayRemove: true, + isLeafNode: true, + copy: true, + shallowCopy: true, + equals: true, + csp: true, + concat: true, + sliceArgs: true, + bind: true, + toJsonReplacer: true, + toJson: true, + fromJson: true, + toBoolean: true, + startingTag: true, + tryDecodeURIComponent: true, + parseKeyValue: true, + toKeyValue: true, + encodeUriSegment: true, + encodeUriQuery: true, + angularInit: true, + bootstrap: true, + snake_case: true, + bindJQuery: true, + assertArg: true, + assertArgFn: true, + assertNotHasOwnProperty: true, + getter: true, + getBlockElements: true, + hasOwnProperty: true, */ //////////////////////////////////// @@ -182,11 +181,15 @@ function minErr(module) { *
*/ +// 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'; + /** * @ngdoc function * @name angular.lowercase * @module ng - * @function + * @kind function * * @description Converts the specified string to lowercase. * @param {string} string String to be converted to lowercase. @@ -199,7 +202,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; * @ngdoc function * @name angular.uppercase * @module ng - * @function + * @kind function * * @description Converts the specified string to uppercase. * @param {string} string String to be converted to uppercase. @@ -240,8 +243,6 @@ var /** holds major version number for IE or NaN for real browsers */ toString = Object.prototype.toString, ngMinErr = minErr('ng'), - - _angular = window.angular, /** @name angular */ angular = window.angular || (window.angular = {}), angularModule, @@ -283,7 +284,7 @@ function isArrayLike(obj) { * @ngdoc function * @name angular.forEach * @module ng - * @function + * @kind function * * @description * Invokes the `iterator` function once for each item in `obj` collection, which can be either an @@ -297,7 +298,7 @@ function isArrayLike(obj) { ```js var values = {name: 'misko', gender: 'male'}; var log = []; - angular.forEach(values, function(value, key){ + angular.forEach(values, function(value, key) { this.push(key + ': ' + value); }, log); expect(log).toEqual(['name: misko', 'gender: male']); @@ -311,7 +312,7 @@ function isArrayLike(obj) { function forEach(obj, iterator, context) { var key; if (obj) { - if (isFunction(obj)){ + if (isFunction(obj)) { for (key in obj) { // Need to check if hasOwnProperty exists, // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function @@ -319,11 +320,12 @@ function forEach(obj, iterator, context) { iterator.call(context, obj[key], key); } } - } else if (obj.forEach && obj.forEach !== forEach) { - obj.forEach(iterator, context); - } else if (isArrayLike(obj)) { - for (key = 0; key < obj.length; key++) + } else if (isArray(obj) || isArrayLike(obj)) { + for (key = 0; key < obj.length; key++) { iterator.call(context, obj[key], key); + } + } else if (obj.forEach && obj.forEach !== forEach) { + obj.forEach(iterator, context); } else { for (key in obj) { if (obj.hasOwnProperty(key)) { @@ -412,10 +414,10 @@ function setHashKey(obj, h) { * @ngdoc function * @name angular.extend * @module ng - * @function + * @kind function * * @description - * Extends the destination object `dst` by copying all of the properties from the `src` object(s) + * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s) * to `dst`. You can specify multiple `src` objects. * * @param {Object} dst Destination object. @@ -424,9 +426,9 @@ function setHashKey(obj, h) { */ function extend(dst) { var h = dst.$$hashKey; - forEach(arguments, function(obj){ + forEach(arguments, function(obj) { if (obj !== dst) { - forEach(obj, function(value, key){ + forEach(obj, function(value, key) { dst[key] = value; }); } @@ -449,7 +451,7 @@ function inherit(parent, extra) { * @ngdoc function * @name angular.noop * @module ng - * @function + * @kind function * * @description * A function that performs no operations. This function can be useful when writing code in the @@ -469,7 +471,7 @@ noop.$inject = []; * @ngdoc function * @name angular.identity * @module ng - * @function + * @kind function * * @description * A function that returns its first argument. This function is useful when writing code in the @@ -491,7 +493,7 @@ function valueFn(value) {return function() {return value;};} * @ngdoc function * @name angular.isUndefined * @module ng - * @function + * @kind function * * @description * Determines if a reference is undefined. @@ -506,7 +508,7 @@ function isUndefined(value){return typeof value === 'undefined';} * @ngdoc function * @name angular.isDefined * @module ng - * @function + * @kind function * * @description * Determines if a reference is defined. @@ -521,7 +523,7 @@ function isDefined(value){return typeof value !== 'undefined';} * @ngdoc function * @name angular.isObject * @module ng - * @function + * @kind function * * @description * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not @@ -537,7 +539,7 @@ function isObject(value){return value != null && typeof value === 'object';} * @ngdoc function * @name angular.isString * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `String`. @@ -552,7 +554,7 @@ function isString(value){return typeof value === 'string';} * @ngdoc function * @name angular.isNumber * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `Number`. @@ -567,7 +569,7 @@ function isNumber(value){return typeof value === 'number';} * @ngdoc function * @name angular.isDate * @module ng - * @function + * @kind function * * @description * Determines if a value is a date. @@ -575,7 +577,7 @@ function isNumber(value){return typeof value === 'number';} * @param {*} value Reference to check. * @returns {boolean} True if `value` is a `Date`. */ -function isDate(value){ +function isDate(value) { return toString.call(value) === '[object Date]'; } @@ -584,7 +586,7 @@ function isDate(value){ * @ngdoc function * @name angular.isArray * @module ng - * @function + * @kind function * * @description * Determines if a reference is an `Array`. @@ -592,16 +594,20 @@ function isDate(value){ * @param {*} value Reference to check. * @returns {boolean} True if `value` is an `Array`. */ -function isArray(value) { - return toString.call(value) === '[object Array]'; -} - +var isArray = (function() { + if (!isFunction(Array.isArray)) { + return function(value) { + return toString.call(value) === '[object Array]'; + }; + } + return Array.isArray; +})(); /** * @ngdoc function * @name angular.isFunction * @module ng - * @function + * @kind function * * @description * Determines if a reference is a `Function`. @@ -656,6 +662,11 @@ function isBoolean(value) { } +function isPromiseLike(obj) { + return obj && isFunction(obj.then); +} + + var trim = (function() { // native trim is way faster: http://jsperf.com/angular-trim-test // but IE doesn't have it... :-( @@ -675,7 +686,7 @@ var trim = (function() { * @ngdoc function * @name angular.isElement * @module ng - * @function + * @kind function * * @description * Determines if a reference is a DOM element (or wrapped jQuery element). @@ -693,7 +704,7 @@ function isElement(node) { * @param str 'key1,key2,...' * @returns {object} in the form of {key1:true, key2:true, ...} */ -function makeMap(str){ +function makeMap(str) { var obj = {}, items = str.split(","), i; for ( i = 0; i < items.length; i++ ) obj[ items[i] ] = true; @@ -740,7 +751,7 @@ function size(obj, ownPropsOnly) { if (isArray(obj) || isString(obj)) { return obj.length; - } else if (isObject(obj)){ + } else if (isObject(obj)) { for (key in obj) if (!ownPropsOnly || obj.hasOwnProperty(key)) count++; @@ -786,7 +797,7 @@ function isLeafNode (node) { * @ngdoc function * @name angular.copy * @module ng - * @function + * @kind function * * @description * Creates a deep copy of `source`, which should be an object or an array. @@ -804,9 +815,9 @@ function isLeafNode (node) { * @returns {*} The copy or updated `destination`, if `destination` was specified. * * @example - + -
+
Name:
E-mail:
@@ -820,26 +831,27 @@ function isLeafNode (node) {
*/ -function copy(source, destination){ +function copy(source, destination, stackSource, stackDest) { if (isWindow(source) || isScope(source)) { throw ngMinErr('cpws', "Can't copy! Making copies of Window or Scope instances is not supported."); @@ -849,52 +861,87 @@ function copy(source, destination){ destination = source; if (source) { if (isArray(source)) { - destination = copy(source, []); + destination = copy(source, [], stackSource, stackDest); } else if (isDate(source)) { destination = new Date(source.getTime()); } else if (isRegExp(source)) { - destination = new RegExp(source.source); + destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]); + destination.lastIndex = source.lastIndex; } else if (isObject(source)) { - destination = copy(source, {}); + destination = copy(source, {}, stackSource, stackDest); } } } else { if (source === destination) throw ngMinErr('cpi', "Can't copy! Source and destination are identical."); + + stackSource = stackSource || []; + stackDest = stackDest || []; + + if (isObject(source)) { + var index = indexOf(stackSource, source); + if (index !== -1) return stackDest[index]; + + stackSource.push(source); + stackDest.push(destination); + } + + var result; if (isArray(source)) { destination.length = 0; for ( var i = 0; i < source.length; i++) { - destination.push(copy(source[i])); + result = copy(source[i], null, stackSource, stackDest); + if (isObject(source[i])) { + stackSource.push(source[i]); + stackDest.push(result); + } + destination.push(result); } } else { var h = destination.$$hashKey; - forEach(destination, function(value, key){ - delete destination[key]; - }); + if (isArray(destination)) { + destination.length = 0; + } else { + forEach(destination, function(value, key) { + delete destination[key]; + }); + } for ( var key in source) { - destination[key] = copy(source[key]); + result = copy(source[key], null, stackSource, stackDest); + if (isObject(source[key])) { + stackSource.push(source[key]); + stackDest.push(result); + } + destination[key] = result; } setHashKey(destination,h); } + } return destination; } /** - * Create a shallow copy of an object + * Creates a shallow copy of an object, an array or a primitive */ function shallowCopy(src, dst) { - dst = dst || {}; + if (isArray(src)) { + dst = dst || []; + + for ( var i = 0; i < src.length; i++) { + dst[i] = src[i]; + } + } else if (isObject(src)) { + dst = dst || {}; - for(var key in src) { - // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src - // so we don't need to worry about using our custom hasOwnProperty here - if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; + for (var key in src) { + if (hasOwnProperty.call(src, key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } } } - return dst; + return dst || src; } @@ -902,7 +949,7 @@ function shallowCopy(src, dst) { * @ngdoc function * @name angular.equals * @module ng - * @function + * @kind function * * @description * Determines if two objects or two values are equivalent. Supports value types, regular @@ -914,7 +961,7 @@ function shallowCopy(src, dst) { * * Both objects or values are of the same type and all of their properties are equal by * comparing them with `angular.equals`. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) - * * Both values represent the same regular expression (In JavasScript, + * * Both values represent the same regular expression (In JavaScript, * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual * representation matches). * @@ -943,7 +990,8 @@ function equals(o1, o2) { return true; } } else if (isDate(o1)) { - return isDate(o2) && o1.getTime() == o2.getTime(); + if (!isDate(o2)) return false; + return (isNaN(o1.getTime()) && isNaN(o2.getTime())) || (o1.getTime() === o2.getTime()); } else if (isRegExp(o1) && isRegExp(o2)) { return o1.toString() == o2.toString(); } else { @@ -967,12 +1015,25 @@ function equals(o1, o2) { return false; } +var csp = function() { + if (isDefined(csp.isActive_)) return csp.isActive_; + + var active = !!(document.querySelector('[ng-csp]') || + document.querySelector('[data-ng-csp]')); + + if (!active) { + try { + /* jshint -W031, -W054 */ + new Function(''); + /* jshint +W031, +W054 */ + } catch (e) { + active = true; + } + } + + return (csp.isActive_ = active); +}; -function csp() { - return (document.securityPolicy && document.securityPolicy.isActive) || - (document.querySelector && - !!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]'))); -} function concat(array1, array2, index) { @@ -989,7 +1050,7 @@ function sliceArgs(args, startIndex) { * @ngdoc function * @name angular.bind * @module ng - * @function + * @kind function * * @description * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for @@ -1045,7 +1106,7 @@ function toJsonReplacer(key, value) { * @ngdoc function * @name angular.toJson * @module ng - * @function + * @kind function * * @description * Serializes input into a JSON-formatted string. Properties with leading $ characters will be @@ -1065,7 +1126,7 @@ function toJson(obj, pretty) { * @ngdoc function * @name angular.fromJson * @module ng - * @function + * @kind function * * @description * Deserializes a JSON string. @@ -1142,13 +1203,13 @@ function tryDecodeURIComponent(value) { */ function parseKeyValue(/**string*/keyValue) { var obj = {}, key_value, key; - forEach((keyValue || "").split('&'), function(keyValue){ + forEach((keyValue || "").split('&'), function(keyValue) { if ( keyValue ) { - key_value = keyValue.split('='); + key_value = keyValue.replace(/\+/g,'%20').split('='); key = tryDecodeURIComponent(key_value[0]); if ( isDefined(key) ) { var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true; - if (!obj[key]) { + if (!hasOwnProperty.call(obj, key)) { obj[key] = val; } else if(isArray(obj[key])) { obj[key].push(val); @@ -1322,7 +1383,7 @@ function angularInit(element, bootstrap) { * * Angular will detect if it has been loaded into the browser more than once and only allow the * first loaded script to be bootstrapped and will report a warning to the browser console for - * each of the subsequent scripts. This prevents strange results in applications, where otherwise + * each of the subsequent scripts. This prevents strange results in applications, where otherwise * multiple instances of Angular try to work on the DOM. * * @@ -1368,7 +1429,11 @@ function bootstrap(element, modules) { if (element.injector()) { var tag = (element[0] === document) ? 'document' : startingTag(element); - throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag); + //Encode angle brackets to prevent input from being sanitized to empty string #8683 + throw ngMinErr( + 'btstrpd', + "App Already Bootstrapped with this Element '{0}'", + tag.replace(//,'>')); } modules = modules || []; @@ -1404,7 +1469,7 @@ function bootstrap(element, modules) { } var SNAKE_CASE_REGEXP = /[A-Z]/g; -function snake_case(name, separator){ +function snake_case(name, separator) { separator = separator || '_'; return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { return (pos ? separator : '') + letter.toLowerCase(); @@ -1414,8 +1479,9 @@ function snake_case(name, separator){ function bindJQuery() { // bind to jQuery if present; jQuery = window.jQuery; - // reset to jQuery or default to us. - if (jQuery) { + // Use jQuery if it exists with proper functionality, otherwise default to us. + // Angular 1.2+ requires jQuery 1.7.1+ for on()/off() support. + if (jQuery && jQuery.fn.on) { jqLite = jQuery; extend(jQuery.fn, { scope: JQLitePrototype.scope, @@ -1451,7 +1517,7 @@ function assertArgFn(arg, name, acceptArrayAnnotation) { } assertArg(isFunction(arg), name, 'not a function, got ' + - (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg)); + (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg)); return arg; } @@ -1561,7 +1627,7 @@ function setupModuleLoader(window) { * * # Module * - * A module is a collection of services, directives, filters, and configuration information. + * A module is a collection of services, directives, controllers, filters, and configuration information. * `angular.module` is used to configure the {@link auto.$injector $injector}. * * ```js @@ -1589,9 +1655,9 @@ function setupModuleLoader(window) { * {@link angular.bootstrap} to simplify this process for you. * * @param {!string} name The name of the module to create or retrieve. -<<<<<* @param {!Array.=} requires If specified then new module is being created. If ->>>>>* unspecified then the module is being retrieved for further configuration. - * @param {Function} configFn Optional configuration function for the module. Same as + * @param {!Array.=} requires If specified then new module is being created. If + * unspecified then the module is being retrieved for further configuration. + * @param {Function=} configFn Optional configuration function for the module. Same as * {@link angular.Module#config Module#config()}. * @returns {module} new module with the {@link angular.Module} api. */ @@ -1631,7 +1697,7 @@ function setupModuleLoader(window) { * @ngdoc property * @name angular.Module#requires * @module ng - * @returns {Array.} List of module names which must be loaded before this module. + * * @description * Holds the list of modules which the injector will load before the current module is * loaded. @@ -1642,8 +1708,9 @@ function setupModuleLoader(window) { * @ngdoc property * @name angular.Module#name * @module ng - * @returns {string} Name of the module. + * * @description + * Name of the module. */ name: name, @@ -1783,6 +1850,8 @@ function setupModuleLoader(window) { * configuration. * @description * Use this method to register work which needs to be performed on module loading. + * For more about how to configure services, see + * {@link providers#providers_provider-recipe Provider Recipe}. */ config: config, @@ -1826,12 +1895,11 @@ function setupModuleLoader(window) { } -/* global - angularModule: true, - version: true, +/* global angularModule: true, + version: true, - $LocaleProvider, - $CompileProvider, + $LocaleProvider, + $CompileProvider, htmlAnchorDirective, inputDirective, @@ -1919,11 +1987,11 @@ function setupModuleLoader(window) { * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.2.16', // all of these placeholder strings will be replaced by grunt's + full: '1.2.26', // all of these placeholder strings will be replaced by grunt's major: 1, // package task minor: 2, - dot: 16, - codeName: 'badger-enumeration' + dot: 26, + codeName: 'captivating-disinterest' }; @@ -1936,11 +2004,11 @@ function publishExternalAPI(angular){ 'element': jqLite, 'forEach': forEach, 'injector': createInjector, - 'noop':noop, - 'bind':bind, + 'noop': noop, + 'bind': bind, 'toJson': toJson, 'fromJson': fromJson, - 'identity':identity, + 'identity': identity, 'isUndefined': isUndefined, 'isDefined': isDefined, 'isString': isString, @@ -2047,12 +2115,10 @@ function publishExternalAPI(angular){ ]); } -/* global - - -JQLitePrototype, - -addEventListenerFn, - -removeEventListenerFn, - -BOOLEAN_ATTR +/* global JQLitePrototype: true, + addEventListenerFn: true, + removeEventListenerFn: true, + BOOLEAN_ATTR: true */ ////////////////////////////////// @@ -2063,7 +2129,7 @@ function publishExternalAPI(angular){ * @ngdoc function * @name angular.element * @module ng - * @function + * @kind function * * @description * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. @@ -2145,8 +2211,9 @@ function publishExternalAPI(angular){ * @returns {Object} jQuery object. */ +JQLite.expando = 'ng339'; + var jqCache = JQLite.cache = {}, - jqName = JQLite.expando = 'ng-' + new Date().getTime(), jqId = 1, addEventListenerFn = (window.document.addEventListener ? function(element, type, fn) {element.addEventListener(type, fn, false);} @@ -2356,7 +2423,7 @@ function jqLiteOff(element, type, fn, unsupported) { } function jqLiteRemoveData(element, name) { - var expandoId = element[jqName], + var expandoId = element.ng339, expandoStore = jqCache[expandoId]; if (expandoStore) { @@ -2370,17 +2437,17 @@ function jqLiteRemoveData(element, name) { jqLiteOff(element); } delete jqCache[expandoId]; - element[jqName] = undefined; // ie does not allow deletion of attributes on elements. + element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it } } function jqLiteExpandoStore(element, key, value) { - var expandoId = element[jqName], + var expandoId = element.ng339, expandoStore = jqCache[expandoId || -1]; if (isDefined(value)) { if (!expandoStore) { - element[jqName] = expandoId = jqNextId(); + element.ng339 = expandoId = jqNextId(); expandoStore = jqCache[expandoId] = {}; } expandoStore[key] = value; @@ -2465,25 +2532,22 @@ function jqLiteController(element, name) { } function jqLiteInheritedData(element, name, value) { - element = jqLite(element); - // if element is the document object work with the html element instead // this makes $(document).scope() possible - if(element[0].nodeType == 9) { - element = element.find('html'); + if(element.nodeType == 9) { + element = element.documentElement; } var names = isArray(name) ? name : [name]; - while (element.length) { - var node = element[0]; + while (element) { for (var i = 0, ii = names.length; i < ii; i++) { - if ((value = element.data(names[i])) !== undefined) return value; + if ((value = jqLite.data(element, names[i])) !== undefined) return value; } // If dealing with a document fragment node with a host element, and no parent, use the host // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM // to lookup parent controllers. - element = jqLite(node.parentNode || (node.nodeType === 11 && node.host)); + element = element.parentNode || (element.nodeType === 11 && element.host); } } @@ -2558,18 +2622,25 @@ function getBooleanAttrName(element, name) { return booleanAttr && BOOLEAN_ELEMENTS[element.nodeName] && booleanAttr; } +forEach({ + data: jqLiteData, + removeData: jqLiteRemoveData +}, function(fn, name) { + JQLite[name] = fn; +}); + forEach({ data: jqLiteData, inheritedData: jqLiteInheritedData, scope: function(element) { // Can't use jqLiteData here directly so we stay compatible with jQuery! - return jqLite(element).data('$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); + return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); }, isolateScope: function(element) { // Can't use jqLiteData here directly so we stay compatible with jQuery! - return jqLite(element).data('$isolateScope') || jqLite(element).data('$isolateScopeNoTemplate'); + return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate'); }, controller: jqLiteController, @@ -2699,6 +2770,7 @@ forEach({ */ JQLite.prototype[name] = function(arg1, arg2) { var i, key; + var nodeCount = this.length; // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it // in a way that survives minification. @@ -2708,7 +2780,7 @@ forEach({ if (isObject(arg1)) { // we are a write, but the object properties are the key/values - for (i = 0; i < this.length; i++) { + for (i = 0; i < nodeCount; i++) { if (fn === jqLiteData) { // data() takes the whole object in jQuery fn(this[i], arg1); @@ -2722,9 +2794,10 @@ forEach({ return this; } else { // we are a read, so read the first child. + // TODO: do we still need this? var value = fn.$dv; // Only if we have $dv do we iterate over all, otherwise it is just the first element. - var jj = (value === undefined) ? Math.min(this.length, 1) : this.length; + var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount; for (var j = 0; j < jj; j++) { var nodeValue = fn(this[j], arg1, arg2); value = value ? value + nodeValue : nodeValue; @@ -2733,7 +2806,7 @@ forEach({ } } else { // we are a write, so apply to all children - for (i = 0; i < this.length; i++) { + for (i = 0; i < nodeCount; i++) { fn(this[i], arg1, arg2); } // return self for chaining @@ -2994,19 +3067,37 @@ forEach({ clone: jqLiteClone, - triggerHandler: function(element, eventName, eventData) { + triggerHandler: function(element, event, extraParameters) { + + var dummyEvent, eventFnsCopy, handlerArgs; + var eventName = event.type || event; var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName]; - eventData = eventData || []; + if (eventFns) { - var event = [{ - preventDefault: noop, - stopPropagation: noop - }]; + // Create a dummy event to pass to the handlers + dummyEvent = { + preventDefault: function() { this.defaultPrevented = true; }, + isDefaultPrevented: function() { return this.defaultPrevented === true; }, + stopPropagation: noop, + type: eventName, + target: element + }; - forEach(eventFns, function(fn) { - fn.apply(element, event.concat(eventData)); - }); + // If a custom event was provided then extend our dummy event with it + if (event.type) { + dummyEvent = extend(dummyEvent, event); + } + + // Copy event handlers in case event handlers array is modified during execution. + eventFnsCopy = shallowCopy(eventFns); + handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent]; + + forEach(eventFnsCopy, function(fn) { + fn.apply(element, handlerArgs); + }); + + } } }, function(fn, name){ /** @@ -3045,16 +3136,16 @@ forEach({ * @returns {string} hash string such that the same input will have the same hash string. * The resulting string key is in 'type:hashKey' format. */ -function hashKey(obj) { +function hashKey(obj, nextUidFn) { var objType = typeof obj, key; - if (objType == 'object' && obj !== null) { + if (objType == 'function' || (objType == 'object' && obj !== null)) { if (typeof (key = obj.$$hashKey) == 'function') { // must invoke on object to keep the right this key = obj.$$hashKey(); } else if (key === undefined) { - key = obj.$$hashKey = nextUid(); + key = obj.$$hashKey = (nextUidFn || nextUid)(); } } else { key = obj; @@ -3066,7 +3157,13 @@ function hashKey(obj) { /** * HashMap which can use objects as keys */ -function HashMap(array){ +function HashMap(array, isolatedUid) { + if (isolatedUid) { + var uid = 0; + this.nextUid = function() { + return ++uid; + }; + } forEach(array, this.put, this); } HashMap.prototype = { @@ -3076,7 +3173,7 @@ HashMap.prototype = { * @param value value to store can be any type */ put: function(key, value) { - this[hashKey(key)] = value; + this[hashKey(key, this.nextUid)] = value; }, /** @@ -3084,7 +3181,7 @@ HashMap.prototype = { * @returns {Object} the value for the key */ get: function(key) { - return this[hashKey(key)]; + return this[hashKey(key, this.nextUid)]; }, /** @@ -3092,7 +3189,7 @@ HashMap.prototype = { * @param key */ remove: function(key) { - var value = this[key = hashKey(key)]; + var value = this[key = hashKey(key, this.nextUid)]; delete this[key]; return value; } @@ -3102,7 +3199,7 @@ HashMap.prototype = { * @ngdoc function * @module ng * @name angular.injector - * @function + * @kind function * * @description * Creates an injector function that can be used for retrieving services as well as for @@ -3129,7 +3226,7 @@ HashMap.prototype = { * * Sometimes you want to get access to the injector of a currently running Angular app * from outside Angular. Perhaps, you want to inject and compile some markup after the - * application has been bootstrapped. You can do this using extra `injector()` added + * application has been bootstrapped. You can do this using the extra `injector()` added * to JQuery/jqLite elements. See {@link angular.element}. * * *This is fairly rare but could be the case if a third party library is injecting the @@ -3170,7 +3267,7 @@ function annotate(fn) { argDecl, last; - if (typeof fn == 'function') { + if (typeof fn === 'function') { if (!($inject = fn.$inject)) { $inject = []; if (fn.length) { @@ -3199,7 +3296,7 @@ function annotate(fn) { /** * @ngdoc service * @name $injector - * @function + * @kind function * * @description * @@ -3242,7 +3339,7 @@ function annotate(fn) { * minification, and obfuscation tools since these tools change the argument names. * * ## `$inject` Annotation - * By adding a `$inject` property onto a function the injection parameters can be specified. + * By adding an `$inject` property onto a function the injection parameters can be specified. * * ## Inline * As an array of injection names, where the last item in the array is the function to call. @@ -3279,7 +3376,7 @@ function annotate(fn) { * @name $injector#has * * @description - * Allows the user to query if the particular service exist. + * Allows the user to query if the particular service exists. * * @param {string} Name of the service to query. * @returns {boolean} returns true if injector has given service. @@ -3289,8 +3386,8 @@ function annotate(fn) { * @ngdoc method * @name $injector#instantiate * @description - * Create a new instance of JS type. The method takes a constructor function invokes the new - * operator and supplies all of the arguments to the constructor function as specified by the + * Create a new instance of JS type. The method takes a constructor function, invokes the new + * operator, and supplies all of the arguments to the constructor function as specified by the * constructor annotation. * * @param {Function} Type Annotated constructor function. @@ -3383,7 +3480,7 @@ function annotate(fn) { /** - * @ngdoc object + * @ngdoc service * @name $provide * * @description @@ -3689,7 +3786,7 @@ function createInjector(modulesToLoad) { var INSTANTIATING = {}, providerSuffix = 'Provider', path = [], - loadedModules = new HashMap(), + loadedModules = new HashMap([], true), providerCache = { $provide: { provider: supportObject(provider), @@ -3822,7 +3919,8 @@ function createInjector(modulesToLoad) { function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); + throw $injectorMinErr('cdep', 'Circular dependency found: {0}', + serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { @@ -3859,8 +3957,7 @@ function createInjector(modulesToLoad) { : getService(key) ); } - if (!fn.$inject) { - // this means that we must be an array. + if (isArray(fn)) { fn = fn[length]; } @@ -3903,7 +4000,7 @@ function createInjector(modulesToLoad) { * @requires $rootScope * * @description - * When called, it checks current value of `$location.hash()` and scroll to related element, + * When called, it checks current value of `$location.hash()` and scrolls to the related element, * according to rules specified in * [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document). * @@ -4105,7 +4202,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#enter - * @function + * @kind function * @description Inserts the element into the DOM either after the `after` element or within * the `parent` element. Once complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will be inserted into the DOM @@ -4132,7 +4229,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#leave - * @function + * @kind function * @description Removes the element from the DOM. Once complete, the done() callback will be * fired (if provided). * @param {DOMElement} element the element which will be removed from the DOM @@ -4148,7 +4245,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#move - * @function + * @kind function * @description Moves the position of the provided element within the DOM to be placed * either after the `after` element or inside of the `parent` element. Once complete, the * done() callback will be fired (if provided). @@ -4172,7 +4269,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#addClass - * @function + * @kind function * @description Adds the provided className CSS class value to the provided element. Once * complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will have the className value @@ -4195,7 +4292,7 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#removeClass - * @function + * @kind function * @description Removes the provided className CSS class value from the provided element. * Once complete, the done() callback will be fired (if provided). * @param {DOMElement} element the element which will have the className value @@ -4218,10 +4315,10 @@ var $AnimateProvider = ['$provide', function($provide) { * * @ngdoc method * @name $animate#setClass - * @function + * @kind function * @description Adds and/or removes the given CSS classes to and from the element. * Once complete, the done() callback will be fired (if provided). - * @param {DOMElement} element the element which will it's CSS classes changed + * @param {DOMElement} element the element which will have its CSS classes changed * removed from it * @param {string} add the CSS classes which will be added to the element * @param {string} remove the CSS class which will be removed from the element @@ -4485,6 +4582,13 @@ function Browser(window, document, $log, $sniffer) { return callback; }; + /** + * Checks whether the url has changed outside of Angular. + * Needs to be exported to be able to check for changes that have been done in sync, + * as hashchange/popstate events fire in async. + */ + self.$$checkUrlChange = fireUrlChange; + ////////////////////////////////////////////////////////////// // Misc API ////////////////////////////////////////////////////////////// @@ -4701,8 +4805,10 @@ function $BrowserProvider(){ $scope.keys = []; $scope.cache = $cacheFactory('cacheId'); $scope.put = function(key, value) { - $scope.cache.put(key, value); - $scope.keys.push(key); + if ($scope.cache.get(key) === undefined) { + $scope.keys.push(key); + } + $scope.cache.put(key, value === undefined ? null : value); }; }]); @@ -4775,7 +4881,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#put - * @function + * @kind function * * @description * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be @@ -4811,7 +4917,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#get - * @function + * @kind function * * @description * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object. @@ -4835,7 +4941,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#remove - * @function + * @kind function * * @description * Removes an entry from the {@link $cacheFactory.Cache Cache} object. @@ -4863,7 +4969,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#removeAll - * @function + * @kind function * * @description * Clears the cache object of any entries. @@ -4879,7 +4985,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#destroy - * @function + * @kind function * * @description * Destroys the {@link $cacheFactory.Cache Cache} object entirely, @@ -4896,7 +5002,7 @@ function $CacheFactoryProvider() { /** * @ngdoc method * @name $cacheFactory.Cache#info - * @function + * @kind function * * @description * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}. @@ -4951,7 +5057,7 @@ function $CacheFactoryProvider() { * @name $cacheFactory#info * * @description - * Get information about all the of the caches that have been created + * Get information about all the caches that have been created * * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info` */ @@ -5052,7 +5158,7 @@ function $TemplateCacheProvider() { /** * @ngdoc service * @name $compile - * @function + * @kind function * * @description * Compiles an HTML string or DOM into a template and produces a template function, which @@ -5090,7 +5196,6 @@ function $TemplateCacheProvider() { * template: '
', // or // function(tElement, tAttrs) { ... }, * // or * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, - * replace: false, * transclude: false, * restrict: 'A', * scope: false, @@ -5194,7 +5299,7 @@ function $TemplateCacheProvider() { * local name. Given `` and widget definition of * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to * a function wrapper for the `count = count + value` expression. Often it's desirable to - * pass data from the isolated scope via an expression and to the parent scope, this can be + * pass data from the isolated scope via an expression to the parent scope, this can be * done by passing a map of local variable names and values into the expression wrapper fn. * For example, if the expression is `increment(amount)` then we can specify the amount value * by calling the `localFn` as `localFn({amount: 22})`. @@ -5223,9 +5328,9 @@ function $TemplateCacheProvider() { * * * (no prefix) - Locate the required controller on the current element. Throw an error if not found. * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found. - * * `^` - Locate the required controller by searching the element's parents. Throw an error if not found. - * * `?^` - Attempt to locate the required controller by searching the element's parents or pass `null` to the - * `link` fn if not found. + * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found. + * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass + * `null` to the `link` fn if not found. * * * #### `controllerAs` @@ -5245,14 +5350,16 @@ function $TemplateCacheProvider() { * * * #### `template` - * replace the current element with the contents of the HTML. The replacement process - * migrates all of the attributes / classes from the old element to the new one. See the - * {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive - * Directives Guide} for an example. + * HTML markup that may: + * * Replace the contents of the directive's element (default). + * * Replace the directive's element itself (if `replace` is true - DEPRECATED). + * * Wrap the contents of the directive's element (if `transclude` is true). + * + * Value may be: * - * You can specify `template` as a string representing the template or as a function which takes - * two arguments `tElement` and `tAttrs` (described in the `compile` function api below) and - * returns a string value representing the template. + * * A string. For example `
{{delete_str}}
`. + * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile` + * function api below) and returns a string value. * * * #### `templateUrl` @@ -5266,12 +5373,15 @@ function $TemplateCacheProvider() { * api/ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}. * * - * #### `replace` - * specify where the template should be inserted. Defaults to `false`. + * #### `replace` ([*DEPRECATED*!], will be removed in next major release) + * specify what the template should replace. Defaults to `false`. * - * * `true` - the template will replace the current element. - * * `false` - the template will replace the contents of the current element. + * * `true` - the template will replace the directive's element. + * * `false` - the template will replace the contents of the directive's element. * + * The replacement process migrates all of the attributes / classes from the old element to the new + * one. See the {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive + * Directives Guide} for an example. * * #### `transclude` * compile the content of the element and make it available to the directive. @@ -5285,6 +5395,11 @@ function $TemplateCacheProvider() { * * `true` - transclude the content of the directive. * * `'element'` - transclude the whole element including any directives defined at lower priority. * + *
+ * **Note:** When testing an element transclude directive you must not place the directive at the root of the + * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives + * Testing Transclusion Directives}. + *
* * #### `compile` * @@ -5293,11 +5408,7 @@ function $TemplateCacheProvider() { * ``` * * The compile function deals with transforming the template DOM. Since most directives do not do - * template transformation, it is not used often. Examples that require compile functions are - * directives that transform template DOM, such as {@link - * api/ng.directive:ngRepeat ngRepeat}, or load the contents - * asynchronously, such as {@link ngRoute.directive:ngView ngView}. The - * compile function takes the following arguments. + * template transformation, it is not used often. The compile function takes the following arguments: * * * `tElement` - template element - The element where the directive has been declared. It is * safe to do template transformation on the element and child elements only. @@ -5418,17 +5529,17 @@ function $TemplateCacheProvider() { * } * ``` * - * Below is an example using `$compileProvider`. + * ## Example * *
* **Note**: Typically directives are registered with `module.directive`. The example below is * to illustrate how `$compile` works. *
* - + -
+


@@ -5535,7 +5645,7 @@ var $compileMinErr = minErr('$compile'); /** * @ngdoc provider * @name $compileProvider - * @function + * @kind function * * @description */ @@ -5543,8 +5653,8 @@ $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider']; function $CompileProvider($provide, $$sanitizeUriProvider) { var hasDirectives = {}, Suffix = 'Directive', - COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, - CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/; + COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/, + CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/; // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes // The assumption is that future DOM event attribute names will begin with @@ -5554,7 +5664,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#directive - * @function + * @kind function * * @description * Register a new directive with the compiler. @@ -5607,7 +5717,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#aHrefSanitizationWhitelist - * @function + * @kind function * * @description * Retrieves or overrides the default regular expression that is used for whitelisting of safe @@ -5637,7 +5747,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compileProvider#imgSrcSanitizationWhitelist - * @function + * @kind function * * @description * Retrieves or overrides the default regular expression that is used for whitelisting of safe @@ -5681,7 +5791,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$addClass - * @function + * @kind function * * @description * Adds the CSS class value specified by the classVal parameter to the element. If animations @@ -5698,7 +5808,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$removeClass - * @function + * @kind function * * @description * Removes the CSS class value specified by the classVal parameter from the element. If @@ -5715,7 +5825,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$updateClass - * @function + * @kind function * * @description * Adds and removes the appropriate CSS class values to the element based on the difference @@ -5803,7 +5913,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { /** * @ngdoc method * @name $compile.directive.Attributes#$observe - * @function + * @kind function * * @description * Observes an interpolated attribute. @@ -5866,7 +5976,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); safeAddClass($compileNodes, 'ng-scope'); - return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){ + return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn){ assertArg(scope, 'scope'); // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart // and sometimes changes the structure of the DOM. @@ -5888,7 +5998,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (cloneConnectFn) cloneConnectFn($linkNode, scope); - if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode); + if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn); return $linkNode; }; } @@ -5935,7 +6045,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { : null; if (nodeLinkFn && nodeLinkFn.scope) { - safeAddClass(jqLite(nodeList[i]), 'ng-scope'); + safeAddClass(attrs.$$element, 'ng-scope'); } childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || @@ -5943,7 +6053,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { !childNodes.length) ? null : compileNodes(childNodes, - nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); + nodeLinkFn ? ( + (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) + && nodeLinkFn.transclude) : transcludeFn); linkFns.push(nodeLinkFn, childLinkFn); linkFnFound = linkFnFound || nodeLinkFn || childLinkFn; @@ -5954,8 +6066,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // return a linking function if we have found anything, null otherwise return linkFnFound ? compositeLinkFn : null; - function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { - var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n; + function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) { + var nodeLinkFn, childLinkFn, node, childScope, i, ii, n, childBoundTranscludeFn; // copy nodeList so that linking doesn't break due to live list updates. var nodeListLength = nodeList.length, @@ -5968,32 +6080,40 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { node = stableNodeList[n]; nodeLinkFn = linkFns[i++]; childLinkFn = linkFns[i++]; - $node = jqLite(node); if (nodeLinkFn) { if (nodeLinkFn.scope) { childScope = scope.$new(); - $node.data('$scope', childScope); + jqLite.data(node, '$scope', childScope); } else { childScope = scope; } - childTranscludeFn = nodeLinkFn.transclude; - if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) { - nodeLinkFn(childLinkFn, childScope, node, $rootElement, - createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn) - ); + + if ( nodeLinkFn.transcludeOnThisElement ) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude, parentBoundTranscludeFn); + + } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) { + childBoundTranscludeFn = parentBoundTranscludeFn; + + } else if (!parentBoundTranscludeFn && transcludeFn) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn); + } else { - nodeLinkFn(childLinkFn, childScope, node, $rootElement, boundTranscludeFn); + childBoundTranscludeFn = null; } + + nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn); + } else if (childLinkFn) { - childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn); + childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn); } } } } - function createBoundTranscludeFn(scope, transcludeFn) { - return function boundTranscludeFn(transcludedScope, cloneFn, controllers) { + function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) { + + var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) { var scopeCreated = false; if (!transcludedScope) { @@ -6002,12 +6122,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { scopeCreated = true; } - var clone = transcludeFn(transcludedScope, cloneFn, controllers); + var clone = transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn); if (scopeCreated) { - clone.on('$destroy', bind(transcludedScope, transcludedScope.$destroy)); + clone.on('$destroy', function() { transcludedScope.$destroy(); }); } return clone; }; + + return boundTranscludeFn; } /** @@ -6033,7 +6155,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective); // iterate over the attributes - for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes, + for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes, j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) { var attrStartName = false; var attrEndName = false; @@ -6041,9 +6163,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { attr = nAttrs[j]; if (!msie || msie >= 8 || attr.specified) { name = attr.name; + value = trim(attr.value); + // support ngAttr attribute binding ngAttrName = directiveNormalize(name); - if (NG_ATTR_BINDING.test(ngAttrName)) { + if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) { name = snake_case(ngAttrName.substr(6), '-'); } @@ -6056,9 +6180,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { nName = directiveNormalize(name.toLowerCase()); attrsMap[nName] = name; - attrs[nName] = value = trim(attr.value); - if (getBooleanAttrName(node, nName)) { - attrs[nName] = true; // presence means true + if (isNgAttr || !attrs.hasOwnProperty(nName)) { + attrs[nName] = value; + if (getBooleanAttrName(node, nName)) { + attrs[nName] = true; // presence means true + } } addAttrInterpolateDirective(node, directives, value, nName); addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, @@ -6185,6 +6311,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { templateDirective = previousCompileContext.templateDirective, nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, hasTranscludeDirective = false, + hasTemplate = false, hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective, $compileNode = templateAttrs.$$element = jqLite(compileNode), directive, @@ -6249,12 +6376,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (directiveValue == 'element') { hasElementTranscludeDirective = true; terminalPriority = directive.priority; - $template = groupScan(compileNode, attrStart, attrEnd); + $template = $compileNode; $compileNode = templateAttrs.$$element = jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' ')); compileNode = $compileNode[0]; - replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode); + replaceWith(jqCollection, sliceArgs($template), compileNode); childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, { @@ -6275,6 +6402,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (directive.template) { + hasTemplate = true; assertNoDuplicate('template', templateDirective, directive, $compileNode); templateDirective = directive; @@ -6289,7 +6417,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(directiveValue)) { $template = []; } else { - $template = jqLite(directiveValue); + $template = jqLite(trim(directiveValue)); } compileNode = $template[0]; @@ -6324,6 +6452,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (directive.templateUrl) { + hasTemplate = true; assertNoDuplicate('template', templateDirective, directive, $compileNode); templateDirective = directive; @@ -6332,7 +6461,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, - templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, { + templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, { controllerDirectives: controllerDirectives, newIsolateScopeDirective: newIsolateScopeDirective, templateDirective: templateDirective, @@ -6360,7 +6489,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; - nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn; + nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective; + nodeLinkFn.templateOnThisElement = hasTemplate; + nodeLinkFn.transclude = childTranscludeFn; + previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective; // might be normal or delayed nodeLinkFn depending on if templateUrl is present @@ -6372,6 +6504,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (pre) { if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd); pre.require = directive.require; + pre.directiveName = directiveName; if (newIsolateScopeDirective === directive || directive.$$isolateScope) { pre = cloneAndAnnotateFn(pre, {isolateScope: true}); } @@ -6380,6 +6513,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (post) { if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd); post.require = directive.require; + post.directiveName = directiveName; if (newIsolateScopeDirective === directive || directive.$$isolateScope) { post = cloneAndAnnotateFn(post, {isolateScope: true}); } @@ -6388,7 +6522,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function getControllers(require, $element, elementControllers) { + function getControllers(directiveName, require, $element, elementControllers) { var value, retrievalMethod = 'data', optional = false; if (isString(require)) { while((value = require.charAt(0)) == '^' || value == '?') { @@ -6414,7 +6548,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } else if (isArray(require)) { value = []; forEach(require, function(require) { - value.push(getControllers(require, $element, elementControllers)); + value.push(getControllers(directiveName, require, $element, elementControllers)); }); } return value; @@ -6424,28 +6558,26 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn; - if (compileNode === linkNode) { - attrs = templateAttrs; - } else { - attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); - } + attrs = (compileNode === linkNode) + ? templateAttrs + : shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr)); $element = attrs.$$element; if (newIsolateScopeDirective) { var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/; - var $linkNode = jqLite(linkNode); isolateScope = scope.$new(true); - if (templateDirective && (templateDirective === newIsolateScopeDirective.$$originalDirective)) { - $linkNode.data('$isolateScope', isolateScope) ; + if (templateDirective && (templateDirective === newIsolateScopeDirective || + templateDirective === newIsolateScopeDirective.$$originalDirective)) { + $element.data('$isolateScope', isolateScope); } else { - $linkNode.data('$isolateScopeNoTemplate', isolateScope); + $element.data('$isolateScopeNoTemplate', isolateScope); } - safeAddClass($linkNode, 'ng-isolate-scope'); + safeAddClass($element, 'ng-isolate-scope'); forEach(newIsolateScopeDirective.scope, function(definition, scopeName) { var match = definition.match(LOCAL_REGEXP) || [], @@ -6479,7 +6611,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (parentGet.literal) { compare = equals; } else { - compare = function(a,b) { return a === b; }; + compare = function(a,b) { return a === b || (a !== a && b !== b); }; } parentSet = parentGet.assign || function() { // reset the change, or we will throw this exception on every $digest @@ -6557,7 +6689,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { try { linkFn = preLinkFns[i]; linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, - linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); } catch (e) { $exceptionHandler(e, startingTag($element)); } @@ -6577,7 +6709,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { try { linkFn = postLinkFns[i]; linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, - linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn); + linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); } catch (e) { $exceptionHandler(e, startingTag($element)); } @@ -6663,7 +6795,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // reapply the old attributes to the new element forEach(dst, function(value, key) { if (key.charAt(0) != '$') { - if (src[key]) { + if (src[key] && src[key] !== value) { value += (key === 'style' ? ';' : ' ') + src[key]; } dst.$set(key, value, true, srcAttr[key]); @@ -6716,7 +6848,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(content)) { $template = []; } else { - $template = jqLite(content); + $template = jqLite(trim(content)); } compileNode = $template[0]; @@ -6752,7 +6884,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn); - while(linkQueue.length) { var scope = linkQueue.shift(), beforeTemplateLinkNode = linkQueue.shift(), @@ -6774,8 +6905,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // Copy in CSS classes from original node safeAddClass(jqLite(linkNode), oldClasses); } - if (afterTemplateNodeLinkFn.transclude) { - childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude); + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); } else { childBoundTranscludeFn = boundTranscludeFn; } @@ -6789,13 +6920,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) { + var childBoundTranscludeFn = boundTranscludeFn; if (linkQueue) { linkQueue.push(scope); linkQueue.push(node); linkQueue.push(rootElement); - linkQueue.push(boundTranscludeFn); + linkQueue.push(childBoundTranscludeFn); } else { - afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn); + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { + childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); + } + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn); } }; } @@ -6820,23 +6955,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function addTextInterpolateDirective(directives, text) { - var interpolateFn = $interpolate(text, true); - if (interpolateFn) { - directives.push({ - priority: 0, - compile: valueFn(function textInterpolateLinkFn(scope, node) { - var parent = node.parent(), - bindings = parent.data('$binding') || []; - bindings.push(interpolateFn); - safeAddClass(parent.data('$binding', bindings), 'ng-binding'); - scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { - node[0].nodeValue = value; - }); - }) - }); + function addTextInterpolateDirective(directives, text) { + var interpolateFn = $interpolate(text, true); + if (interpolateFn) { + directives.push({ + priority: 0, + compile: function textInterpolateCompileFn(templateNode) { + // when transcluding a template that has bindings in the root + // then we don't have a parent and should do this in the linkFn + var parent = templateNode.parent(), hasCompileParent = parent.length; + if (hasCompileParent) safeAddClass(templateNode.parent(), 'ng-binding'); + + return function textInterpolateLinkFn(scope, node) { + var parent = node.parent(), + bindings = parent.data('$binding') || []; + bindings.push(interpolateFn); + parent.data('$binding', bindings); + if (!hasCompileParent) safeAddClass(parent, 'ng-binding'); + scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { + node[0].nodeValue = value; + }); + }; + } + }); + } } - } function getTrustedContext(node, attrNormalizedName) { @@ -6997,21 +7140,25 @@ function directiveNormalize(name) { * element attributes. The values reflect current binding state `{{ }}`. The normalization is * needed since all of these are treated as equivalent in Angular: * + * ``` * + * ``` */ /** * @ngdoc property * @name $compile.directive.Attributes#$attr - * @returns {object} A map of DOM element attribute names to the normalized name. This is - * needed to do reverse lookup from normalized name back to actual name. + * + * @description + * A map of DOM element attribute names to the normalized name. This is + * needed to do reverse lookup from normalized name back to actual name. */ /** * @ngdoc method * @name $compile.directive.Attributes#$set - * @function + * @kind function * * @description * Set DOM element attribute value. @@ -7134,7 +7281,7 @@ function $ControllerProvider() { instance = $injector.instantiate(expression, locals); if (identifier) { - if (!(locals && typeof locals.$scope == 'object')) { + if (!(locals && typeof locals.$scope === 'object')) { throw minErr('$controller')('noscp', "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", constructor || expression.name, identifier); @@ -7157,18 +7304,19 @@ function $ControllerProvider() { * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object. * * @example - + -
+

$document title:

window.document title:

- function MainCtrl($scope, $document) { - $scope.title = $document[0].title; - $scope.windowTitle = angular.element(window.document)[0].title; - } + angular.module('documentExample', []) + .controller('ExampleController', ['$scope', '$document', function($scope, $document) { + $scope.title = $document[0].title; + $scope.windowTitle = angular.element(window.document)[0].title; + }]); */ @@ -7235,11 +7383,7 @@ function parseHeaders(headers) { val = trim(line.substr(i + 1)); if (key) { - if (parsed[key]) { - parsed[key] += ', ' + val; - } else { - parsed[key] = val; - } + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; } }); @@ -7301,12 +7445,39 @@ function isSuccess(status) { } +/** + * @ngdoc provider + * @name $httpProvider + * @description + * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service. + * */ function $HttpProvider() { var JSON_START = /^\s*(\[|\{[^\{])/, JSON_END = /[\}\]]\s*$/, PROTECTION_PREFIX = /^\)\]\}',?\n/, CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'}; + /** + * @ngdoc property + * @name $httpProvider#defaults + * @description + * + * Object containing default values for all {@link ng.$http $http} requests. + * + * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token. + * Defaults value is `'XSRF-TOKEN'`. + * + * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the + * XSRF token. Defaults value is `'X-XSRF-TOKEN'`. + * + * - **`defaults.headers`** - {Object} - Default headers for all $http requests. + * Refer to {@link ng.$http#setting-http-headers $http} for documentation on + * setting default headers. + * - **`defaults.headers.common`** + * - **`defaults.headers.post`** + * - **`defaults.headers.put`** + * - **`defaults.headers.patch`** + **/ var defaults = this.defaults = { // transform incoming response data transformResponse: [function(data) { @@ -7329,9 +7500,9 @@ function $HttpProvider() { common: { 'Accept': 'application/json, text/plain, */*' }, - post: copy(CONTENT_TYPE_APPLICATION_JSON), - put: copy(CONTENT_TYPE_APPLICATION_JSON), - patch: copy(CONTENT_TYPE_APPLICATION_JSON) + post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), + patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON) }, xsrfCookieName: 'XSRF-TOKEN', @@ -7470,6 +7641,7 @@ function $HttpProvider() { * - {@link ng.$http#put $http.put} * - {@link ng.$http#delete $http.delete} * - {@link ng.$http#jsonp $http.jsonp} + * - {@link ng.$http#patch $http.patch} * * * # Setting HTTP Headers @@ -7573,14 +7745,14 @@ function $HttpProvider() { * * There are two kinds of interceptors (and two kinds of rejection interceptors): * - * * `request`: interceptors get called with http `config` object. The function is free to - * modify the `config` or create a new one. The function needs to return the `config` - * directly or as a promise. + * * `request`: interceptors get called with a http `config` object. The function is free to + * modify the `config` object or create a new one. The function needs to return the `config` + * object directly, or a promise containing the `config` or a new `config` object. * * `requestError`: interceptor gets called when a previous interceptor threw an error or * resolved with a rejection. * * `response`: interceptors get called with http `response` object. The function is free to - * modify the `response` or create a new one. The function needs to return the `response` - * directly or as a promise. + * modify the `response` object or create a new one. The function needs to return the `response` + * object directly, or as a promise containing the `response` or a new `response` object. * * `responseError`: interceptor gets called when a previous interceptor threw an error or * resolved with a rejection. * @@ -7592,7 +7764,7 @@ function $HttpProvider() { * // optional method * 'request': function(config) { * // do something on success - * return config || $q.when(config); + * return config; * }, * * // optional method @@ -7609,7 +7781,7 @@ function $HttpProvider() { * // optional method * 'response': function(response) { * // do something on success - * return response || $q.when(response); + * return response; * }, * * // optional method @@ -7734,7 +7906,7 @@ function $HttpProvider() { * that only JavaScript running on your domain could have sent the request. The token must be * unique for each user and must be verifiable by the server (to prevent the JavaScript from * making up its own tokens). We recommend that the token is a digest of your site's - * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography)) + * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography)) * for added security. * * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName @@ -7770,8 +7942,8 @@ function $HttpProvider() { * caching. * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} * that should abort the request when resolved. - * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the - * XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5 + * - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the + * XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials) * for more information. * - **responseType** - `{string}` - see * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType). @@ -7796,9 +7968,9 @@ function $HttpProvider() { * * * @example - + -
+

- * Current time is: - *
- * Blood 1 : {{blood_1}} - * Blood 2 : {{blood_2}} - * - * - * - *
+ *
+ *
+ * Date format:
+ * Current time is: + *
+ * Blood 1 : {{blood_1}} + * Blood 2 : {{blood_2}} + * + * + * *
+ *
* - * + * * */ function interval(fn, delay, count, invokeApply) { @@ -8854,7 +9068,7 @@ function $IntervalProvider() { interval.cancel = function(promise) { if (promise && promise.$$intervalId in intervals) { intervals[promise.$$intervalId].reject('canceled'); - clearInterval(promise.$$intervalId); + $window.clearInterval(promise.$$intervalId); delete intervals[promise.$$intervalId]; return true; } @@ -9137,7 +9351,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { Matches paths for file protocol on windows, such as /C:/foo/bar, and captures only /foo/bar. */ - var windowsFilePathExp = /^\/?.*?:(\/.*)/; + var windowsFilePathExp = /^\/[A-Z]:(\/.*)/; var firstPathSegmentMatch; @@ -9146,10 +9360,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { url = url.replace(base, ''); } - /* - * The input URL intentionally contains a - * first path segment that ends with a colon. - */ + // The input URL intentionally contains a first path segment that ends with a colon. if (windowsFilePathExp.exec(url)) { return path; } @@ -9205,6 +9416,16 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) { return appBaseNoFile; } }; + + this.$$compose = function() { + var search = toKeyValue(this.$$search), + hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; + + this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; + // include hashPrefix in $$absUrl when $$url is empty so IE8 & 9 do not reload page because of removal of '#' + this.$$absUrl = appBase + hashPrefix + this.$$url; + }; + } @@ -9250,17 +9471,16 @@ LocationHashbangInHtml5Url.prototype = * Change path, search and hash, when called with parameter and return `$location`. * * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`) - * @param {string=} replace The path that will be changed * @return {string} url */ - url: function(url, replace) { + url: function(url) { if (isUndefined(url)) return this.$$url; var match = PATH_MATCH.exec(url); if (match[1]) this.path(decodeURIComponent(match[1])); if (match[2] || match[1]) this.search(match[3] || ''); - this.hash(match[5] || '', replace); + this.hash(match[5] || ''); return this; }, @@ -9318,10 +9538,11 @@ LocationHashbangInHtml5Url.prototype = * Note: Path should always begin with forward slash (/), this method will add the forward slash * if it is missing. * - * @param {string=} path New path + * @param {(string|number)=} path New path * @return {string} path */ path: locationGetterSetter('$$path', function(path) { + path = path ? path.toString() : ''; return path.charAt(0) == '/' ? path : '/' + path; }), @@ -9336,24 +9557,55 @@ LocationHashbangInHtml5Url.prototype = * * Change search part when called with parameter and return `$location`. * + * + * ```js + * // given url http://example.com/#/some/path?foo=bar&baz=xoxo + * var searchObject = $location.search(); + * // => {foo: 'bar', baz: 'xoxo'} + * + * + * // set foo to 'yipee' + * $location.search('foo', 'yipee'); + * // => $location + * ``` + * * @param {string|Object.|Object.>} search New search params - string or - * hash object. Hash object may contain an array of values, which will be decoded as duplicates in - * the url. + * hash object. + * + * When called with a single argument the method acts as a setter, setting the `search` component + * of `$location` to the specified value. + * + * If the argument is a hash object containing an array of values, these values will be encoded + * as duplicate search parameters in the url. + * + * @param {(string|Number|Array|boolean)=} paramValue If `search` is a string or number, then `paramValue` + * will override only a single search property. + * + * If `paramValue` is an array, it will override the property of the `search` component of + * `$location` specified via the first argument. + * + * If `paramValue` is `null`, the property specified via the first argument will be deleted. * - * @param {(string|Array)=} paramValue If `search` is a string, then `paramValue` will override only a - * single search parameter. If `paramValue` is an array, it will set the parameter as a - * comma-separated value. If `paramValue` is `null`, the parameter will be deleted. + * If `paramValue` is `true`, the property specified via the first argument will be added with no + * value nor trailing equal sign. * - * @return {string} search + * @return {Object} If called with no arguments returns the parsed `search` object. If called with + * one or more arguments returns `$location` object itself. */ search: function(search, paramValue) { switch (arguments.length) { case 0: return this.$$search; case 1: - if (isString(search)) { + if (isString(search) || isNumber(search)) { + search = search.toString(); this.$$search = parseKeyValue(search); } else if (isObject(search)) { + // remove object undefined or null properties + forEach(search, function(value, key) { + if (value == null) delete search[key]; + }); + this.$$search = search; } else { throw $locationMinErr('isrcharg', @@ -9383,10 +9635,12 @@ LocationHashbangInHtml5Url.prototype = * * Change hash fragment when called with parameter and return `$location`. * - * @param {string=} hash New hash fragment + * @param {(string|number)=} hash New hash fragment * @return {string} hash */ - hash: locationGetterSetter('$$hash', identity), + hash: locationGetterSetter('$$hash', function(hash) { + return hash ? hash.toString() : ''; + }), /** * @ngdoc method @@ -9459,7 +9713,7 @@ function $LocationProvider(){ html5Mode = false; /** - * @ngdoc property + * @ngdoc method * @name $locationProvider#hashPrefix * @description * @param {string=} prefix Prefix for hash part (containing path and search) @@ -9475,7 +9729,7 @@ function $LocationProvider(){ }; /** - * @ngdoc property + * @ngdoc method * @name $locationProvider#html5Mode * @description * @param {boolean=} mode Use HTML5 strategy if available. @@ -9535,6 +9789,8 @@ function $LocationProvider(){ $location = new LocationMode(appBase, '#' + hashPrefix); $location.$$parse($location.$$rewrite(initialUrl)); + var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i; + $rootElement.on('click', function(event) { // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) // currently we open nice url link and redirect then @@ -9557,6 +9813,43 @@ function $LocationProvider(){ absHref = urlResolve(absHref.animVal).href; } + // Ignore when url is started with javascript: or mailto: + if (IGNORE_URI_REGEXP.test(absHref)) return; + + // Make relative links work in HTML5 mode for legacy browsers (or at least IE8 & 9) + // The href should be a regular url e.g. /link/somewhere or link/somewhere or ../somewhere or + // somewhere#anchor or http://example.com/somewhere + if (LocationMode === LocationHashbangInHtml5Url) { + // get the actual href attribute - see + // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx + var href = elm.attr('href') || elm.attr('xlink:href'); + + if (href && href.indexOf('://') < 0) { // Ignore absolute URLs + var prefix = '#' + hashPrefix; + if (href[0] == '/') { + // absolute path - replace old path + absHref = appBase + prefix + href; + } else if (href[0] == '#') { + // local anchor + absHref = appBase + prefix + ($location.path() || '/') + href; + } else { + // relative path - join with current path + var stack = $location.path().split("/"), + parts = href.split("/"); + if (stack.length === 2 && !stack[1]) stack.length = 1; + for (var i=0; i + - function LogCtrl($scope, $log) { - $scope.$log = $log; - $scope.message = 'Hello World!'; - } + angular.module('logExample', []) + .controller('LogController', ['$scope', '$log', function($scope, $log) { + $scope.$log = $log; + $scope.message = 'Hello World!'; + }]); -
+

Reload this page with open console, enter text and hit the log button...

Message: @@ -9674,7 +9968,7 @@ function $LogProvider(){ self = this; /** - * @ngdoc property + * @ngdoc method * @name $logProvider#debugEnabled * @description * @param {boolean=} flag enable or disable debug level messages @@ -9800,14 +10094,7 @@ var promiseWarning; // // As an example, consider the following Angular expression: // -// {}.toString.constructor(alert("evil JS code")) -// -// We want to prevent this type of access. For the sake of performance, during the lexing phase we -// disallow any "dotted" access to any member named "constructor". -// -// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor -// while evaluating the expression, which is a stronger but more expensive test. Since reflective -// calls are expensive anyway, this is not such a big deal compared to static dereferencing. +// {}.toString.constructor('alert("evil JS code")') // // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits // against the expression language, but not to prevent exploits that were enabled by exposing @@ -9815,17 +10102,19 @@ var promiseWarning; // practice and therefore we are not even trying to protect against interaction with an object // explicitly exposed in this way. // -// A developer could foil the name check by aliasing the Function constructor under a different -// name on the scope. -// // In general, it is not possible to access a Window object from an angular expression unless a // window or some DOM object that has a reference to window is published onto a Scope. +// Similarly we prevent invocations of function known to be dangerous, as well as assignments to +// native objects. + function ensureSafeMemberName(name, fullExpression) { - if (name === "constructor") { + if (name === "__defineGetter__" || name === "__defineSetter__" + || name === "__lookupGetter__" || name === "__lookupSetter__" + || name === "__proto__") { throw $parseMinErr('isecfld', - 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', - fullExpression); + 'Attempting to access a disallowed field in Angular expressions! ' + +'Expression: {0}', fullExpression); } return name; } @@ -9847,11 +10136,34 @@ function ensureSafeObject(obj, fullExpression) { throw $parseMinErr('isecdom', 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', fullExpression); + } else if (// block Object so that we can't get hold of dangerous Object.* methods + obj === Object) { + throw $parseMinErr('isecobj', + 'Referencing Object in Angular expressions is disallowed! Expression: {0}', + fullExpression); } } return obj; } +var CALL = Function.prototype.call; +var APPLY = Function.prototype.apply; +var BIND = Function.prototype.bind; + +function ensureSafeFunction(obj, fullExpression) { + if (obj) { + if (obj.constructor === obj) { + throw $parseMinErr('isecfn', + 'Referencing Function in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } else if (obj === CALL || obj === APPLY || (BIND && obj === BIND)) { + throw $parseMinErr('isecff', + 'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } + } +} + var OPERATORS = { /* jshint bitwise : false */ 'null':function(){return null;}, @@ -9917,9 +10229,6 @@ Lexer.prototype = { this.tokens = []; - var token; - var json = []; - while (this.index < this.text.length) { this.ch = this.text.charAt(this.index); if (this.is('"\'')) { @@ -9928,19 +10237,11 @@ Lexer.prototype = { this.readNumber(); } else if (this.isIdent(this.ch)) { this.readIdent(); - // identifiers can only be if the preceding char was a { or , - if (this.was('{,') && json[0] === '{' && - (token = this.tokens[this.tokens.length - 1])) { - token.json = token.text.indexOf('.') === -1; - } } else if (this.is('(){}[].,;:?')) { this.tokens.push({ index: this.index, - text: this.ch, - json: (this.was(':[,') && this.is('{[')) || this.is('}]:,') + text: this.ch }); - if (this.is('{[')) json.unshift(this.ch); - if (this.is('}]')) json.shift(); this.index++; } else if (this.isWhitespace(this.ch)) { this.index++; @@ -9961,8 +10262,7 @@ Lexer.prototype = { this.tokens.push({ index: this.index, text: this.ch, - fn: fn, - json: (this.was('[,:') && this.is('+-')) + fn: fn }); this.index += 1; } else { @@ -10045,7 +10345,8 @@ Lexer.prototype = { this.tokens.push({ index: start, text: number, - json: true, + literal: true, + constant: true, fn: function() { return number; } }); }, @@ -10097,7 +10398,8 @@ Lexer.prototype = { // OPERATORS is our own object so we don't need to use special hasOwnPropertyFn if (OPERATORS.hasOwnProperty(ident)) { token.fn = OPERATORS[ident]; - token.json = OPERATORS[ident]; + token.literal = true; + token.constant = true; } else { var getter = getterFn(ident, this.options, this.text); token.fn = extend(function(self, locals) { @@ -10114,13 +10416,11 @@ Lexer.prototype = { if (methodName) { this.tokens.push({ index:lastDot, - text: '.', - json: false + text: '.' }); this.tokens.push({ index: lastDot + 1, - text: methodName, - json: false + text: methodName }); } }, @@ -10143,11 +10443,7 @@ Lexer.prototype = { string += String.fromCharCode(parseInt(hex, 16)); } else { var rep = ESCAPE[ch]; - if (rep) { - string += rep; - } else { - string += ch; - } + string = string + (rep || ch); } escape = false; } else if (ch === '\\') { @@ -10158,7 +10454,8 @@ Lexer.prototype = { index: start, text: rawString, string: string, - json: true, + literal: true, + constant: true, fn: function() { return string; } }); return; @@ -10190,28 +10487,12 @@ Parser.ZERO = extend(function () { Parser.prototype = { constructor: Parser, - parse: function (text, json) { + parse: function (text) { this.text = text; - //TODO(i): strip all the obsolte json stuff from this file - this.json = json; - this.tokens = this.lexer.lex(text); - if (json) { - // The extra level of aliasing is here, just in case the lexer misses something, so that - // we prevent any accidental execution in JSON. - this.assignment = this.logicalOR; - - this.functionCall = - this.fieldAccess = - this.objectIndex = - this.filterChain = function() { - this.throwError('is not valid json', {text: text, index: 0}); - }; - } - - var value = json ? this.primary() : this.statements(); + var value = this.statements(); if (this.tokens.length !== 0) { this.throwError('is an unexpected token', this.tokens[0]); @@ -10238,10 +10519,8 @@ Parser.prototype = { if (!primary) { this.throwError('not a primary expression', token); } - if (token.json) { - primary.constant = true; - primary.literal = true; - } + primary.literal = !!token.literal; + primary.constant = !!token.constant; } var next, context; @@ -10289,9 +10568,6 @@ Parser.prototype = { expect: function(e1, e2, e3, e4){ var token = this.peek(e1, e2, e3, e4); if (token) { - if (this.json && !token.json) { - this.throwError('is not valid json', token); - } this.tokens.shift(); return token; } @@ -10412,9 +10688,9 @@ Parser.prototype = { var middle; var token; if ((token = this.expect('?'))) { - middle = this.ternary(); + middle = this.assignment(); if ((token = this.expect(':'))) { - return this.ternaryFn(left, middle, this.ternary()); + return this.ternaryFn(left, middle, this.assignment()); } else { this.throwError('expected :', token); } @@ -10502,7 +10778,9 @@ Parser.prototype = { return getter(self || object(scope, locals)); }, { assign: function(scope, value, locals) { - return setter(object(scope, locals), field, value, parser.text, parser.options); + var o = object(scope, locals); + if (!o) object.assign(scope, o = {}); + return setter(o, field, value, parser.text, parser.options); } }); }, @@ -10518,6 +10796,7 @@ Parser.prototype = { i = indexFn(self, locals), v, p; + ensureSafeMemberName(i, parser.text); if (!o) return undefined; v = ensureSafeObject(o[i], parser.text); if (v && v.then && parser.options.unwrapPromises) { @@ -10531,10 +10810,11 @@ Parser.prototype = { return v; }, { assign: function(self, value, locals) { - var key = indexFn(self, locals); + var key = ensureSafeMemberName(indexFn(self, locals), parser.text); // prevent overwriting of Function.constructor which would break ensureSafeObject check - var safe = ensureSafeObject(obj(self, locals), parser.text); - return safe[key] = value; + var o = ensureSafeObject(obj(self, locals), parser.text); + if (!o) obj.assign(self, o = {}); + return o[key] = value; } }); }, @@ -10555,12 +10835,12 @@ Parser.prototype = { var context = contextGetter ? contextGetter(scope, locals) : scope; for (var i = 0; i < argsFn.length; i++) { - args.push(argsFn[i](scope, locals)); + args.push(ensureSafeObject(argsFn[i](scope, locals), parser.text)); } var fnPtr = fn(scope, locals, context) || noop; ensureSafeObject(context, parser.text); - ensureSafeObject(fnPtr, parser.text); + ensureSafeFunction(fnPtr, parser.text); // IE stupidity! (IE doesn't have apply for some native functions) var v = fnPtr.apply @@ -10643,13 +10923,15 @@ Parser.prototype = { ////////////////////////////////////////////////// function setter(obj, path, setValue, fullExp, options) { + ensureSafeObject(obj, fullExp); + //needed? options = options || {}; var element = path.split('.'), key; for (var i = 0; element.length > 1; i++) { key = ensureSafeMemberName(element.shift(), fullExp); - var propertyObj = obj[key]; + var propertyObj = ensureSafeObject(obj[key], fullExp); if (!propertyObj) { propertyObj = {}; obj[key] = propertyObj; @@ -10669,6 +10951,7 @@ function setter(obj, path, setValue, fullExp, options) { } } key = ensureSafeMemberName(element.shift(), fullExp); + ensureSafeObject(obj[key], fullExp); obj[key] = setValue; return setValue; } @@ -10784,26 +11067,6 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) { }; } -function simpleGetterFn1(key0, fullExp) { - ensureSafeMemberName(key0, fullExp); - - return function simpleGetterFn1(scope, locals) { - if (scope == null) return undefined; - return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; - }; -} - -function simpleGetterFn2(key0, key1, fullExp) { - ensureSafeMemberName(key0, fullExp); - ensureSafeMemberName(key1, fullExp); - - return function simpleGetterFn2(scope, locals) { - if (scope == null) return undefined; - scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0]; - return scope == null ? undefined : scope[key1]; - }; -} - function getterFn(path, options, fullExp) { // Check whether the cache has this getter already. // We can use hasOwnProperty directly on the cache because we ensure, @@ -10816,13 +11079,8 @@ function getterFn(path, options, fullExp) { pathKeysLength = pathKeys.length, fn; - // When we have only 1 or 2 tokens, use optimized special case closures. // http://jsperf.com/angularjs-parse-getter/6 - if (!options.unwrapPromises && pathKeysLength === 1) { - fn = simpleGetterFn1(pathKeys[0], fullExp); - } else if (!options.unwrapPromises && pathKeysLength === 2) { - fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp); - } else if (options.csp) { + if (options.csp) { if (pathKeysLength < 6) { fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, options); @@ -10926,7 +11184,7 @@ function getterFn(path, options, fullExp) { /** * @ngdoc provider * @name $parseProvider - * @function + * @kind function * * @description * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} @@ -11045,7 +11303,7 @@ function $ParseProvider() { var lexer = new Lexer($parseOptions); var parser = new Parser(lexer, $filter, $parseOptions); - parsedExpression = parser.parse(exp, false); + parsedExpression = parser.parse(exp); if (exp !== 'hasOwnProperty') { // Only cache the value if it's not going to mess up the cache object @@ -11088,17 +11346,13 @@ function $ParseProvider() { * var deferred = $q.defer(); * * setTimeout(function() { - * // since this fn executes async in a future turn of the event loop, we need to wrap - * // our code into an $apply call so that the model changes are properly observed. - * scope.$apply(function() { - * deferred.notify('About to greet ' + name + '.'); - * - * if (okToGreet(name)) { - * deferred.resolve('Hello, ' + name + '!'); - * } else { - * deferred.reject('Greeting ' + name + ' is not allowed.'); - * } - * }); + * deferred.notify('About to greet ' + name + '.'); + * + * if (okToGreet(name)) { + * deferred.resolve('Hello, ' + name + '!'); + * } else { + * deferred.reject('Greeting ' + name + ' is not allowed.'); + * } * }, 1000); * * return deferred.promise; @@ -11256,7 +11510,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#defer - * @function + * @kind function * * @description * Creates a `Deferred` object which represents a task which will finish in the future. @@ -11372,7 +11626,7 @@ function qFactory(nextTick, exceptionHandler) { } catch(e) { return makePromise(e, false); } - if (callbackOutput && isFunction(callbackOutput.then)) { + if (isPromiseLike(callbackOutput)) { return callbackOutput.then(function() { return makePromise(value, isResolved); }, function(error) { @@ -11397,7 +11651,7 @@ function qFactory(nextTick, exceptionHandler) { var ref = function(value) { - if (value && isFunction(value.then)) return value; + if (isPromiseLike(value)) return value; return { then: function(callback) { var result = defer(); @@ -11413,7 +11667,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#reject - * @function + * @kind function * * @description * Creates a promise that is resolved as rejected with the specified `reason`. This api should be @@ -11473,7 +11727,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#when - * @function + * @kind function * * @description * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. @@ -11545,7 +11799,7 @@ function qFactory(nextTick, exceptionHandler) { /** * @ngdoc method * @name $q#all - * @function + * @kind function * * @description * Combines multiple promises into a single promise that is resolved when all of the input @@ -11636,7 +11890,7 @@ function $$RAFProvider(){ //rAF * * Loop operations are optimized by using while(count--) { ... } * - this means that in order to keep the same order of execution as addition we have to add - * items to the array at the beginning (shift) instead of at the end (push) + * items to the array at the beginning (unshift) instead of at the end (push) * * Child scopes are created and removed often * - Using an array would be slow since inserts in middle are expensive so we use linked list @@ -11760,24 +12014,39 @@ function $RootScopeProvider(){ /** * @ngdoc property * @name $rootScope.Scope#$id - * @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for - * debugging. + * + * @description + * Unique scope ID (monotonically increasing) useful for debugging. */ + /** + * @ngdoc property + * @name $rootScope.Scope#$parent + * + * @description + * Reference to the parent scope. + */ + + /** + * @ngdoc property + * @name $rootScope.Scope#$root + * + * @description + * Reference to the root scope. + */ Scope.prototype = { constructor: Scope, /** * @ngdoc method * @name $rootScope.Scope#$new - * @function + * @kind function * * @description * Creates a new child {@link ng.$rootScope.Scope scope}. * - * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} and - * {@link ng.$rootScope.Scope#$digest $digest()} events. The scope can be removed from the - * scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. + * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event. + * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. * * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is * desired for the scope and its child scopes to be permanently detached from the parent and @@ -11802,18 +12071,23 @@ function $RootScopeProvider(){ child.$$asyncQueue = this.$$asyncQueue; child.$$postDigestQueue = this.$$postDigestQueue; } else { - ChildScope = function() {}; // should be anonymous; This is so that when the minifier munges - // the name it does not become random set of chars. This will then show up as class - // name in the web inspector. - ChildScope.prototype = this; - child = new ChildScope(); - child.$id = nextUid(); + // Only create a child scope class if somebody asks for one, + // but cache it to allow the VM to optimize lookups. + if (!this.$$childScopeClass) { + this.$$childScopeClass = function() { + this.$$watchers = this.$$nextSibling = + this.$$childHead = this.$$childTail = null; + this.$$listeners = {}; + this.$$listenerCount = {}; + this.$id = nextUid(); + this.$$childScopeClass = null; + }; + this.$$childScopeClass.prototype = this; + } + child = new this.$$childScopeClass(); } child['this'] = child; - child.$$listeners = {}; - child.$$listenerCount = {}; child.$parent = this; - child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null; child.$$prevSibling = this.$$childTail; if (this.$$childHead) { this.$$childTail.$$nextSibling = child; @@ -11827,7 +12101,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$watch - * @function + * @kind function * * @description * Registers a `listener` callback to be executed whenever the `watchExpression` changes. @@ -11839,10 +12113,14 @@ function $RootScopeProvider(){ * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) * - The `listener` is called only when the value from the current `watchExpression` and the * previous call to `watchExpression` are not equal (with the exception of the initial run, - * see below). The inequality is determined according to - * {@link angular.equals} function. To save the value of the object for later comparison, - * the {@link angular.copy} function is used. It also means that watching complex options - * will have adverse memory and performance implications. + * see below). Inequality is determined according to reference inequality, + * [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) + * via the `!==` Javascript operator, unless `objectEquality == true` + * (see next point) + * - When `objectEquality == true`, inequality of the `watchExpression` is determined + * according to the {@link angular.equals} function. To save the value of the object for + * later comparison, the {@link angular.copy} function is used. This therefore means that + * watching complex objects will have adverse memory and performance implications. * - The watch `listener` may change the model, which may trigger other `listener`s to fire. * This is achieved by rerunning the watchers until no changes are detected. The rerun * iteration limit is 10 to prevent an infinite loop deadlock. @@ -11877,13 +12155,17 @@ function $RootScopeProvider(){ expect(scope.counter).toEqual(0); scope.$digest(); - // no variable change - expect(scope.counter).toEqual(0); + // the listener is always called during the first $digest loop after it was registered + expect(scope.counter).toEqual(1); - scope.name = 'adam'; scope.$digest(); + // but now it will not be called unless the value changes expect(scope.counter).toEqual(1); + scope.name = 'adam'; + scope.$digest(); + expect(scope.counter).toEqual(2); + // Using a listener function @@ -11969,7 +12251,7 @@ function $RootScopeProvider(){ // the while loop reads in reverse order. array.unshift(watcher); - return function() { + return function deregisterWatch() { arrayRemove(array, watcher); lastDirtyWatch = null; }; @@ -11979,7 +12261,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$watchCollection - * @function + * @kind function * * @description * Shallow watches the properties of an object and fires whenever any of the properties change @@ -12051,7 +12333,7 @@ function $RootScopeProvider(){ function $watchCollectionWatch() { newValue = objGetter(self); - var newLength, key; + var newLength, key, bothNaN; if (!isObject(newValue)) { // if primitive if (oldValue !== newValue) { @@ -12075,7 +12357,7 @@ function $RootScopeProvider(){ } // copy the items to oldValue and look for changes. for (var i = 0; i < newLength; i++) { - var bothNaN = (oldValue[i] !== oldValue[i]) && + bothNaN = (oldValue[i] !== oldValue[i]) && (newValue[i] !== newValue[i]); if (!bothNaN && (oldValue[i] !== newValue[i])) { changeDetected++; @@ -12095,7 +12377,9 @@ function $RootScopeProvider(){ if (newValue.hasOwnProperty(key)) { newLength++; if (oldValue.hasOwnProperty(key)) { - if (oldValue[key] !== newValue[key]) { + bothNaN = (oldValue[key] !== oldValue[key]) && + (newValue[key] !== newValue[key]); + if (!bothNaN && (oldValue[key] !== newValue[key])) { changeDetected++; oldValue[key] = newValue[key]; } @@ -12155,7 +12439,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$digest - * @function + * @kind function * * @description * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and @@ -12190,12 +12474,16 @@ function $RootScopeProvider(){ expect(scope.counter).toEqual(0); scope.$digest(); - // no variable change - expect(scope.counter).toEqual(0); + // the listener is always called during the first $digest loop after it was registered + expect(scope.counter).toEqual(1); - scope.name = 'adam'; scope.$digest(); + // but now it will not be called unless the value changes expect(scope.counter).toEqual(1); + + scope.name = 'adam'; + scope.$digest(); + expect(scope.counter).toEqual(2); * ``` * */ @@ -12211,6 +12499,8 @@ function $RootScopeProvider(){ logIdx, logMsg, asyncTask; beginPhase('$digest'); + // Check for changes to browser url that happened in sync before the call to $digest + $browser.$$checkUrlChange(); lastDirtyWatch = null; @@ -12243,11 +12533,11 @@ function $RootScopeProvider(){ if ((value = watch.get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) - : (typeof value == 'number' && typeof last == 'number' + : (typeof value === 'number' && typeof last === 'number' && isNaN(value) && isNaN(last)))) { dirty = true; lastDirtyWatch = watch; - watch.last = watch.eq ? copy(value) : value; + watch.last = watch.eq ? copy(value, null) : value; watch.fn(value, ((last === initWatchVal) ? value : last), current); if (ttl < 5) { logIdx = 4 - ttl; @@ -12322,7 +12612,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$destroy - * @function + * @kind function * * @description * Removes the current scope (and all of its children) from the parent scope. Removal implies @@ -12383,7 +12673,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$eval - * @function + * @kind function * * @description * Executes the `expression` on the current scope and returns the result. Any exceptions in @@ -12415,7 +12705,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$evalAsync - * @function + * @kind function * * @description * Executes the expression on the current scope at a later point in time. @@ -12462,7 +12752,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$apply - * @function + * @kind function * * @description * `$apply()` is used to execute an expression in angular from outside of the angular @@ -12524,7 +12814,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$on - * @function + * @kind function * * @description * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for @@ -12573,7 +12863,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$emit - * @function + * @kind function * * @description * Dispatches an event `name` upwards through the scope hierarchy notifying the @@ -12641,7 +12931,7 @@ function $RootScopeProvider(){ /** * @ngdoc method * @name $rootScope.Scope#$broadcast - * @function + * @kind function * * @description * Dispatches an event `name` downwards to all child scopes (and their children) notifying the @@ -12757,7 +13047,7 @@ function $RootScopeProvider(){ */ function $$SanitizeUriProvider() { var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/, - imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//; + imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file):|data:image\/)/; /** * @description @@ -12889,7 +13179,7 @@ function adjustMatchers(matchers) { /** * @ngdoc service * @name $sceDelegate - * @function + * @kind function * * @description * @@ -12936,19 +13226,21 @@ function adjustMatchers(matchers) { * * Here is what a secure configuration for this scenario might look like: * - *
- *    angular.module('myApp', []).config(function($sceDelegateProvider) {
- *      $sceDelegateProvider.resourceUrlWhitelist([
- *        // Allow same origin resource loads.
- *        'self',
- *        // Allow loading from our assets domain.  Notice the difference between * and **.
- *        'http://srv*.assets.example.com/**']);
- *
- *      // The blacklist overrides the whitelist so the open redirect here is blocked.
- *      $sceDelegateProvider.resourceUrlBlacklist([
- *        'http://myapp.example.com/clickThru**']);
- *      });
- * 
+ * ``` + * angular.module('myApp', []).config(function($sceDelegateProvider) { + * $sceDelegateProvider.resourceUrlWhitelist([ + * // Allow same origin resource loads. + * 'self', + * // Allow loading from our assets domain. Notice the difference between * and **. + * 'http://srv*.assets.example.com/**' + * ]); + * + * // The blacklist overrides the whitelist so the open redirect here is blocked. + * $sceDelegateProvider.resourceUrlBlacklist([ + * 'http://myapp.example.com/clickThru**' + * ]); + * }); + * ``` */ function $SceDelegateProvider() { @@ -12961,7 +13253,7 @@ function $SceDelegateProvider() { /** * @ngdoc method * @name $sceDelegateProvider#resourceUrlWhitelist - * @function + * @kind function * * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value * provided. This must be an array or null. A snapshot of this array is used so further @@ -12990,7 +13282,7 @@ function $SceDelegateProvider() { /** * @ngdoc method * @name $sceDelegateProvider#resourceUrlBlacklist - * @function + * @kind function * * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value * provided. This must be an array or null. A snapshot of this array is used so further @@ -13217,7 +13509,7 @@ function $SceDelegateProvider() { /** * @ngdoc service * @name $sce - * @function + * @kind function * * @description * @@ -13243,10 +13535,10 @@ function $SceDelegateProvider() { * * Here's an example of a binding in a privileged context: * - *
- *     
- *     
- *
+ * ``` + * + *
+ * ``` * * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE * disabled, this application allows the user to render arbitrary HTML into the DIV. @@ -13286,15 +13578,15 @@ function $SceDelegateProvider() { * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly * simplified): * - *
- *   var ngBindHtmlDirective = ['$sce', function($sce) {
- *     return function(scope, element, attr) {
- *       scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
- *         element.html(value || '');
- *       });
- *     };
- *   }];
- * 
+ * ``` + * var ngBindHtmlDirective = ['$sce', function($sce) { + * return function(scope, element, attr) { + * scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) { + * element.html(value || ''); + * }); + * }; + * }]; + * ``` * * ## Impact on loading templates * @@ -13343,7 +13635,7 @@ function $SceDelegateProvider() { * * | Context | Notes | * |---------------------|----------------| - * | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. | + * | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. | * | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. | * | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`
Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. | @@ -13367,7 +13659,7 @@ function $SceDelegateProvider() { * - `**`: matches zero or more occurrences of *any* character. As such, it's not * not appropriate to use in for a scheme, domain, etc. as it would match too much. (e.g. * http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might - * not have been the intention.) It's usage at the very end of the path is ok. (e.g. + * not have been the intention.) Its usage at the very end of the path is ok. (e.g. * http://foo.example.com/templates/**). * - **RegExp** (*see caveat below*) * - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax @@ -13398,66 +13690,65 @@ function $SceDelegateProvider() { * * ## Show me an example using SCE. * - * @example - - -
-

- User comments
- By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when - $sanitize is available. If $sanitize isn't available, this results in an error instead of an - exploit. -
-
- {{userComment.name}}: - -
-
-
-
-
- - - var mySceApp = angular.module('mySceApp', ['ngSanitize']); - - mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { - var self = this; - $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { - self.userComments = userComments; - }); - self.explicitlyTrustedHtml = $sce.trustAsHtml( - 'Hover over this text.'); - }); - - - -[ - { "name": "Alice", - "htmlComment": - "Is anyone reading this?" - }, - { "name": "Bob", - "htmlComment": "Yes! Am I the only other one?" - } -] - - - - describe('SCE doc demo', function() { - it('should sanitize untrusted values', function() { - expect(element(by.css('.htmlComment')).getInnerHtml()) - .toBe('Is anyone reading this?'); - }); - - it('should NOT sanitize explicitly trusted values', function() { - expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( - 'Hover over this text.'); - }); - }); - -
+ * + * + *
+ *

+ * User comments
+ * By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when + * $sanitize is available. If $sanitize isn't available, this results in an error instead of an + * exploit. + *
+ *
+ * {{userComment.name}}: + * + *
+ *
+ *
+ *
+ *
+ * + * + * var mySceApp = angular.module('mySceApp', ['ngSanitize']); + * + * mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { + * var self = this; + * $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { + * self.userComments = userComments; + * }); + * self.explicitlyTrustedHtml = $sce.trustAsHtml( + * 'Hover over this text.'); + * }); + * + * + * + * [ + * { "name": "Alice", + * "htmlComment": + * "Is anyone reading this?" + * }, + * { "name": "Bob", + * "htmlComment": "Yes! Am I the only other one?" + * } + * ] + * + * + * + * describe('SCE doc demo', function() { + * it('should sanitize untrusted values', function() { + * expect(element.all(by.css('.htmlComment')).first().getInnerHtml()) + * .toBe('Is anyone reading this?'); + * }); + * + * it('should NOT sanitize explicitly trusted values', function() { + * expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( + * 'Hover over this text.'); + * }); + * }); + * + *
* * * @@ -13471,13 +13762,13 @@ function $SceDelegateProvider() { * * That said, here's how you can completely disable SCE: * - *
- *   angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
- *     // Completely disable SCE.  For demonstration purposes only!
- *     // Do not use in new projects.
- *     $sceProvider.enabled(false);
- *   });
- * 
+ * ``` + * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) { + * // Completely disable SCE. For demonstration purposes only! + * // Do not use in new projects. + * $sceProvider.enabled(false); + * }); + * ``` * */ /* jshint maxlen: 100 */ @@ -13488,7 +13779,7 @@ function $SceProvider() { /** * @ngdoc method * @name $sceProvider#enabled - * @function + * @kind function * * @param {boolean=} value If provided, then enables/disables SCE. * @return {boolean} true if SCE is enabled, false otherwise. @@ -13561,12 +13852,12 @@ function $SceProvider() { 'document. See http://docs.angularjs.org/api/ng.$sce for more information.'); } - var sce = copy(SCE_CONTEXTS); + var sce = shallowCopy(SCE_CONTEXTS); /** * @ngdoc method * @name $sce#isEnabled - * @function + * @kind function * * @return {Boolean} true if SCE is enabled, false otherwise. If you want to set the value, you * have to do it at module config time on {@link ng.$sceProvider $sceProvider}. @@ -13588,7 +13879,7 @@ function $SceProvider() { /** * @ngdoc method - * @name $sce#parse + * @name $sce#parseAs * * @description * Converts Angular {@link guide/expression expression} into a function. This is like {@link @@ -14101,7 +14392,7 @@ var originUrl = urlResolve(window.location.href, true); * https://github.com/angular/angular.js/pull/2902 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ * - * @function + * @kind function * @param {string} url The URL to be parsed. * @description Normalizes and parses a URL. * @returns {object} Returns the normalized URL as a dictionary. @@ -14174,17 +14465,18 @@ function urlIsSameOrigin(requestUrl) { * expression. * * @example - + -
+
@@ -14202,6 +14494,17 @@ function $WindowProvider(){ this.$get = valueFn(window); } +/* global currencyFilter: true, + dateFilter: true, + filterFilter: true, + jsonFilter: true, + limitToFilter: true, + lowercaseFilter: true, + numberFilter: true, + orderByFilter: true, + uppercaseFilter: true, + */ + /** * @ngdoc provider * @name $filterProvider @@ -14251,21 +14554,11 @@ function $WindowProvider(){ * For more information about how angular filters work, and how to create your own filters, see * {@link guide/filter Filters} in the Angular Developer Guide. */ -/** - * @ngdoc method - * @name $filterProvider#register - * @description - * Register filter factory function. - * - * @param {String} name Name of the filter. - * @param {Function} fn The filter factory function which is injectable. - */ - /** * @ngdoc service * @name $filter - * @function + * @kind function * @description * Filters are used for formatting data displayed to the user. * @@ -14275,14 +14568,31 @@ function $WindowProvider(){ * * @param {String} name Name of the filter function to retrieve * @return {Function} the filter function - */ + * @example + + +
+

{{ originalText }}

+

{{ filteredText }}

+
+
+ + + angular.module('filterExample', []) + .controller('MainCtrl', function($scope, $filter) { + $scope.originalText = 'hello'; + $scope.filteredText = $filter('uppercase')($scope.originalText); + }); + +
+ */ $FilterProvider.$inject = ['$provide']; function $FilterProvider($provide) { var suffix = 'Filter'; /** * @ngdoc method - * @name $controllerProvider#register + * @name $filterProvider#register * @param {string|Object} name Name of the filter function, or an object map of filters where * the keys are the filter names and the values are the filter factories. * @returns {Object} Registered filter instance, or if a map of filters was provided then a map @@ -14335,7 +14645,7 @@ function $FilterProvider($provide) { /** * @ngdoc filter * @name filter - * @function + * @kind function * * @description * Selects a subset of items from `array` and returns it as a new array. @@ -14355,7 +14665,9 @@ function $FilterProvider($provide) { * which have property `name` containing "M" and property `phone` containing "1". A special * property name `$` can be used (as in `{$:"text"}`) to accept a match against any * property of the object. That's equivalent to the simple substring match with a `string` - * as described above. + * as described above. The predicate can be negated by prefixing the string with `!`. + * For Example `{name: "!M"}` predicate will return an array of items which have property `name` + * not containing "M". * * - `function(value)`: A predicate function can be used to write arbitrary filters. The function is * called for each element of `array`. The final result is an array of those elements that @@ -14367,15 +14679,15 @@ function $FilterProvider($provide) { * * Can be one of: * - * - `function(actual, expected)`: - * The function will be given the object value and the predicate value to compare and - * should return true if the item should be included in filtered result. + * - `function(actual, expected)`: + * The function will be given the object value and the predicate value to compare and + * should return true if the item should be included in filtered result. * - * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`. - * this is essentially strict comparison of expected and actual. + * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`. + * this is essentially strict comparison of expected and actual. * - * - `false|undefined`: A short hand for a function which will look for a substring match in case - * insensitive way. + * - `false|undefined`: A short hand for a function which will look for a substring match in case + * insensitive way. * * @example @@ -14527,7 +14839,7 @@ function filterFilter() { // jshint +W086 for (var key in expression) { (function(path) { - if (typeof expression[path] == 'undefined') return; + if (typeof expression[path] === 'undefined') return; predicates.push(function(value) { return search(path == '$' ? value : (value && value[path]), expression[path]); }); @@ -14554,7 +14866,7 @@ function filterFilter() { /** * @ngdoc filter * @name currency - * @function + * @kind function * * @description * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default @@ -14566,14 +14878,15 @@ function filterFilter() { * * * @example - + -
+

default currency symbol ($): {{amount | currency}}
custom currency identifier (USD$): {{amount | currency:"USD$"}} @@ -14611,7 +14924,7 @@ function currencyFilter($locale) { /** * @ngdoc filter * @name number - * @function + * @kind function * * @description * Formats a number as text. @@ -14625,14 +14938,15 @@ function currencyFilter($locale) { * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. * * @example - + -
+
Enter number:
Default formatting: {{val | number}}
No fractions: {{val | number:0}}
@@ -14682,6 +14996,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { var match = numStr.match(/([\d\.]+)e(-?)(\d+)/); if (match && match[2] == '-' && match[3] > fractionSize + 1) { numStr = '0'; + number = 0; } else { formatedText = numStr; hasExponent = true; @@ -14696,8 +15011,15 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); } - var pow = Math.pow(10, fractionSize); - number = Math.round(number * pow) / pow; + // safely round numbers in JS without hitting imprecisions of floating-point arithmetics + // inspired by: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round + number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize); + + if (number === 0) { + isNegative = false; + } + var fraction = ('' + number).split(DECIMAL_SEP); var whole = fraction[0]; fraction = fraction[1] || ''; @@ -14823,7 +15145,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ /** * @ngdoc filter * @name date - * @function + * @kind function * * @description * Formats `date` to a string based on the requested `format`. @@ -14867,12 +15189,12 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm) * * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 pm) * - * `format` string can contain literal values. These need to be quoted with single quotes (e.g. - * `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence + * `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g. + * `"h 'in the morning'"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence * (e.g. `"h 'o''clock'"`). * * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or - * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its + * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is * specified in the string input, the time is considered to be in the local timezone. * @param {string=} format Formatting rules (see Description). If not specified, @@ -14888,6 +15210,8 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}: {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
+ {{1288323623006 | date:"MM/dd/yyyy 'at' h:mma"}}: + {{'1288323623006' | date:"MM/dd/yyyy 'at' h:mma"}}
it('should format date', function() { @@ -14897,6 +15221,8 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/); expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()). toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); + expect(element(by.binding("'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"")).getText()). + toMatch(/10\/2\d\/2010 at \d{1,2}:\d{2}(AM|PM)/); }); @@ -14940,11 +15266,7 @@ function dateFilter($locale) { format = format || 'mediumDate'; format = $locale.DATETIME_FORMATS[format] || format; if (isString(date)) { - if (NUMBER_STRING.test(date)) { - date = int(date); - } else { - date = jsonStringToDate(date); - } + date = NUMBER_STRING.test(date) ? int(date) : jsonStringToDate(date); } if (isNumber(date)) { @@ -14980,7 +15302,7 @@ function dateFilter($locale) { /** * @ngdoc filter * @name json - * @function + * @kind function * * @description * Allows you to convert a JavaScript object into JSON string. @@ -15015,7 +15337,7 @@ function jsonFilter() { /** * @ngdoc filter * @name lowercase - * @function + * @kind function * @description * Converts string to lowercase. * @see angular.lowercase @@ -15026,7 +15348,7 @@ var lowercaseFilter = valueFn(lowercase); /** * @ngdoc filter * @name uppercase - * @function + * @kind function * @description * Converts string to uppercase. * @see angular.uppercase @@ -15036,7 +15358,7 @@ var uppercaseFilter = valueFn(uppercase); /** * @ngdoc filter * @name limitTo - * @function + * @kind function * * @description * Creates a new array or string containing only a specified number of elements. The elements @@ -15052,20 +15374,21 @@ var uppercaseFilter = valueFn(uppercase); * had less than `limit` elements. * * @example - + -
- Limit {{numbers}} to: +
+ Limit {{numbers}} to:

Output numbers: {{ numbers | limitTo:numLimit }}

- Limit {{letters}} to: + Limit {{letters}} to:

Output letters: {{ letters | limitTo:letterLimit }}

@@ -15082,14 +15405,15 @@ var uppercaseFilter = valueFn(uppercase); expect(limitedLetters.getText()).toEqual('Output letters: abc'); }); - it('should update the output when -3 is entered', function() { - numLimitInput.clear(); - numLimitInput.sendKeys('-3'); - letterLimitInput.clear(); - letterLimitInput.sendKeys('-3'); - expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]'); - expect(limitedLetters.getText()).toEqual('Output letters: ghi'); - }); + // There is a bug in safari and protractor that doesn't like the minus key + // it('should update the output when -3 is entered', function() { + // numLimitInput.clear(); + // numLimitInput.sendKeys('-3'); + // letterLimitInput.clear(); + // letterLimitInput.sendKeys('-3'); + // expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]'); + // expect(limitedLetters.getText()).toEqual('Output letters: ghi'); + // }); it('should not exceed the maximum size of input array', function() { numLimitInput.clear(); @@ -15106,7 +15430,11 @@ function limitToFilter(){ return function(input, limit) { if (!isArray(input) && !isString(input)) return input; - limit = int(limit); + if (Math.abs(Number(limit)) === Infinity) { + limit = Number(limit); + } else { + limit = int(limit); + } if (isString(input)) { //NaN check on limit @@ -15145,10 +15473,12 @@ function limitToFilter(){ /** * @ngdoc filter * @name orderBy - * @function + * @kind function * * @description - * Orders a specified `array` by the `expression` predicate. + * Orders a specified `array` by the `expression` predicate. It is ordered alphabetically + * for strings and numerically for numbers. Note: if you notice numbers are not being sorted + * correctly, make sure they are actually being saved as numbers and not strings. * * @param {Array} array The array to sort. * @param {function(*)|string|Array.<(function(*)|string)>} expression A predicate to be @@ -15158,9 +15488,13 @@ function limitToFilter(){ * * - `function`: Getter function. The result of this function will be sorted using the * `<`, `=`, `>` operator. - * - `string`: An Angular expression which evaluates to an object to order by, such as 'name' - * to sort by a property called 'name'. Optionally prefixed with `+` or `-` to control - * ascending or descending sort order (for example, +name or -name). + * - `string`: An Angular expression. The result of this expression is used to compare elements + * (for example `name` to sort by a property called `name` or `name.substr(0, 3)` to sort by + * 3 first characters of a property called `name`). The result of a constant expression + * is interpreted as a property name to be used in comparisons (for example `"special name"` + * to sort object by the value of their `special name` property). An expression can be + * optionally prefixed with `+` or `-` to control ascending or descending sort order + * (for example, `+name` or `-name`). * - `Array`: An array of function or string predicates. The first predicate in the array * is used for sorting, but when two items are equivalent, the next predicate is used. * @@ -15168,20 +15502,21 @@ function limitToFilter(){ * @returns {Array} Sorted copy of the source array. * * @example - + -
+ + * + * It's also possible to call the orderBy filter manually, by injecting `$filter`, retrieving the + * filter routine with `$filter('orderBy')`, and calling the returned filter routine with the + * desired parameters. + * + * Example: + * + * @example + + +
+ + + + + + + + + + + +
Name + (^)Phone NumberAge
{{friend.name}}{{friend.phone}}{{friend.age}}
+
+
+ + + angular.module('orderByExample', []) + .controller('ExampleController', ['$scope', '$filter', function($scope, $filter) { + var orderBy = $filter('orderBy'); + $scope.friends = [ + { name: 'John', phone: '555-1212', age: 10 }, + { name: 'Mary', phone: '555-9876', age: 19 }, + { name: 'Mike', phone: '555-4321', age: 21 }, + { name: 'Adam', phone: '555-5678', age: 35 }, + { name: 'Julie', phone: '555-8765', age: 29 } + ]; + $scope.order = function(predicate, reverse) { + $scope.friends = orderBy($scope.friends, predicate, reverse); + }; + $scope.order('-age',false); + }]); + +
*/ orderByFilter.$inject = ['$parse']; function orderByFilter($parse){ return function(array, sortPredicate, reverseOrder) { - if (!isArray(array)) return array; + if (!(isArrayLike(array))) return array; if (!sortPredicate) return array; sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate]; sortPredicate = map(sortPredicate, function(predicate){ @@ -15247,6 +15627,10 @@ function orderByFilter($parse){ var t1 = typeof v1; var t2 = typeof v2; if (t1 == t2) { + if (isDate(v1) && isDate(v2)) { + v1 = v1.valueOf(); + v2 = v2.valueOf(); + } if (t1 == "string") { v1 = v1.toLowerCase(); v2 = v2.toLowerCase(); @@ -15384,7 +15768,7 @@ var htmlAnchorDirective = valueFn({ return browser.driver.getCurrentUrl().then(function(url) { return url.match(/\/123$/); }); - }, 1000, 'page should navigate to /123'); + }, 5000, 'page should navigate to /123'); }); xit('should execute ng-click but not reload when href empty string and name specified', function() { @@ -15412,7 +15796,7 @@ var htmlAnchorDirective = valueFn({ return browser.driver.getCurrentUrl().then(function(url) { return url.match(/\/6$/); }); - }, 1000, 'page should navigate to /6'); + }, 5000, 'page should navigate to /6'); }); @@ -15478,7 +15862,7 @@ var htmlAnchorDirective = valueFn({ * * @description * - * The following markup will make the button enabled on Chrome/Firefox but not on IE8 and older IEs: + * We shouldn't do this, because it will make the button enabled on Chrome/Firefox but not on IE8 and older IEs: * ```html *
* @@ -15698,8 +16082,12 @@ forEach(['src', 'srcset', 'href'], function(attrName) { } attr.$observe(normalized, function(value) { - if (!value) - return; + if (!value) { + if (attrName === 'href') { + attr.$set(name, null); + } + return; + } attr.$set(name, value); @@ -15752,7 +16140,7 @@ var nullFormCtrl = { * - `url` * * @description - * `FormController` keeps track of all its controls and nested forms as well as state of them, + * `FormController` keeps track of all its controls and nested forms as well as the state of them, * such as being valid/invalid or dirty/pristine. * * Each {@link ng.directive:form form} directive creates an instance @@ -15784,8 +16172,9 @@ function FormController(element, attrs, $scope, $animate) { // convenience method for easy toggling of classes function toggleValidCss(isValid, validationErrorKey) { validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; - $animate.removeClass(element, (isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey); - $animate.addClass(element, (isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey); + $animate.setClass(element, + (isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey, + (isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey); } /** @@ -16000,8 +16389,6 @@ function FormController(element, attrs, $scope, $animate) { * hitting enter in any of the input fields will trigger the click handler on the *first* button or * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`) * - * @param {string=} name Name of the form. If specified, the form controller will be published into - * related scope, under this name. * * ## Animation Hooks * @@ -16028,12 +16415,13 @@ function FormController(element, attrs, $scope, $animate) { * * * @example - + - + userType: Required!
userType = {{userType}}
@@ -16078,6 +16466,8 @@ function FormController(element, attrs, $scope, $animate) {
* + * @param {string=} name Name of the form. If specified, the form controller will be published into + * related scope, under this name. */ var formDirectiveFactory = function(isNgForm) { return ['$timeout', function($timeout) { @@ -16139,16 +16529,14 @@ var formDirectiveFactory = function(isNgForm) { var formDirective = formDirectiveFactory(); var ngFormDirective = formDirectiveFactory(true); -/* global - - -VALID_CLASS, - -INVALID_CLASS, - -PRISTINE_CLASS, - -DIRTY_CLASS +/* global VALID_CLASS: true, + INVALID_CLASS: true, + PRISTINE_CLASS: true, + DIRTY_CLASS: true */ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; -var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i; +var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; var inputType = { @@ -16158,7 +16546,9 @@ var inputType = { * @name input[text] * * @description - * Standard HTML text input with angular data binding. + * Standard HTML text input with angular data binding, inherited by most of the `input` elements. + * + * *NOTE* Not every feature offered is available for all input types. * * @param {string} ngModel Assignable angular expression to data-bind to. * @param {string=} name Property name of the form under which the control is published. @@ -16176,17 +16566,20 @@ var inputType = { * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * This parameter is ignored for input[type=password] controls, which will never trim the + * input. * * @example - + - + Single word: @@ -16258,14 +16651,15 @@ var inputType = { * interaction with the input element. * * @example - + - + Number: @@ -16333,14 +16727,15 @@ var inputType = { * interaction with the input element. * * @example - + - + URL: Required! @@ -16409,14 +16804,15 @@ var inputType = { * interaction with the input element. * * @example - + - + Email: Required! @@ -16475,18 +16871,19 @@ var inputType = { * be set when selected. * * @example - + - + Red
Green
Blue
@@ -16525,15 +16922,16 @@ var inputType = { * interaction with the input element. * * @example - + - + Value1:
Value2:
@@ -16574,15 +16972,29 @@ function validate(ctrl, validatorName, validity, value){ return validity ? value : undefined; } +function testFlags(validity, flags) { + var i, flag; + if (flags) { + for (i=0; i - if (toBoolean(attr.ngTrim || 'T')) { + // If input type is 'password', the value is never trimmed + if (type !== 'password' && (toBoolean(attr.ngTrim || 'T'))) { value = trim(value); } - if (ctrl.$viewValue !== value || - // If the value is still empty/falsy, and there is no `required` error, run validators - // again. This enables HTML5 constraint validation errors to affect Angular validation - // even when the first character entered causes an error. - (validity && value === '' && !validity.valueMissing)) { - if (scope.$$phase) { + // If a control is suffering from bad input, browsers discard its value, so it may be + // necessary to revalidate even if the control's value is the same empty value twice in + // a row. + var revalidate = validity && ctrl.$$hasNativeValidators; + if (ctrl.$viewValue !== value || (value === '' && revalidate)) { + if (scope.$root.$$phase) { ctrl.$setViewValue(value); } else { scope.$apply(function() { @@ -16731,6 +17156,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { } } +var numberBadFlags = ['badInput']; + function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { textInputType(scope, element, attr, ctrl, $sniffer, $browser); @@ -16745,7 +17172,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { } }); - addNativeHtml5Validators(ctrl, 'number', element); + addNativeHtml5Validators(ctrl, 'number', numberBadFlags, null, ctrl.$$validityState); ctrl.$formatters.push(function(value) { return ctrl.$isEmpty(value) ? '' : '' + value; @@ -16877,6 +17304,7 @@ function checkboxInputType(scope, element, attr, ctrl) { * patterns defined as scope expressions. * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. */ @@ -16889,6 +17317,8 @@ function checkboxInputType(scope, element, attr, ctrl) { * HTML input element control with angular data-binding. Input control follows HTML5 input types * and polyfills the HTML5 validation behavior for older browsers. * + * *NOTE* Not every feature offered is available for all input types. + * * @param {string} ngModel Assignable angular expression to data-bind to. * @param {string=} name Property name of the form under which the control is published. * @param {string=} required Sets `required` validation error key if the value is not entered. @@ -16902,16 +17332,20 @@ function checkboxInputType(scope, element, attr, ctrl) { * patterns defined as scope expressions. * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * This parameter is ignored for input[type=password] controls, which will never trim the + * input. * * @example - + -
+
User name: @@ -17026,14 +17460,14 @@ var VALID_CLASS = 'ng-valid', * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever the model value changes. Each function is called, in turn, passing the value through to the next. Used to format / convert values for display in the control and validation. - * ```js - * function formatter(value) { - * if (value) { - * return value.toUpperCase(); - * } - * } - * ngModel.$formatters.push(formatter); - * ``` + * ```js + * function formatter(value) { + * if (value) { + * return value.toUpperCase(); + * } + * } + * ngModel.$formatters.push(formatter); + * ``` * * @property {Array.} $viewChangeListeners Array of functions to execute whenever the * view value has changed. It is called with no arguments, and its return value is ignored. @@ -17062,7 +17496,12 @@ var VALID_CLASS = 'ng-valid', * Note that `contenteditable` is an HTML5 attribute, which tells the browser to let the element * contents be edited in place by the user. This will not work on older browsers. * - * + * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize} + * module to automatically remove "bad" content like inline event listener (e.g. ``). + * However, as we are using `$sce` the model can still decide to to provide unsafe content if it marks + * that content using the `$sce` service. + * + * [contenteditable] { border: 1px solid black; @@ -17076,8 +17515,8 @@ var VALID_CLASS = 'ng-valid', - angular.module('customControl', []). - directive('contenteditable', function() { + angular.module('customControl', ['ngSanitize']). + directive('contenteditable', ['$sce', function($sce) { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController @@ -17086,7 +17525,7 @@ var VALID_CLASS = 'ng-valid', // Specify how UI should be updated ngModel.$render = function() { - element.html(ngModel.$viewValue || ''); + element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); }; // Listen for change events to enable binding @@ -17107,7 +17546,7 @@ var VALID_CLASS = 'ng-valid', } } }; - }); + }]); @@ -17221,7 +17660,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * This method should be called by validators - i.e. the parser or formatter functions. * * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign - * to `$error[validationErrorKey]=isValid` so that it is available for data-binding. + * to `$error[validationErrorKey]=!isValid` so that it is available for data-binding. * The `validationErrorKey` should be in camelCase and will get converted into dash-case * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error` * class and can be bound to as `{{someForm.someControl.$error.myError}}` . @@ -17424,12 +17863,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$ * * * @example - * + * Update input to see transitions when valid/invalid. Integer is a valid value. - + @@ -17488,17 +17928,18 @@ var ngModelDirective = function() { * in input value. * * @example - * + * * * - *
+ *
* * *
@@ -17579,14 +18020,15 @@ var requiredDirective = function() { * specified in form `/something/` then the value will be converted into a regular expression. * * @example - + -
+ List: Required! @@ -17678,15 +18120,16 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; * of the `input` element * * @example - + - +

Which is your favorite?

+
Enter name:
Hello !
@@ -17781,14 +18225,19 @@ var ngValueDirective = function() { */ -var ngBindDirective = ngDirective(function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBind); - scope.$watch(attr.ngBind, function ngBindWatchAction(value) { - // We are purposefully using == here rather than === because we want to - // catch when value is "null or undefined" - // jshint -W041 - element.text(value == undefined ? '' : value); - }); +var ngBindDirective = ngDirective({ + compile: function(templateElement) { + templateElement.addClass('ng-binding'); + return function (scope, element, attr) { + element.data('$binding', attr.ngBind); + scope.$watch(attr.ngBind, function ngBindWatchAction(value) { + // We are purposefully using == here rather than === because we want to + // catch when value is "null or undefined" + // jshint -W041 + element.text(value == undefined ? '' : value); + }); + }; + } }); @@ -17810,15 +18259,16 @@ var ngBindDirective = ngDirective(function(scope, element, attr) { * * @example * Try it here: enter text in text box and watch the greeting change. - + -
+
Salutation:
Name:

@@ -17874,22 +18324,21 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
  * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
  *
  * @example
-   Try it here: enter text in text box and watch the greeting change.
 
-   
+   
      
-       
+

- angular.module('ngBindHtmlExample', ['ngSanitize']) - - .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) { - $scope.myHTML = - 'I am an HTMLstring with links! and other stuff'; - }]); + angular.module('bindHtmlExample', ['ngSanitize']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.myHTML = + 'I am an HTMLstring with ' + + '
links! and other stuff'; + }]); @@ -17901,15 +18350,24 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) { */ var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) { - return function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBindHtml); + return { + compile: function (tElement) { + tElement.addClass('ng-binding'); + + return function (scope, element, attr) { + element.data('$binding', attr.ngBindHtml); - var parsed = $parse(attr.ngBindHtml); - function getStringValue() { return (parsed(scope) || '').toString(); } + var parsed = $parse(attr.ngBindHtml); - scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { - element.html($sce.getTrustedHtml(parsed(scope)) || ''); - }); + function getStringValue() { + return (parsed(scope) || '').toString(); + } + + scope.$watch(getStringValue, function ngBindHtmlWatchAction(value) { + element.html($sce.getTrustedHtml(parsed(scope)) || ''); + }); + }; + } }; }]; @@ -17932,7 +18390,7 @@ function classDirective(name, selector) { scope.$watch('$index', function($index, old$index) { // jshint bitwise: false var mod = $index & 1; - if (mod !== old$index & 1) { + if (mod !== (old$index & 1)) { var classes = arrayClasses(scope.$eval(attr[name])); mod === selector ? addClasses(classes) : @@ -17991,7 +18449,7 @@ function classDirective(name, selector) { updateClasses(oldClasses, newClasses); } } - oldVal = copy(newVal); + oldVal = shallowCopy(newVal); } } }; @@ -18019,7 +18477,7 @@ function classDirective(name, selector) { var classes = [], i = 0; forEach(classVal, function(v, k) { if (v) { - classes.push(k); + classes = classes.concat(k.split(' ')); } }); return classes; @@ -18344,7 +18802,7 @@ var ngCloakDirective = ngDirective({ * * MVC components in angular: * - * * Model — The Model is scope properties; scopes are attached to the DOM where scope properties + * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties * are accessed through bindings. * * View — The template (HTML with data bindings) that is rendered into the View. * * Controller — The `ngController` directive specifies a Controller class; the class contains business @@ -18357,6 +18815,7 @@ var ngCloakDirective = ngDirective({ * * @element ANY * @scope + * @priority 500 * @param {expression} ngController Name of a globally accessible constructor function or an * {@link guide/expression expression} that on the current scope evaluates to a * constructor function. The controller instance can be published into a scope property @@ -18365,165 +18824,192 @@ var ngCloakDirective = ngDirective({ * @example * Here is a simple form for editing user contact information. Adding, removing, clearing, and * greeting are methods declared on the controller (see source tab). These methods can - * easily be called from the angular markup. Notice that the scope becomes the `this` for the - * controller's instance. This allows for easy access to the view data from the controller. Also - * notice that any changes to the data are automatically reflected in the View without the need - * for a manual update. The example is shown in two different declaration styles you may use - * according to preference. - - - -
- Name: - [ greet ]
- Contact: -
    -
  • - - - [ clear - | X ] -
  • -
  • [ add ]
  • -
-
-
- - it('should check controller as', function() { - var container = element(by.id('ctrl-as-exmpl')); - - expect(container.findElement(by.model('settings.name')) - .getAttribute('value')).toBe('John Smith'); - - var firstRepeat = - container.findElement(by.repeater('contact in settings.contacts').row(0)); - var secondRepeat = - container.findElement(by.repeater('contact in settings.contacts').row(1)); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('408 555 1212'); - expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('john.smith@example.org'); - - firstRepeat.findElement(by.linkText('clear')).click(); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe(''); - - container.findElement(by.linkText('add')).click(); - - expect(container.findElement(by.repeater('contact in settings.contacts').row(2)) - .findElement(by.model('contact.value')) - .getAttribute('value')) - .toBe('yourname@example.org'); - }); - -
- - - -
- Name: - [ greet ]
- Contact: -
    -
  • - - - [ clear - | X ] -
  • -
  • [ add ]
  • -
-
-
- - it('should check controller', function() { - var container = element(by.id('ctrl-exmpl')); - - expect(container.findElement(by.model('name')) - .getAttribute('value')).toBe('John Smith'); - - var firstRepeat = - container.findElement(by.repeater('contact in contacts').row(0)); - var secondRepeat = - container.findElement(by.repeater('contact in contacts').row(1)); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('408 555 1212'); - expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe('john.smith@example.org'); - - firstRepeat.findElement(by.linkText('clear')).click(); - - expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) - .toBe(''); - - container.findElement(by.linkText('add')).click(); - - expect(container.findElement(by.repeater('contact in contacts').row(2)) - .findElement(by.model('contact.value')) - .getAttribute('value')) - .toBe('yourname@example.org'); - }); - -
+ * easily be called from the angular markup. Any changes to the data are automatically reflected + * in the View without the need for a manual update. + * + * Two different declaration styles are included below: + * + * * one binds methods and properties directly onto the controller using `this`: + * `ng-controller="SettingsController1 as settings"` + * * one injects `$scope` into the controller: + * `ng-controller="SettingsController2"` + * + * The second option is more common in the Angular community, and is generally used in boilerplates + * and in this guide. However, there are advantages to binding properties directly to the controller + * and avoiding scope. + * + * * Using `controller as` makes it obvious which controller you are accessing in the template when + * multiple controllers apply to an element. + * * If you are writing your controllers as classes you have easier access to the properties and + * methods, which will appear on the scope, from inside the controller code. + * * Since there is always a `.` in the bindings, you don't have to worry about prototypal + * inheritance masking primitives. + * + * This example demonstrates the `controller as` syntax. + * + * + * + *
+ * Name: + * [ greet ]
+ * Contact: + *
    + *
  • + * + * + * [ clear + * | X ] + *
  • + *
  • [ add ]
  • + *
+ *
+ *
+ * + * angular.module('controllerAsExample', []) + * .controller('SettingsController1', SettingsController1); + * + * function SettingsController1() { + * this.name = "John Smith"; + * this.contacts = [ + * {type: 'phone', value: '408 555 1212'}, + * {type: 'email', value: 'john.smith@example.org'} ]; + * } + * + * SettingsController1.prototype.greet = function() { + * alert(this.name); + * }; + * + * SettingsController1.prototype.addContact = function() { + * this.contacts.push({type: 'email', value: 'yourname@example.org'}); + * }; + * + * SettingsController1.prototype.removeContact = function(contactToRemove) { + * var index = this.contacts.indexOf(contactToRemove); + * this.contacts.splice(index, 1); + * }; + * + * SettingsController1.prototype.clearContact = function(contact) { + * contact.type = 'phone'; + * contact.value = ''; + * }; + * + * + * it('should check controller as', function() { + * var container = element(by.id('ctrl-as-exmpl')); + * expect(container.element(by.model('settings.name')) + * .getAttribute('value')).toBe('John Smith'); + * + * var firstRepeat = + * container.element(by.repeater('contact in settings.contacts').row(0)); + * var secondRepeat = + * container.element(by.repeater('contact in settings.contacts').row(1)); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe('408 555 1212'); + * + * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe('john.smith@example.org'); + * + * firstRepeat.element(by.linkText('clear')).click(); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe(''); + * + * container.element(by.linkText('add')).click(); + * + * expect(container.element(by.repeater('contact in settings.contacts').row(2)) + * .element(by.model('contact.value')) + * .getAttribute('value')) + * .toBe('yourname@example.org'); + * }); + * + *
+ * + * This example demonstrates the "attach to `$scope`" style of controller. + * + * + * + *
+ * Name: + * [ greet ]
+ * Contact: + *
    + *
  • + * + * + * [ clear + * | X ] + *
  • + *
  • [ add ]
  • + *
+ *
+ *
+ * + * angular.module('controllerExample', []) + * .controller('SettingsController2', ['$scope', SettingsController2]); + * + * function SettingsController2($scope) { + * $scope.name = "John Smith"; + * $scope.contacts = [ + * {type:'phone', value:'408 555 1212'}, + * {type:'email', value:'john.smith@example.org'} ]; + * + * $scope.greet = function() { + * alert($scope.name); + * }; + * + * $scope.addContact = function() { + * $scope.contacts.push({type:'email', value:'yourname@example.org'}); + * }; + * + * $scope.removeContact = function(contactToRemove) { + * var index = $scope.contacts.indexOf(contactToRemove); + * $scope.contacts.splice(index, 1); + * }; + * + * $scope.clearContact = function(contact) { + * contact.type = 'phone'; + * contact.value = ''; + * }; + * } + * + * + * it('should check controller', function() { + * var container = element(by.id('ctrl-exmpl')); + * + * expect(container.element(by.model('name')) + * .getAttribute('value')).toBe('John Smith'); + * + * var firstRepeat = + * container.element(by.repeater('contact in contacts').row(0)); + * var secondRepeat = + * container.element(by.repeater('contact in contacts').row(1)); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe('408 555 1212'); + * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe('john.smith@example.org'); + * + * firstRepeat.element(by.linkText('clear')).click(); + * + * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value')) + * .toBe(''); + * + * container.element(by.linkText('add')).click(); + * + * expect(container.element(by.repeater('contact in contacts').row(2)) + * .element(by.model('contact.value')) + * .getAttribute('value')) + * .toBe('yourname@example.org'); + * }); + * + *
*/ var ngControllerDirective = [function() { @@ -18545,8 +19031,10 @@ var ngControllerDirective = [function() { * This is necessary when developing things like Google Chrome Extensions. * * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things). - * For us to be compatible, we just need to implement the "getterFn" in $parse without violating - * any of these restrictions. + * For Angular to be CSP compatible there are only two things that we need to do differently: + * + * - don't use `Function` constructor to generate optimized value getters + * - don't inject custom stylesheet into the document * * AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp` * directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will @@ -18557,7 +19045,18 @@ var ngControllerDirective = [function() { * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}). * To make those directives work in CSP mode, include the `angular-csp.css` manually. * - * In order to use this feature put the `ngCsp` directive on the root element of the application. + * Angular tries to autodetect if CSP is active and automatically turn on the CSP-safe mode. This + * autodetection however triggers a CSP error to be logged in the console: + * + * ``` + * Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of + * script in the following Content Security Policy directive: "default-src 'self'". Note that + * 'script-src' was not explicitly set, so 'default-src' is used as a fallback. + * ``` + * + * This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp` + * directive on the root element of the application or on the `angular.js` script tag, whichever + * appears first in the html document. * * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.* * @@ -18572,9 +19071,9 @@ var ngControllerDirective = [function() { ``` */ -// ngCsp is not implemented as a proper directive any more, because we need it be processed while we bootstrap -// the system (before $parse is instantiated), for this reason we just have a csp() fn that looks for ng-csp attribute -// anywhere in the current doc +// ngCsp is not implemented as a proper directive any more, because we need it be processed while we +// bootstrap the system (before $parse is instantiated), for this reason we just have +// the csp.isActive() fn that looks for ng-csp attribute anywhere in the current doc /** * @ngdoc directive @@ -18595,7 +19094,9 @@ var ngControllerDirective = [function() { - count: {{count}} + + count: {{count}} +
it('should check ng-click', function() { @@ -18613,19 +19114,32 @@ var ngControllerDirective = [function() { * Events that are handled via these handler are always configured not to propagate further. */ var ngEventDirectives = {}; + +// For events that might fire synchronously during DOM manipulation +// we need to execute their event handlers asynchronously using $evalAsync, +// so that they are not executed in an inconsistent state. +var forceAsyncEvents = { + 'blur': true, + 'focus': true +}; forEach( 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '), - function(name) { - var directiveName = directiveNormalize('ng-' + name); - ngEventDirectives[directiveName] = ['$parse', function($parse) { + function(eventName) { + var directiveName = directiveNormalize('ng-' + eventName); + ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) { return { compile: function($element, attr) { var fn = $parse(attr[directiveName]); - return function(scope, element, attr) { - element.on(lowercase(name), function(event) { - scope.$apply(function() { + return function ngEventHandler(scope, element) { + element.on(eventName, function(event) { + var callback = function() { fn(scope, {$event:event}); - }); + }; + if (forceAsyncEvents[eventName] && $rootScope.$$phase) { + scope.$evalAsync(callback); + } else { + scope.$apply(callback); + } }); }; } @@ -18838,8 +19352,13 @@ forEach( * @example - - key up count: {{count}} +

Typing in the input box below updates the key count

+ key up count: {{count}} + +

Typing in the input box below updates the keycode

+ +

event keyCode: {{ event.keyCode }}

+

event altKey: {{ event.altKey }}

*/ @@ -18878,27 +19397,35 @@ forEach( * server and reloading the current page), but only if the form does not contain `action`, * `data-action`, or `x-action` attributes. * + *
+ * **Warning:** Be careful not to cause "double-submission" by using both the `ngClick` and + * `ngSubmit` handlers together. See the + * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation} + * for a detailed discussion of when `ngSubmit` may be triggered. + *
+ * * @element form * @priority 0 * @param {expression} ngSubmit {@link guide/expression Expression} to eval. * ({@link guide/expression#-event- Event object is available as `$event`}) * * @example - + - + Enter text and hit enter: @@ -18910,7 +19437,7 @@ forEach( expect(element(by.binding('list')).getText()).toBe('list=[]'); element(by.css('#submit')).click(); expect(element(by.binding('list')).getText()).toContain('hello'); - expect(element(by.input('text')).getAttribute('value')).toBe(''); + expect(element(by.model('text')).getAttribute('value')).toBe(''); }); it('should ignore empty strings', function() { expect(element(by.binding('list')).getText()).toBe('list=[]'); @@ -18929,6 +19456,10 @@ forEach( * @description * Specify custom behavior on focus event. * + * Note: As the `focus` event is executed synchronously when calling `input.focus()` + * AngularJS executes the expression using `scope.$evalAsync` if the event is fired + * during an `$apply` to ensure a consistent state. + * * @element window, input, select, textarea, a * @priority 0 * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon @@ -18945,6 +19476,14 @@ forEach( * @description * Specify custom behavior on blur event. * + * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when + * an element has lost focus. + * + * Note: As the `blur` event is executed synchronously also during DOM manipulations + * (e.g. removing a focussed input), + * AngularJS executes the expression using `scope.$evalAsync` if the event is fired + * during an `$apply` to ensure a consistent state. + * * @element window, input, select, textarea, a * @priority 0 * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon @@ -19111,7 +19650,7 @@ var ngIfDirective = ['$animate', function($animate) { clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' '); // Note: We only need the first/last node of the cloned nodes. // However, we need to keep the reference to the jqlite wrapper as it might be changed later - // by a directive with templateUrl when it's template arrives. + // by a directive with templateUrl when its template arrives. block = { clone: clone }; @@ -19183,9 +19722,9 @@ var ngIfDirective = ['$animate', function($animate) { * - Otherwise enable scrolling only if the expression evaluates to truthy value. * * @example - + -
+
@@ -19197,12 +19736,13 @@ var ngIfDirective = ['$animate', function($animate) {
- function Ctrl($scope) { - $scope.templates = - [ { name: 'template1.html', url: 'template1.html'}, - { name: 'template2.html', url: 'template2.html'} ]; - $scope.template = $scope.templates[0]; - } + angular.module('includeExample', ['ngAnimate']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.templates = + [ { name: 'template1.html', url: 'template1.html'}, + { name: 'template2.html', url: 'template2.html'} ]; + $scope.template = $scope.templates[0]; + }]); Content of template1.html @@ -19265,7 +19805,7 @@ var ngIfDirective = ['$animate', function($animate) { return; } templateSelect.click(); - templateSelect.element.all(by.css('option')).get(2).click(); + templateSelect.all(by.css('option')).get(2).click(); expect(includeElem.getText()).toMatch(/Content of template2.html/); }); @@ -19275,7 +19815,7 @@ var ngIfDirective = ['$animate', function($animate) { return; } templateSelect.click(); - templateSelect.element.all(by.css('option')).get(0).click(); + templateSelect.all(by.css('option')).get(0).click(); expect(includeElem.isPresent()).toBe(false); }); @@ -19427,14 +19967,15 @@ var ngIncludeFillContentDirective = ['$compile', * @param {expression} ngInit {@link guide/expression Expression} to eval. * * @example - + -
+
list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}}; @@ -19574,7 +20115,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); * When one person, perhaps John, views the document, "John is viewing" will be shown. * When three people view the document, no explicit number rule is found, so * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category. - * In this case, plural category 'one' is matched and "John, Marry and one other person are viewing" + * In this case, plural category 'one' is matched and "John, Mary and one other person are viewing" * is shown. * * Note that when you specify offsets, you must provide explicit number rules for @@ -19587,16 +20128,17 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); * @param {number=} offset Offset to deduct from the total number. * * @example - + -
+
Person 1:
Person 2:
Number of People:
@@ -19810,7 +20352,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression, * before specifying a tracking expression. * - * For example: `item in items` is equivalent to `item in items track by $id(item)'. This implies that the DOM elements + * For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements * will be associated by item identity in the array. * * For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique @@ -20022,8 +20564,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { if (block && block.scope) lastBlockMap[block.id] = block; }); // This is a duplicate and we need to throw an error - throw ngRepeatMinErr('dupes', "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}", - expression, trackById); + throw ngRepeatMinErr('dupes', + "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}", + expression, trackById, toJson(value)); } else { // new never before seen block nextBlockOrder[index] = { id: trackById }; @@ -20088,7 +20631,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { block.scope = childScope; // Note: We only need the first/last node of the cloned nodes. // However, we need to keep the reference to the jqlite wrapper as it might be changed later - // by a directive with templateUrl when it's template arrives. + // by a directive with templateUrl when its template arrives. block.clone = clone; nextBlockMap[block.id] = block; }); @@ -20114,8 +20657,8 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * * @description * The `ngShow` directive shows or hides the given HTML element based on the expression - * provided to the ngShow attribute. The element is shown or hidden by removing or adding - * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined + * provided to the `ngShow` attribute. The element is shown or hidden by removing or adding + * the `.ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined * in AngularJS and sets the display style to none (using an !important flag). * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). * @@ -20127,13 +20670,18 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { *
* ``` * - * When the ngShow expression evaluates to false then the ng-hide CSS class is added to the class attribute - * on the element causing it to become hidden. When true, the ng-hide CSS class is removed + * When the `ngShow` expression evaluates to false then the `.ng-hide` CSS class is added to the class attribute + * on the element causing it to become hidden. When true, the `.ng-hide` CSS class is removed * from the element causing the element not to appear hidden. * + *
+ * **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):
+ * "f" / "0" / "false" / "no" / "n" / "[]" + *
+ * * ## Why is !important used? * - * You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector + * You may be wondering why !important is used for the `.ng-hide` CSS class. This is because the `.ng-hide` selector * can be easily overridden by heavier selectors. For example, something as simple * as changing the display style on a HTML list item would make hidden elements appear visible. * This also becomes a bigger issue when dealing with CSS frameworks. @@ -20142,30 +20690,25 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the * styling to change how to hide an element then it is just a matter of using !important in their own CSS code. * - * ### Overriding .ng-hide + * ### Overriding `.ng-hide` + * + * By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change + * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide` + * class in CSS: * - * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by - * restating the styles for the .ng-hide class in CSS: * ```css * .ng-hide { - * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default... - * display:block!important; - * * //this is just another form of hiding an element + * display:block!important; * position:absolute; * top:-9999px; * left:-9999px; * } * ``` * - * Just remember to include the important flag so the CSS override will function. - * - *
- * **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):
- * "f" / "0" / "false" / "no" / "n" / "[]" - *
+ * By default you don't need to override in CSS anything and the animations will work around the display style. * - * ## A note about animations with ngShow + * ## A note about animations with `ngShow` * * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression * is true and false. This system works like the animation system present with ngClass except that @@ -20178,7 +20721,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * // * .my-element.ng-hide-add, .my-element.ng-hide-remove { * transition:0.5s linear all; - * display:block!important; * } * * .my-element.ng-hide-add { ... } @@ -20187,9 +20729,12 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { * .my-element.ng-hide-remove.ng-hide-remove-active { ... } * ``` * + * Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display + * property to block during animation states--ngAnimate will handle the style toggling automatically for you. + * * @animations - * addClass: .ng-hide - happens after the ngShow expression evaluates to a truthy value and the just before contents are set to visible - * removeClass: .ng-hide - happens after the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden + * addClass: `.ng-hide` - happens after the `ngShow` expression evaluates to a truthy value and the just before contents are set to visible + * removeClass: `.ng-hide` - happens after the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden * * @element ANY * @param {expression} ngShow If the {@link guide/expression expression} is truthy @@ -20226,11 +20771,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { background:white; } - .animate-show.ng-hide-add, - .animate-show.ng-hide-remove { - display:block!important; - } - .animate-show.ng-hide { line-height:0; opacity:0; @@ -20274,26 +20814,31 @@ var ngShowDirective = ['$animate', function($animate) { * * @description * The `ngHide` directive shows or hides the given HTML element based on the expression - * provided to the ngHide attribute. The element is shown or hidden by removing or adding + * provided to the `ngHide` attribute. The element is shown or hidden by removing or adding * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined * in AngularJS and sets the display style to none (using an !important flag). * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). * * ```html * - *
+ *
* * - *
+ *
* ``` * - * When the ngHide expression evaluates to true then the .ng-hide CSS class is added to the class attribute - * on the element causing it to become hidden. When false, the ng-hide CSS class is removed + * When the `.ngHide` expression evaluates to true then the `.ng-hide` CSS class is added to the class attribute + * on the element causing it to become hidden. When false, the `.ng-hide` CSS class is removed * from the element causing the element not to appear hidden. * + *
+ * **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):
+ * "f" / "0" / "false" / "no" / "n" / "[]" + *
+ * * ## Why is !important used? * - * You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector + * You may be wondering why !important is used for the `.ng-hide` CSS class. This is because the `.ng-hide` selector * can be easily overridden by heavier selectors. For example, something as simple * as changing the display style on a HTML list item would make hidden elements appear visible. * This also becomes a bigger issue when dealing with CSS frameworks. @@ -20302,35 +20847,29 @@ var ngShowDirective = ['$animate', function($animate) { * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the * styling to change how to hide an element then it is just a matter of using !important in their own CSS code. * - * ### Overriding .ng-hide + * ### Overriding `.ng-hide` + * + * By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change + * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide` + * class in CSS: * - * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by - * restating the styles for the .ng-hide class in CSS: * ```css * .ng-hide { - * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default... - * display:block!important; - * * //this is just another form of hiding an element + * display:block!important; * position:absolute; * top:-9999px; * left:-9999px; * } * ``` * - * Just remember to include the important flag so the CSS override will function. - * - *
- * **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):
- * "f" / "0" / "false" / "no" / "n" / "[]" - *
+ * By default you don't need to override in CSS anything and the animations will work around the display style. * - * ## A note about animations with ngHide + * ## A note about animations with `ngHide` * * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression - * is true and false. This system works like the animation system present with ngClass, except that - * you must also include the !important flag to override the display property so - * that you can perform an animation when the element is hidden during the time of the animation. + * is true and false. This system works like the animation system present with ngClass, except that the `.ng-hide` + * CSS class is added and removed for you instead of your own CSS class. * * ```css * // @@ -20338,7 +20877,6 @@ var ngShowDirective = ['$animate', function($animate) { * // * .my-element.ng-hide-add, .my-element.ng-hide-remove { * transition:0.5s linear all; - * display:block!important; * } * * .my-element.ng-hide-add { ... } @@ -20347,9 +20885,12 @@ var ngShowDirective = ['$animate', function($animate) { * .my-element.ng-hide-remove.ng-hide-remove-active { ... } * ``` * + * Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display + * property to block during animation states--ngAnimate will handle the style toggling automatically for you. + * * @animations - * removeClass: .ng-hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden - * addClass: .ng-hide - happens after the ngHide expression evaluates to a non truthy value and just before the contents are set to visible + * removeClass: `.ng-hide` - happens after the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden + * addClass: `.ng-hide` - happens after the `ngHide` expression evaluates to a non truthy value and just before the contents are set to visible * * @element ANY * @param {expression} ngHide If the {@link guide/expression expression} is truthy then @@ -20386,11 +20927,6 @@ var ngShowDirective = ['$animate', function($animate) { background:white; } - .animate-hide.ng-hide-add, - .animate-hide.ng-hide-remove { - display:block!important; - } - .animate-hide.ng-hide { line-height:0; opacity:0; @@ -20436,14 +20972,20 @@ var ngHideDirective = ['$animate', function($animate) { * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally. * * @element ANY - * @param {expression} ngStyle {@link guide/expression Expression} which evals to an - * object whose keys are CSS style names and values are corresponding values for those CSS - * keys. + * @param {expression} ngStyle + * + * {@link guide/expression Expression} which evals to an + * object whose keys are CSS style names and values are corresponding values for those CSS + * keys. + * + * Since some CSS style names are not valid keys for an object, they must be quoted. + * See the 'background-color' style in the example below. * * @example - + +
Sample Text @@ -20459,7 +21001,7 @@ var ngHideDirective = ['$animate', function($animate) { it('should check ng-style', function() { expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)'); - element(by.css('input[value=set]')).click(); + element(by.css('input[value=\'set color\']')).click(); expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)'); element(by.css('input[value=clear]')).click(); expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)'); @@ -20507,11 +21049,14 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { * leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM * * @usage + * + * ``` * * ... * ... * ... * + * ``` * * * @scope @@ -20528,9 +21073,9 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { * * * @example - + -
+
selection={{selection}} @@ -20544,10 +21089,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
- function Ctrl($scope) { - $scope.items = ['settings', 'home', 'other']; - $scope.selection = $scope.items[0]; - } + angular.module('switchExample', ['ngAnimate']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.items = ['settings', 'home', 'other']; + $scope.selection = $scope.items[0]; + }]); .animate-switch-container { @@ -20590,11 +21136,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { expect(switchElem.getText()).toMatch(/Settings Div/); }); it('should change to home', function() { - select.element.all(by.css('option')).get(1).click(); + select.all(by.css('option')).get(1).click(); expect(switchElem.getText()).toMatch(/Home Span/); }); it('should select default', function() { - select.element.all(by.css('option')).get(2).click(); + select.all(by.css('option')).get(2).click(); expect(switchElem.getText()).toMatch(/default/); }); @@ -20611,37 +21157,29 @@ var ngSwitchDirective = ['$animate', function($animate) { }], link: function(scope, element, attr, ngSwitchController) { var watchExpr = attr.ngSwitch || attr.on, - selectedTranscludes, - selectedElements, - previousElements, + selectedTranscludes = [], + selectedElements = [], + previousElements = [], selectedScopes = []; scope.$watch(watchExpr, function ngSwitchWatchAction(value) { - var i, ii = selectedScopes.length; - if(ii > 0) { - if(previousElements) { - for (i = 0; i < ii; i++) { - previousElements[i].remove(); - } - previousElements = null; - } - - previousElements = []; - for (i= 0; i + -
+


{{text}} @@ -20874,21 +21411,22 @@ var ngOptionsMinErr = minErr('ngOptions'); * `value` variable (e.g. `value.propertyName`). * * @example - + -
+
  • Name: @@ -20900,37 +21438,37 @@ var ngOptionsMinErr = minErr('ngOptions');

Color (null not allowed): -
+
Color (null allowed): -
Color grouped by shade: -
- Select bogus.
+ Select bogus.

- Currently selected: {{ {selected_color:color} }} + Currently selected: {{ {selected_color:myColor} }}
+ ng-style="{'background-color':myColor.name}">
it('should check ng-options', function() { - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red'); - element.all(by.select('color')).first().click(); - element.all(by.css('select[ng-model="color"] option')).first().click(); - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black'); - element(by.css('.nullable select[ng-model="color"]')).click(); - element.all(by.css('.nullable select[ng-model="color"] option')).first().click(); - expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null'); + expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red'); + element.all(by.model('myColor')).first().click(); + element.all(by.css('select[ng-model="myColor"] option')).first().click(); + expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black'); + element(by.css('.nullable select[ng-model="myColor"]')).click(); + element.all(by.css('.nullable select[ng-model="myColor"] option')).first().click(); + expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null'); }); @@ -21085,7 +21623,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // we need to work of an array, so we need to see if anything was inserted/removed scope.$watch(function selectMultipleWatch() { if (!equals(lastView, ctrl.$viewValue)) { - lastView = copy(ctrl.$viewValue); + lastView = shallowCopy(ctrl.$viewValue); ctrl.$render(); } }); @@ -21196,21 +21734,50 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { value = valueFn(scope, locals); } } - // Update the null option's selected property here so $render cleans it up correctly - if (optionGroupsCache[0].length > 1) { - if (optionGroupsCache[0][1].id !== key) { - optionGroupsCache[0][1].selected = false; - } - } } ctrl.$setViewValue(value); + render(); }); }); ctrl.$render = render; - // TODO(vojta): can't we optimize this ? - scope.$watch(render); + scope.$watchCollection(valuesFn, render); + scope.$watchCollection(function () { + var locals = {}, + values = valuesFn(scope); + if (values) { + var toDisplay = new Array(values.length); + for (var i = 0, ii = values.length; i < ii; i++) { + locals[valueName] = values[i]; + toDisplay[i] = displayFn(scope, locals); + } + return toDisplay; + } + }, render); + + if ( multiple ) { + scope.$watchCollection(function() { return ctrl.$modelValue; }, render); + } + + function getSelectedSet() { + var selectedSet = false; + if (multiple) { + var modelValue = ctrl.$modelValue; + if (trackFn && isArray(modelValue)) { + selectedSet = new HashMap([]); + var locals = {}; + for (var trackIndex = 0; trackIndex < modelValue.length; trackIndex++) { + locals[valueName] = modelValue[trackIndex]; + selectedSet.put(trackFn(scope, locals), modelValue[trackIndex]); + } + } else { + selectedSet = new HashMap(modelValue); + } + } + return selectedSet; + } + function render() { // Temporary location for the option groups before we render them @@ -21228,22 +21795,11 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { groupIndex, index, locals = {}, selected, - selectedSet = false, // nothing is selected yet + selectedSet = getSelectedSet(), lastElement, element, label; - if (multiple) { - if (trackFn && isArray(modelValue)) { - selectedSet = new HashMap([]); - for (var trackIndex = 0; trackIndex < modelValue.length; trackIndex++) { - locals[valueName] = modelValue[trackIndex]; - selectedSet.put(trackFn(scope, locals), modelValue[trackIndex]); - } - } else { - selectedSet = new HashMap(modelValue); - } - } // We now build up the list of options we need (we merge later) for (index = 0; length = keys.length, index < length; index++) { @@ -21339,8 +21895,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { lastElement.val(existingOption.id = option.id); } // lastElement.prop('selected') provided by jQuery has side-effects - if (existingOption.selected !== option.selected) { + if (lastElement[0].selected !== option.selected) { lastElement.prop('selected', (existingOption.selected = option.selected)); + if (msie) { + // See #7692 + // The selected item wouldn't visually update on IE without this. + // Tested on Win7: IE9, IE10 and IE11. Future IEs should be tested as well + lastElement.prop('selected', existingOption.selected); + } } } else { // grow elements @@ -21355,6 +21917,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // rather then the element. (element = optionTemplate.clone()) .val(option.id) + .prop('selected', option.selected) .attr('selected', option.selected) .text(option.label); } @@ -21365,6 +21928,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { id: option.id, selected: option.selected }); + selectCtrl.addOption(option.label, element); if (lastElement) { lastElement.after(element); } else { @@ -21376,7 +21940,9 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { // remove any excessive OPTIONs in a group index++; // increment since the existingOptions[0] is parent element not OPTION while(existingOptions.length > index) { - existingOptions.pop().element.remove(); + option = existingOptions.pop(); + selectCtrl.removeOption(option.label); + option.element.remove(); } } // remove any excessive OPTGROUPs from select @@ -21461,4 +22027,4 @@ var styleDirective = valueFn({ })(window, document); -!angular.$$csp() && angular.element(document).find('head').prepend(''); \ No newline at end of file +!window.angular.$$csp() && window.angular.element(document).find('head').prepend(''); \ No newline at end of file diff --git a/bower_components/angular/angular.min.js b/bower_components/angular/angular.min.js old mode 100755 new mode 100644 index 43f31f6..b9f64f4 --- a/bower_components/angular/angular.min.js +++ b/bower_components/angular/angular.min.js @@ -1,210 +1,216 @@ /* - AngularJS v1.2.16 + AngularJS v1.2.26 (c) 2010-2014 Google, Inc. http://angularjs.org License: MIT */ -(function(O,U,s){'use strict';function t(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.16/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/, -function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function Xb(b){try{return decodeURIComponent(b)}catch(a){}}function Yb(b){var a={},c,d;q((b||"").split("&"),function(b){b&&(c=b.split("="),d=Xb(c[0]),B(d)&&(b=B(c[1])?Xb(c[1]):!0,a[d]?M(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Zb(b){var a=[];q(b,function(b,d){M(b)?q(b,function(b){a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))}):a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))});return a.length?a.join("&"):""}function wb(b){return za(b, -!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function za(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Wc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,f=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;q(f,function(a){f[a]=!0;c(U.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(q(b.querySelectorAll("."+a),c),q(b.querySelectorAll("."+ -a+"\\:"),c),q(b.querySelectorAll("["+a+"]"),c))});q(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):q(a.attributes,function(b){!e&&f[b.name]&&(e=a,g=b.value)})}});e&&a(e,g?[g]:[])}function $b(b,a){var c=function(){b=y(b);if(b.injector()){var c=b[0]===U?"document":ha(b);throw Pa("btstrpd",c);}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=ac(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate", -function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(O&&!d.test(O.name))return c();O.name=O.name.replace(d,"");Ea.resumeBootstrap=function(b){q(b,function(b){a.push(b)});c()}}function fb(b,a){a=a||"_";return b.replace(Xc,function(b,d){return(d?a:"")+b.toLowerCase()})}function xb(b,a,c){if(!b)throw Pa("areq",a||"?",c||"required");return b}function Ra(b,a,c){c&&M(b)&&(b=b[b.length-1]);xb(P(b),a,"not a function, got "+(b&&"object"==typeof b? -b.constructor.name||"Object":typeof b));return b}function Aa(b,a){if("hasOwnProperty"===b)throw Pa("badname",a);}function bc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,g=a.length,f=0;f 
"+e[1]+a.replace(le,"<$1>")+e[2]; -d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=S?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ia(b){var a=typeof b,c;"object"==a&&null!==b?"function"==typeof(c=b.$$hashKey)?c=b.$$hashKey():c===s&&(c=b.$$hashKey=bb()):c=b;return a+":"+c}function Va(b){q(b,this.put,this)}function oc(b){var a,c;"function"==typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(oe, -""),c=c.match(pe),q(c[1].split(qe),function(b){b.replace(re,function(b,c,d){a.push(d)})})),b.$inject=a):M(b)?(c=b.length-1,Ra(b[c],"fn"),a=b.slice(0,c)):Ra(b,"fn",!0);return a}function ac(b){function a(a){return function(b,c){if(X(b))q(b,Rb(a));else return a(b,c)}}function c(a,b){Aa(a,"service");if(P(b)||M(b))b=n.instantiate(b);if(!b.$get)throw Wa("pget",a);return m[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,g,h;q(a,function(a){if(!k.get(a)){k.put(a,!0);try{if(w(a))for(c= -Sa(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,g=0,h=d.length;g 4096 bytes)!"));else{if(l.cookie!==da)for(da=l.cookie,d=da.split("; "),Q={},g=0;gk&&this.remove(p.key),b},get:function(a){if(k").parent()[0])});var g=L(a,b,a,c,d,e);ma(a,"ng-scope");return function(b,c,d){xb(b,"scope");var e=c?Ja.clone.call(a):a;q(d,function(a,b){e.data("$"+b+"Controller",a)});d=0;for(var f=e.length;darguments.length&& -(b=a,a=s);D&&(c=lb);return p(a,b,c)}var I,x,v,A,R,H,lb={},da;I=c===g?d:Ub(d,new Hb(y(g),d.$attr));x=I.$$element;if(Q){var T=/^\s*([@=&])(\??)\s*(\w*)\s*$/;f=y(g);H=e.$new(!0);ia&&ia===Q.$$originalDirective?f.data("$isolateScope",H):f.data("$isolateScopeNoTemplate",H);ma(f,"ng-isolate-scope");q(Q.scope,function(a,c){var d=a.match(T)||[],g=d[3]||c,f="?"==d[2],d=d[1],l,m,n,p;H.$$isolateBindings[c]=d+g;switch(d){case "@":I.$observe(g,function(a){H[c]=a});I.$$observers[g].$$scope=e;I[g]&&(H[c]=b(I[g])(e)); -break;case "=":if(f&&!I[g])break;m=r(I[g]);p=m.literal?xa:function(a,b){return a===b};n=m.assign||function(){l=H[c]=m(e);throw ja("nonassign",I[g],Q.name);};l=H[c]=m(e);H.$watch(function(){var a=m(e);p(a,H[c])||(p(a,l)?n(e,a=H[c]):H[c]=a);return l=a},null,m.literal);break;case "&":m=r(I[g]);H[c]=function(a){return m(e,a)};break;default:throw ja("iscp",Q.name,c,a);}})}da=p&&u;L&&q(L,function(a){var b={$scope:a===Q||a.$$isolateScope?H:e,$element:x,$attrs:I,$transclude:da},c;R=a.controller;"@"==R&&(R= -I[a.name]);c=z(R,b);lb[a.name]=c;D||x.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});f=0;for(v=l.length;fG.priority)break;if(V=G.scope)A=A||G,G.templateUrl||(K("new/isolated scope",Q,G,Z),X(V)&&(Q=G));t=G.name;!G.templateUrl&&G.controller&&(V=G.controller,L=L||{},K("'"+t+"' controller",L[t],G,Z),L[t]=G);if(V=G.transclude)E=!0,G.$$tlb||(K("transclusion",T,G,Z),T=G),"element"==V?(D=!0,v=G.priority, -V=H(c,ra,W),Z=d.$$element=y(U.createComment(" "+t+": "+d[t]+" ")),c=Z[0],mb(g,y(ya.call(V,0)),c),Xa=x(V,e,v,f&&f.name,{nonTlbTranscludeDirective:T})):(V=y(Eb(c)).contents(),Z.empty(),Xa=x(V,e));if(G.template)if(K("template",ia,G,Z),ia=G,V=P(G.template)?G.template(Z,d):G.template,V=Y(V),G.replace){f=G;V=Cb.test(V)?y(V):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",t,"");mb(g,Z,c);S={$attr:{}};V=da(c,[],S);var $=a.splice(N+1,a.length-(N+1));Q&&pc(V);a=a.concat(V).concat($);B(d,S);S=a.length}else Z.html(V); -if(G.templateUrl)K("template",ia,G,Z),ia=G,G.replace&&(f=G),J=C(a.splice(N,a.length-N),Z,d,g,Xa,l,n,{controllerDirectives:L,newIsolateScopeDirective:Q,templateDirective:ia,nonTlbTranscludeDirective:T}),S=a.length;else if(G.compile)try{O=G.compile(Z,d,Xa),P(O)?u(null,O,ra,W):O&&u(O.pre,O.post,ra,W)}catch(aa){m(aa,ha(Z))}G.terminal&&(J.terminal=!0,v=Math.max(v,G.priority))}J.scope=A&&!0===A.scope;J.transclude=E&&Xa;p.hasElementTranscludeDirective=D;return J}function pc(a){for(var b=0,c=a.length;bp.priority)&&-1!=p.restrict.indexOf(g)&&(n&&(p=Tb(p,{$$start:n,$$end:r})),b.push(p),k=p)}catch(F){m(F)}}return k}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;q(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});q(b,function(b,g){"class"==g?(ma(e,b),a["class"]=(a["class"]? -a["class"]+" ":"")+b):"style"==g?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==g.charAt(0)||a.hasOwnProperty(g)||(a[g]=b,d[g]=c[g])})}function C(a,b,c,d,e,g,f,l){var k=[],m,r,z=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),x=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl;b.empty();n.get(v.getTrustedResourceUrl(x),{cache:p}).success(function(n){var p,J;n=Y(n);if(u.replace){n=Cb.test(n)?y(n):[];p=n[0];if(1!=n.length|| -1!==p.nodeType)throw ja("tplrt",u.name,x);n={$attr:{}};mb(d,b,p);var v=da(p,[],n);X(u.scope)&&pc(v);a=v.concat(a);B(c,n)}else p=z,b.html(n);a.unshift(F);m=ia(a,p,c,e,b,u,g,f,l);q(d,function(a,c){a==p&&(d[c]=b[0])});for(r=L(b[0].childNodes,e);k.length;){n=k.shift();J=k.shift();var A=k.shift(),R=k.shift(),v=b[0];if(J!==z){var H=J.className;l.hasElementTranscludeDirective&&u.replace||(v=Eb(p));mb(A,y(J),v);ma(y(v),H)}J=m.transclude?Q(n,m.transclude):R;m(r,n,v,d,J)}k=null}).error(function(a,b,c,d){throw ja("tpload", -d.url);});return function(a,b,c,d,e){k?(k.push(b),k.push(c),k.push(d),k.push(e)):m(r,b,c,d,e)}}function E(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status? -b:n.reject(b)}var d={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},g=function(a){function b(a){var c;q(a,function(b,d){P(b)&&(c=b(),null!=c?a[d]=c:delete a[d])})}var c=e.headers,d=D({},a.headers),g,f,c=D({},c.common,c[K(a.method)]);b(c);b(d);a:for(g in c){a=K(g);for(f in d)if(K(f)===a)continue a;d[g]=c[g]}return d}(a);D(d,a);d.headers=g;d.method=Fa(d.method);(a=Ib(d.url)?b.cookies()[d.xsrfCookieName||e.xsrfCookieName]:s)&&(g[d.xsrfHeaderName||e.xsrfHeaderName]= -a);var f=[function(a){g=a.headers;var b=uc(a.data,tc(g),a.transformRequest);E(a.data)&&q(g,function(a,b){"content-type"===K(b)&&delete g[b]});E(a.withCredentials)&&!E(e.withCredentials)&&(a.withCredentials=e.withCredentials);return z(a,b,g).then(c,c)},s],h=n.when(d);for(q(v,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var k=f.shift(),h=h.then(a,k)}h.success=function(a){h.then(function(b){a(b.data, -b.status,b.headers,d)});return h};h.error=function(a){h.then(null,function(b){a(b.data,b.status,b.headers,d)});return h};return h}function z(b,c,g){function f(a,b,c,e){v&&(200<=a&&300>a?v.put(s,[a,b,sc(c),e]):v.remove(s));l(b,a,c,e);d.$$phase||d.$apply()}function l(a,c,d,e){c=Math.max(c,0);(200<=c&&300>c?p.resolve:p.reject)({data:a,status:c,headers:tc(d),config:b,statusText:e})}function k(){var a=db(r.pendingRequests,b);-1!==a&&r.pendingRequests.splice(a,1)}var p=n.defer(),z=p.promise,v,q,s=u(b.url, -b.params);r.pendingRequests.push(b);z.then(k,k);(b.cache||e.cache)&&(!1!==b.cache&&"GET"==b.method)&&(v=X(b.cache)?b.cache:X(e.cache)?e.cache:F);if(v)if(q=v.get(s),B(q)){if(q.then)return q.then(k,k),q;M(q)?l(q[1],q[0],ba(q[2]),q[3]):l(q,200,{},"OK")}else v.put(s,z);E(q)&&a(b.method,s,c,f,g,b.timeout,b.withCredentials,b.responseType);return z}function u(a,b){if(!b)return a;var c=[];Sc(b,function(a,b){null===a||E(a)||(M(a)||(a=[a]),q(a,function(a){X(a)&&(a=qa(a));c.push(za(b)+"="+za(a))}))});0=S&&(!b.match(/^(get|post|head|put|delete|options)$/i)||!O.XMLHttpRequest))return new O.ActiveXObject("Microsoft.XMLHTTP");if(O.XMLHttpRequest)return new O.XMLHttpRequest;throw t("$httpBackend")("noxhr");}function Ud(){this.$get=["$browser","$window","$document",function(b,a,c){return ve(b,ue,b.defer,a.angular.callbacks,c[0])}]}function ve(b,a,c,d,e){function g(a,b){var c=e.createElement("script"),d=function(){c.onreadystatechange= -c.onload=c.onerror=null;e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;S&&8>=S?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=function(){d()};e.body.appendChild(c);return d}var f=-1;return function(e,l,k,m,n,p,r,z){function u(){v=f;A&&A();x&&x.abort()}function F(a,d,e,g,f){L&&c.cancel(L);A=x=null;0===d&&(d=e?200:"file"==sa(l).protocol?404:0);a(1223===d?204:d,e,g,f||"");b.$$completeOutstandingRequest(C)}var v;b.$$incOutstandingRequestCount(); -l=l||b.url();if("jsonp"==K(e)){var J="_"+(d.counter++).toString(36);d[J]=function(a){d[J].data=a};var A=g(l.replace("JSON_CALLBACK","angular.callbacks."+J),function(){d[J].data?F(m,200,d[J].data):F(m,v||-2);d[J]=Ea.noop})}else{var x=a(e);x.open(e,l,!0);q(n,function(a,b){B(a)&&x.setRequestHeader(b,a)});x.onreadystatechange=function(){if(x&&4==x.readyState){var a=null,b=null;v!==f&&(a=x.getAllResponseHeaders(),b="response"in x?x.response:x.responseText);F(m,v||x.status,b,a,x.statusText||"")}};r&&(x.withCredentials= -!0);if(z)try{x.responseType=z}catch(s){if("json"!==z)throw s;}x.send(k||null)}if(0=h&&(n.resolve(r),m(p.$$intervalId),delete e[p.$$intervalId]);z||b.$apply()},f);e[p.$$intervalId]=n;return p}var e={};d.cancel=function(a){return a&&a.$$intervalId in e?(e[a.$$intervalId].reject("canceled"),clearInterval(a.$$intervalId),delete e[a.$$intervalId], -!0):!1};return d}]}function ad(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "), -DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function wc(b){b=b.split("/");for(var a=b.length;a--;)b[a]=wb(b[a]);return b.join("/")}function xc(b,a,c){b=sa(b,c);a.$$protocol= -b.protocol;a.$$host=b.hostname;a.$$port=Y(b.port)||we[b.protocol]||null}function yc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=sa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=Yb(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function oa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ya(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Jb(b){return b.substr(0, -Ya(b).lastIndexOf("/")+1)}function zc(b,a){this.$$html5=!0;a=a||"";var c=Jb(b);xc(b,this,b);this.$$parse=function(a){var e=oa(c,a);if(!w(e))throw Kb("ipthprfx",a,c);yc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Zb(this.$$search),b=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=oa(b,d))!==s)return d=e,(e=oa(a,e))!==s?c+(oa("/",e)||e):b+d;if((e=oa(c, -d))!==s)return c+e;if(c==d+"/")return c}}function Lb(b,a){var c=Jb(b);xc(b,this,b);this.$$parse=function(d){var e=oa(b,d)||oa(c,d),e="#"==e.charAt(0)?oa(a,e):this.$$html5?e:"";if(!w(e))throw Kb("ihshprfx",d,a);yc(e,this,b);d=this.$$path;var g=/^\/?.*?:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));g.exec(e)||(d=(e=g.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Zb(this.$$search),e=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl= -b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(Ya(b)==Ya(a))return a}}function Ac(b,a){this.$$html5=!0;Lb.apply(this,arguments);var c=Jb(b);this.$$rewrite=function(d){var e;if(b==Ya(d))return d;if(e=oa(c,d))return b+a+e;if(c===d+"/")return c}}function nb(b){return function(){return this[b]}}function Bc(b,a){return function(c){if(E(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Vd(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode= -function(b){return B(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function f(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,l=d.baseHref(),k=d.url();a?(l=k.substring(0,k.indexOf("/",k.indexOf("//")+2))+(l||"/"),e=e.history?zc:Ac):(l=Ya(k),e=Lb);h=new e(l,"#"+b);h.$$parse(h.$$rewrite(k));g.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=y(a.target);"a"!==K(b[0].nodeName);)if(b[0]===g[0]||!(b=b.parent())[0])return; -var e=b.prop("href");X(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=sa(e.animVal).href);var f=h.$$rewrite(e);e&&(!b.attr("target")&&f&&!a.isDefaultPrevented())&&(a.preventDefault(),f!=d.url()&&(h.$$parse(f),c.$apply(),O.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=k&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):f(b)}),c.$$phase|| -c.$digest())});var m=0;c.$watch(function(){var a=d.url(),b=h.$$replace;m&&a==h.absUrl()||(m++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),f(a))}));h.$$replace=!1;return m});return h}]}function Wd(){var b=!0,a=this;this.debugEnabled=function(a){return B(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack: -a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||C;a=!1;try{a=!!e.apply}catch(l){}return a?function(){var a=[];q(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function fa(b,a){if("constructor"===b)throw Ba("isecfld",a);return b}function Za(b, -a){if(b){if(b.constructor===b)throw Ba("isecfn",a);if(b.document&&b.location&&b.alert&&b.setInterval)throw Ba("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw Ba("isecdom",a);}return b}function ob(b,a,c,d,e){e=e||{};a=a.split(".");for(var g,f=0;1e?Cc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,g){var f=0,h;do h=Cc(d[f++],d[f++],d[f++],d[f++],d[f++],c,a)(b,g),g=s,b=h;while(fa)for(b in l++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(q--,delete e[b])}else e!==d&&(e=d,l++);return l},function(){p?(p=!1,b(d,d,c)):b(d,f,c);if(h)if(X(d))if(ab(d)){f=Array(d.length);for(var a=0;as&&(y=4-s,Q[y]||(Q[y]=[]),H=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):d.exp,H+="; newVal: "+qa(g)+"; oldVal: "+qa(f),Q[y].push(H));else if(d===c){x=!1;break a}}catch(w){p.$$phase= -null,e(w)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((x||k.length)&&!s--)throw p.$$phase=null,a("infdig",b,qa(Q));}while(x||k.length);for(p.$$phase=null;m.length;)try{m.shift()()}catch(T){e(T)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(q(this.$$listenerCount,eb(null,m,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&& -(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=C,this.$on=this.$watch=function(){return C})}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a){p.$$phase|| -p.$$asyncQueue.length||f.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return l("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent); -var e=this;return function(){c[db(c,b)]=null;m(e,1,a)}},$emit:function(a,b){var c=[],d,g=this,f=!1,h={name:a,targetScope:g,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},l=[h].concat(ya.call(arguments,1)),k,m;do{d=g.$$listeners[a]||c;h.currentScope=g;k=0;for(m=d.length;kc.msieDocumentMode)throw ua("iequirks");var e=ba(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=Da);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b, -d(a,c))}};var g=e.parseAs,f=e.getTrusted,h=e.trustAs;q(ga,function(a,b){var c=K(b);e[Ta("parse_as_"+c)]=function(b){return g(a,b)};e[Ta("get_trusted_"+c)]=function(b){return f(a,b)};e[Ta("trust_as_"+c)]=function(b){return h(a,b)}});return e}]}function be(){this.$get=["$window","$document",function(b,a){var c={},d=Y((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),g=a[0]||{},f=g.documentMode,h,l=/^(Moz|webkit|O|ms)(?=[A-Z])/,k=g.body&&g.body.style, -m=!1,n=!1;if(k){for(var p in k)if(m=l.exec(p)){h=m[0];h=h.substr(0,1).toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in k&&"webkit");m=!!("transition"in k||h+"Transition"in k);n=!!("animation"in k||h+"Animation"in k);!d||m&&n||(m=w(g.body.style.webkitTransition),n=w(g.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!f||7b;b=Math.abs(b);var f=b+"",h="",l=[],k=!1;if(-1!==f.indexOf("e")){var m=f.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&m[3]>e+1?f="0":(h=f,k=!0)}if(k)0b)&&(h=b.toFixed(e)); -else{f=(f.split(Nc)[1]||"").length;E(e)&&(e=Math.min(Math.max(a.minFrac,f),a.maxFrac));f=Math.pow(10,e);b=Math.round(b*f)/f;b=(""+b).split(Nc);f=b[0];b=b[1]||"";var m=0,n=a.lgSize,p=a.gSize;if(f.length>=n+p)for(m=f.length-n,k=0;kb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Ob(e,a,d)}}function pb(b,a){return function(c,d){var e=c["get"+b](),g=Fa(a?"SHORT"+b:b);return d[g][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var g=0,f=0,h=b[8]?a.setUTCFullYear:a.setFullYear,l=b[8]?a.setUTCHours:a.setHours;b[9]&&(g=Y(b[9]+b[10]),f=Y(b[9]+b[11])); -h.call(a,Y(b[1]),Y(b[2])-1,Y(b[3]));g=Y(b[4]||0)-g;f=Y(b[5]||0)-f;h=Y(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));l.call(a,g,f,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g="",f=[],h,l;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;w(c)&&(c=Ge.test(c)?Y(c):a(c));vb(c)&&(c=new Date(c));if(!Na(c))return c;for(;e;)(l=He.exec(e))?(f=f.concat(ya.call(l,1)),e=f.pop()):(f.push(e),e=null);q(f,function(a){h= -Ie[a];g+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Ce(){return function(b){return qa(b,!0)}}function De(){return function(b,a){if(!M(b)&&!w(b))return b;a=Y(a);if(w(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||m()});if(e.hasEvent("paste"))a.on("paste cut",m)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)? -"":d.$viewValue)};var n=c.ngPattern;n&&((e=n.match(/^\/(.*)\/([gim]*)$/))?(n=RegExp(e[1],e[2]),e=function(a){return pa(d,"pattern",d.$isEmpty(a)||n.test(a),a)}):e=function(c){var e=b.$eval(n);if(!e||!e.test)throw t("ngPattern")("noregexp",n,e,ha(a));return pa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var p=Y(c.ngMinlength);e=function(a){return pa(d,"minlength",d.$isEmpty(a)||a.length>=p,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var r= -Y(c.ngMaxlength);e=function(a){return pa(d,"maxlength",d.$isEmpty(a)||a.length<=r,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Pb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dS?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Fa(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xc=/[A-Z]/g,$c={full:"1.2.16",major:1,minor:2,dot:16,codeName:"badger-enumeration"},Ua=N.cache={},gb=N.expando="ng-"+(new Date).getTime(), -me=1,Pc=O.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},Fb=O.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};N._data=function(b){return this.cache[b[this.expando]]||{}};var he=/([\:\-\_]+(.))/g,ie=/^moz([A-Z])/,Bb=t("jqLite"),je=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Cb=/<|&#?\w+;/,ke=/<([\w:]+)/,le=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea= -{option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th=ea.td;var Ja=N.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===U.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),N(O).on("load",a))},toString:function(){var b= -[];q(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?y(this[b]):y(this[this.length+b])},length:0,push:Ke,sort:[].sort,splice:[].splice},kb={};q("multiple selected checked disabled readOnly required open".split(" "),function(b){kb[K(b)]=b});var nc={};q("input select option textarea button form details".split(" "),function(b){nc[Fa(b)]=!0});q({data:jc,inheritedData:jb,scope:function(b){return y(b).data("$scope")||jb(b.parentNode||b,["$isolateScope","$scope"])}, -isolateScope:function(b){return y(b).data("$isolateScope")||y(b).data("$isolateScopeNoTemplate")},controller:kc,injector:function(b){return jb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Gb,css:function(b,a,c){a=Ta(a);if(B(c))b.style[a]=c;else{var d;8>=S&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=S&&(d=""===d?s:d);return d}},attr:function(b,a,c){var d=K(a);if(kb[d])if(B(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d)); -else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:s;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?s:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(E(d))return e?b[e]:"";b[e]=d}var a=[];9>S?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(E(a)){if("SELECT"===Ka(b)&&b.multiple){var c=[];q(b.options,function(a){a.selected&& -c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(E(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Ne={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'}, -Nb=function(a){this.options=a};Nb.prototype={constructor:Nb,lex:function(a){this.text=a;this.index=0;this.ch=s;this.lastCh=":";this.tokens=[];var c;for(a=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"=== -a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=B(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw Ba("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn($a.ZERO,a.fn, -this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Dc(d,this.options,this.text);return D(function(c,d,h){return e(h||a(c,d))},{assign:function(e,f,h){return ob(a(e,h),d,f,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,g){var f=a(e,g),h=d(e,g),l;if(!f)return s;(f=Za(f[h],c.text))&&(f.then&&c.options.unwrapPromises)&&(l=f,"$$v"in f||(l.$$v=s,l.then(function(a){l.$$v= -a})),f=f.$$v);return f},{assign:function(e,g,f){var h=d(e,f);return Za(a(e,f),c.text)[h]=g}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(g,f){for(var h=[],l=c?c(g,f):g,k=0;ka.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Ob(Math[0=S&&(c.href||c.name||c.$set("href",""),a.append(U.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var g="[object SVGAnimatedString]"===wa.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(g)||a.preventDefault()})}}}),zb={};q(kb,function(a,c){if("multiple"!=a){var d=na("ng-"+c);zb[d]=function(){return{priority:100,link:function(a,g,f){a.$watch(f[d],function(a){f.$set(c,!!a)})}}}}});q(["src", -"srcset","href"],function(a){var c=na("ng-"+a);zb[c]=function(){return{priority:99,link:function(d,e,g){var f=a,h=a;"href"===a&&"[object SVGAnimatedString]"===wa.call(e.prop("href"))&&(h="xlinkHref",g.$attr[h]="xlink:href",f=null);g.$observe(c,function(a){a&&(g.$set(h,a),S&&f&&e.prop(f,g[h]))})}}}});var sb={$addControl:C,$removeControl:C,$setValidity:C,$setDirty:C,$setPristine:C};Oc.$inject=["$element","$attrs","$scope","$animate"];var Qc=function(a){return["$timeout",function(c){return{name:"form", -restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,g,f){if(!g.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};Pc(e[0],"submit",h);e.on("$destroy",function(){c(function(){Fb(e[0],"submit",h)},0,!1)})}var l=e.parent().controller("form"),k=g.name||g.ngForm;k&&ob(a,k,f,k);if(l)e.on("$destroy",function(){l.$removeControl(f);k&&ob(a,k,s,k);D(f,sb)})}}}}}]},dd=Qc(),qd=Qc(!0),Oe=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/, -Pe=/^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i,Qe=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Rc={text:ub,number:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Qe.test(a))return e.$setValidity("number",!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return s});Je(e,"number",c);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return pa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a), -e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return pa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return pa(e,"number",e.$isEmpty(a)||vb(a),a)})},url:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"url",e.$isEmpty(a)||Oe.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"email",e.$isEmpty(a)||Pe.test(a),a)};e.$formatters.push(a); -e.$parsers.push(a)},radio:function(a,c,d,e){E(d.name)&&c.attr("name",bb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,f=d.ngFalseValue;w(g)||(g=!0);w(f)||(f=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==g}; -e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:f})},hidden:C,button:C,submit:C,reset:C,file:C},dc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,f){f&&(Rc[K(g.type)]||Rc.text)(d,e,g,f,c,a)}}}],rb="ng-valid",qb="ng-invalid",La="ng-pristine",tb="ng-dirty",Re=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,g,f){function h(a,c){c=c?"-"+fb(c,"-"):"";f.removeClass(e,(a?qb:rb)+c); -f.addClass(e,(a?rb:qb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var l=g(d.ngModel),k=l.assign;if(!k)throw t("ngModel")("nonassign",d.ngModel,ha(e));this.$render=C;this.$isEmpty=function(a){return E(a)||""===a||null===a||a!==a};var m=e.inheritedData("$formController")||sb,n=0,p=this.$error={};e.addClass(La);h(!0);this.$setValidity=function(a,c){p[a]!== -!c&&(c?(p[a]&&n--,n||(h(!0),this.$valid=!0,this.$invalid=!1)):(h(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,h(c,a),m.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;f.removeClass(e,tb);f.addClass(e,La)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,f.removeClass(e,La),f.addClass(e,tb),m.$setDirty());q(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,k(a,d),q(this.$viewChangeListeners, -function(a){try{a()}catch(d){c(d)}}))};var r=this;a.$watch(function(){var c=l(a);if(r.$modelValue!==c){var d=r.$formatters,e=d.length;for(r.$modelValue=c;e--;)c=d[e](c);r.$viewValue!==c&&(r.$viewValue=c,r.$render())}return c})}],Fd=function(){return{require:["ngModel","^?form"],controller:Re,link:function(a,c,d,e){var g=e[0],f=e[1]||sb;f.$addControl(g);a.$on("$destroy",function(){f.$removeControl(g)})}}},Hd=aa({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), -ec=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},Gd=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!E(a)){var c=[];a&&q(a.split(g),function(a){a&& -c.push(ca(a))});return c}});e.$formatters.push(function(a){return M(a)?a.join(", "):s});e.$isEmpty=function(a){return!a||!a.length}}}},Se=/^(true|false|\d+)$/,Id=function(){return{priority:100,compile:function(a,c){return Se.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a)})}}}},id=va(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==s?"":a)})}),kd=["$interpolate", -function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],jd=["$sce","$parse",function(a,c){return function(d,e,g){e.addClass("ng-binding").data("$binding",g.ngBindHtml);var f=c(g.ngBindHtml);d.$watch(function(){return(f(d)||"").toString()},function(c){e.html(a.getTrustedHtml(f(d))||"")})}}],ld=Pb("",!0),nd=Pb("Odd",0),md=Pb("Even",1),od=va({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}), -pd=[function(){return{scope:!0,controller:"@",priority:500}}],fc={};q("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=na("ng-"+a);fc[c]=["$parse",function(d){return{compile:function(e,g){var f=d(g[c]);return function(c,d,e){d.on(K(a),function(a){c.$apply(function(){f(c,{$event:a})})})}}}}]});var sd=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A", -$$tlb:!0,link:function(c,d,e,g,f){var h,l,k;c.$watch(e.ngIf,function(g){Qa(g)?l||(l=c.$new(),f(l,function(c){c[c.length++]=U.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)})):(k&&(k.remove(),k=null),l&&(l.$destroy(),l=null),h&&(k=yb(h.clone),a.leave(k,function(){k=null}),h=null))})}}}],td=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,g){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Ea.noop,compile:function(f, -h){var l=h.ngInclude||h.src,k=h.onload||"",m=h.autoscroll;return function(f,h,q,s,u){var F=0,v,y,A,x=function(){y&&(y.remove(),y=null);v&&(v.$destroy(),v=null);A&&(e.leave(A,function(){y=null}),y=A,A=null)};f.$watch(g.parseAsResourceUrl(l),function(g){var l=function(){!B(m)||m&&!f.$eval(m)||d()},q=++F;g?(a.get(g,{cache:c}).success(function(a){if(q===F){var c=f.$new();s.template=a;a=u(c,function(a){x();e.enter(a,null,h,l)});v=c;A=a;v.$emit("$includeContentLoaded");f.$eval(k)}}).error(function(){q=== -F&&x()}),f.$emit("$includeContentRequested")):(x(),s.template=null)})}}}}],Jd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,g){d.html(g.template);a(d.contents())(c)}}}],ud=va({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),vd=va({terminal:!0,priority:1E3}),wd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,f){var h=f.count,l=f.$attr.when&&g.attr(f.$attr.when),k=f.offset|| -0,m=e.$eval(l)||{},n={},p=c.startSymbol(),r=c.endSymbol(),s=/^when(Minus)?(.+)$/;q(f,function(a,c){s.test(c)&&(m[K(c.replace("when","").replace("Minus","-"))]=g.attr(f.$attr[c]))});q(m,function(a,e){n[e]=c(a.replace(d,p+h+"-"+k+r))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in m||(c=a.pluralCat(c-k));return n[c](e,g,!0)},function(a){g.text(a)})}}}],xd=["$parse","$animate",function(a,c){var d=t("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0, -link:function(e,g,f,h,l){var k=f.ngRepeat,m=k.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,r,s,u,F,v={$id:Ia};if(!m)throw d("iexp",k);f=m[1];h=m[2];(m=m[3])?(n=a(m),p=function(a,c,d){F&&(v[F]=a);v[u]=c;v.$index=d;return n(e,v)}):(r=function(a,c){return Ia(c)},s=function(a){return a});m=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!m)throw d("iidexp",f);u=m[3]||m[1];F=m[2];var B={};e.$watchCollection(h,function(a){var f,h,m=g[0],n,v={},H,R,w,C,T,t, -E=[];if(ab(a))T=a,n=p||r;else{n=p||s;T=[];for(w in a)a.hasOwnProperty(w)&&"$"!=w.charAt(0)&&T.push(w);T.sort()}H=T.length;h=E.length=T.length;for(f=0;fA;)z.pop().element.remove()}for(;x.length>I;)x.pop()[0].element.remove()}var k;if(!(k=t.match(d)))throw Te("iexp",t,ha(f));var l=c(k[2]||k[1]),m=k[4]||k[6],n=k[5],p=c(k[3]||""),q= -c(k[2]?k[1]:m),y=c(k[7]),w=k[8]?c(k[8]):null,x=[[{element:f,label:""}]];u&&(a(u)(e),u.removeClass("ng-scope"),u.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=y(e)||[],d={},h,k,l,p,t,v,u;if(r)for(k=[],p=0,v=x.length;p@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}'); +(function(W,X,t){'use strict';function C(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.26/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function dc(b){try{return decodeURIComponent(b)}catch(a){}}function ec(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=dc(c[0]),y(d)&&(b=y(c[1])?dc(c[1]):!0,kb.call(a,d)?J(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Cb(b){var a= +[];r(b,function(b,d){J(b)?r(b,function(b){a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))}):a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))});return a.length?a.join("&"):""}function lb(b){return Ca(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ca(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Xc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app", +"data-ng-app"],k=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;r(g,function(a){g[a]=!0;c(X.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(r(b.querySelectorAll("."+a),c),r(b.querySelectorAll("."+a+"\\:"),c),r(b.querySelectorAll("["+a+"]"),c))});r(d,function(a){if(!e){var b=k.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):r(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function fc(b,a){var c=function(){b=w(b);if(b.injector()){var c=b[0]===X? +"document":ia(b);throw Ta("btstrpd",c.replace(//,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=gc(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(W&&!d.test(W.name))return c();W.name=W.name.replace(d,"");Va.resumeBootstrap=function(b){r(b,function(b){a.push(b)});c()}}function mb(b,a){a= +a||"_";return b.replace(Yc,function(b,d){return(d?a:"")+b.toLowerCase()})}function Db(b,a,c){if(!b)throw Ta("areq",a||"?",c||"required");return b}function Wa(b,a,c){c&&J(b)&&(b=b[b.length-1]);Db(P(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Da(b,a){if("hasOwnProperty"===b)throw Ta("badname",a);}function hc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g 
"+e[1]+a.replace(me,"<$1>")+e[2];d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=Q?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ka(b,a){var c=typeof b,d;"function"==c||"object"==c&&null!==b?"function"==typeof(d= +b.$$hashKey)?d=b.$$hashKey():d===t&&(d=b.$$hashKey=(a||hb)()):d=b;return c+":"+d}function bb(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function sc(b){var a,c;"function"===typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(pe,""),c=c.match(qe),r(c[1].split(re),function(b){b.replace(se,function(b,c,d){a.push(d)})})),b.$inject=a):J(b)?(c=b.length-1,Wa(b[c],"fn"),a=b.slice(0,c)):Wa(b,"fn",!0);return a}function gc(b){function a(a){return function(b,c){if(T(b))r(b, +$b(a));else return a(b,c)}}function c(a,b){Da(a,"service");if(P(b)||J(b))b=n.instantiate(b);if(!b.$get)throw cb("pget",a);return l[a+k]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,k;r(a,function(a){if(!h.get(a)){h.put(a,!0);try{if(v(a))for(c=Ya(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,k=d.length;f 4096 bytes)!"));else{if(m.cookie!== +da)for(da=m.cookie,d=da.split("; "),O={},f=0;fh&&this.remove(p.key),b},get:function(a){if(h").parent()[0])});var f=L(a,b,a,c,d,e);ca(a,"ng-scope");return function(b,c,d,e){Db(b,"scope");var g=c?La.clone.call(a):a;r(d,function(a,b){g.data("$"+b+"Controller",a)});d=0;for(var m=g.length;darguments.length&& +(b=a,a=t);K&&(c=da);return p(a,b,c)}var u,M,z,O,I,B,da={},rb;u=c===f?d:ha(d,new Ob(w(f),d.$attr));M=u.$$element;if(L){var Na=/^\s*([@=&])(\??)\s*(\w*)\s*$/;B=e.$new(!0);!H||H!==L&&H!==L.$$originalDirective?M.data("$isolateScopeNoTemplate",B):M.data("$isolateScope",B);ca(M,"ng-isolate-scope");r(L.scope,function(a,c){var d=a.match(Na)||[],f=d[3]||c,g="?"==d[2],d=d[1],m,l,n,p;B.$$isolateBindings[c]=d+f;switch(d){case "@":u.$observe(f,function(a){B[c]=a});u.$$observers[f].$$scope=e;u[f]&&(B[c]=b(u[f])(e)); +break;case "=":if(g&&!u[f])break;l=q(u[f]);p=l.literal?Aa:function(a,b){return a===b||a!==a&&b!==b};n=l.assign||function(){m=B[c]=l(e);throw ja("nonassign",u[f],L.name);};m=B[c]=l(e);B.$watch(function(){var a=l(e);p(a,B[c])||(p(a,m)?n(e,a=B[c]):B[c]=a);return m=a},null,l.literal);break;case "&":l=q(u[f]);B[c]=function(a){return l(e,a)};break;default:throw ja("iscp",L.name,c,a);}})}rb=p&&F;R&&r(R,function(a){var b={$scope:a===L||a.$$isolateScope?B:e,$element:M,$attrs:u,$transclude:rb},c;I=a.controller; +"@"==I&&(I=u[a.name]);c=s(I,b);da[a.name]=c;K||M.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});g=0;for(z=m.length;gG.priority)break;if(V=G.scope)O=O||G,G.templateUrl||(db("new/isolated scope",L,G,Z),T(V)&&(L=G));C=G.name;!G.templateUrl&&G.controller&&(V=G.controller,R=R||{},db("'"+C+"' controller",R[C],G,Z),R[C]=G);if(V=G.transclude)x=!0,G.$$tlb|| +(db("transclusion",fa,G,Z),fa=G),"element"==V?(K=!0,u=G.priority,V=Z,Z=d.$$element=w(X.createComment(" "+C+": "+d[C]+" ")),c=Z[0],Na(f,Ba.call(V,0),c),S=z(V,e,u,g&&g.name,{nonTlbTranscludeDirective:fa})):(V=w(Kb(c)).contents(),Z.empty(),S=z(V,e));if(G.template)if(D=!0,db("template",H,G,Z),H=G,V=P(G.template)?G.template(Z,d):G.template,V=W(V),G.replace){g=G;V=Ib.test(V)?w(aa(V)):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",C,"");Na(f,Z,c);qa={$attr:{}};V=da(c,[],qa);var $=a.splice(Fa+ +1,a.length-(Fa+1));L&&y(V);a=a.concat(V).concat($);E(d,qa);qa=a.length}else Z.html(V);if(G.templateUrl)D=!0,db("template",H,G,Z),H=G,G.replace&&(g=G),N=ue(a.splice(Fa,a.length-Fa),Z,d,f,x&&S,m,n,{controllerDirectives:R,newIsolateScopeDirective:L,templateDirective:H,nonTlbTranscludeDirective:fa}),qa=a.length;else if(G.compile)try{Q=G.compile(Z,d,S),P(Q)?F(null,Q,U,Y):Q&&F(Q.pre,Q.post,U,Y)}catch(ve){l(ve,ia(Z))}G.terminal&&(N.terminal=!0,u=Math.max(u,G.priority))}N.scope=O&&!0===O.scope;N.transcludeOnThisElement= +x;N.templateOnThisElement=D;N.transclude=S;p.hasElementTranscludeDirective=K;return N}function y(a){for(var b=0,c=a.length;bp.priority)&&-1!=p.restrict.indexOf(f)&&(q&&(p=bc(p,{$$start:q,$$end:n})),b.push(p),h=p)}catch(F){l(F)}}return h}function E(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!= +e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(ca(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function ue(a,b,c,d,e,f,g,h){var m=[],l,q,s=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),N=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl; +b.empty();n.get(A.getTrustedResourceUrl(N),{cache:p}).success(function(n){var p,A;n=W(n);if(u.replace){n=Ib.test(n)?w(aa(n)):[];p=n[0];if(1!=n.length||1!==p.nodeType)throw ja("tplrt",u.name,N);n={$attr:{}};Na(d,b,p);var z=da(p,[],n);T(u.scope)&&y(z);a=z.concat(a);E(c,n)}else p=s,b.html(n);a.unshift(F);l=H(a,p,c,e,b,u,f,g,h);r(d,function(a,c){a==p&&(d[c]=b[0])});for(q=L(b[0].childNodes,e);m.length;){n=m.shift();A=m.shift();var R=m.shift(),I=m.shift(),z=b[0];if(A!==s){var B=A.className;h.hasElementTranscludeDirective&& +u.replace||(z=Kb(p));Na(R,w(A),z);ca(w(z),B)}A=l.transcludeOnThisElement?O(n,l.transclude,I):I;l(q,n,z,d,A)}m=null}).error(function(a,b,c,d){throw ja("tpload",d.url);});return function(a,b,c,d,e){a=e;m?(m.push(b),m.push(c),m.push(d),m.push(a)):(l.transcludeOnThisElement&&(a=O(b,l.transclude,e)),l(q,b,c,d,a))}}function x(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status?d:n.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},d=function(a){var b=e.headers,c=D({},a.headers),d,f,b=D({},b.common,b[K(a.method)]); +a:for(d in b){a=K(d);for(f in c)if(K(f)===a)continue a;c[d]=b[d]}(function(a){var b;r(a,function(c,d){P(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);return c}(a);D(c,a);c.headers=d;c.method=Ia(c.method);var f=[function(a){d=a.headers;var c=xc(a.data,wc(d),a.transformRequest);x(c)&&r(d,function(a,b){"content-type"===K(b)&&delete d[b]});x(a.withCredentials)&&!x(e.withCredentials)&&(a.withCredentials=e.withCredentials);return s(a,c,d).then(b,b)},t],g=n.when(c);for(r(A,function(a){(a.request||a.requestError)&& +f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var m=f.shift(),g=g.then(a,m)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,c)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,c)});return g};return g}function s(c,f,g){function h(a,b,c,e){I&&(200<=a&&300>a?I.put(w,[a,b,vc(c),e]):I.remove(w));p(b,a,c,e);d.$$phase||d.$apply()}function p(a,b,d,e){b=Math.max(b,0);(200<= +b&&300>b?A.resolve:A.reject)({data:a,status:b,headers:wc(d),config:c,statusText:e})}function s(){var a=Ra(q.pendingRequests,c);-1!==a&&q.pendingRequests.splice(a,1)}var A=n.defer(),r=A.promise,I,H,w=F(c.url,c.params);q.pendingRequests.push(c);r.then(s,s);!c.cache&&!e.cache||(!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method)||(I=T(c.cache)?c.cache:T(e.cache)?e.cache:u);if(I)if(H=I.get(w),y(H)){if(H&&P(H.then))return H.then(s,s),H;J(H)?p(H[1],H[0],ha(H[2]),H[3]):p(H,200,{},"OK")}else I.put(w,r);x(H)&& +((H=Pb(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:t)&&(g[c.xsrfHeaderName||e.xsrfHeaderName]=H),a(c.method,w,f,h,g,c.timeout,c.withCredentials,c.responseType));return r}function F(a,b){if(!b)return a;var c=[];Tc(b,function(a,b){null===a||x(a)||(J(a)||(a=[a]),r(a,function(a){T(a)&&(a=ta(a)?a.toISOString():na(a));c.push(Ca(b)+"="+Ca(a))}))});0=Q&&(!b.match(/^(get|post|head|put|delete|options)$/i)|| +!W.XMLHttpRequest))return new W.ActiveXObject("Microsoft.XMLHTTP");if(W.XMLHttpRequest)return new W.XMLHttpRequest;throw C("$httpBackend")("noxhr");}function Vd(){this.$get=["$browser","$window","$document",function(b,a,c){return ye(b,xe,b.defer,a.angular.callbacks,c[0])}]}function ye(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),g=null;f.type="text/javascript";f.src=a;f.async=!0;g=function(a){$a(f,"load",g);$a(f,"error",g);e.body.removeChild(f);f=null;var k=-1,s="unknown";a&&("load"!== +a.type||d[b].called||(a={type:"error"}),s=a.type,k="error"===a.type?404:200);c&&c(k,s)};sb(f,"load",g);sb(f,"error",g);8>=Q&&(f.onreadystatechange=function(){v(f.readyState)&&/loaded|complete/.test(f.readyState)&&(f.onreadystatechange=null,g({type:"load"}))});e.body.appendChild(f);return g}var g=-1;return function(e,m,h,l,n,p,q,s){function F(){A=g;R&&R();z&&z.abort()}function u(a,d,e,f,g){L&&c.cancel(L);R=z=null;0===d&&(d=e?200:"file"==ua(m).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(E)} +var A;b.$$incOutstandingRequestCount();m=m||b.url();if("jsonp"==K(e)){var N="_"+(d.counter++).toString(36);d[N]=function(a){d[N].data=a;d[N].called=!0};var R=f(m.replace("JSON_CALLBACK","angular.callbacks."+N),N,function(a,b){u(l,a,d[N].data,"",b);d[N]=E})}else{var z=a(e);z.open(e,m,!0);r(n,function(a,b){y(a)&&z.setRequestHeader(b,a)});z.onreadystatechange=function(){if(z&&4==z.readyState){var a=null,b=null,c="";A!==g&&(a=z.getAllResponseHeaders(),b="response"in z?z.response:z.responseText);A===g&& +10>Q||(c=z.statusText);u(l,A||z.status,b,a,c)}};q&&(z.withCredentials=!0);if(s)try{z.responseType=s}catch(ca){if("json"!==s)throw ca;}z.send(h||null)}if(0=k&&(n.resolve(q),l(p.$$intervalId),delete e[p.$$intervalId]);s||b.$apply()},g);e[p.$$intervalId]=n;return p}var e={};d.cancel= +function(b){return b&&b.$$intervalId in e?(e[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete e[b.$$intervalId],!0):!1};return d}]}function bd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "), +SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Qb(b){b=b.split("/");for(var a=b.length;a--;)b[a]= +lb(b[a]);return b.join("/")}function zc(b,a,c){b=ua(b,c);a.$$protocol=b.protocol;a.$$host=b.hostname;a.$$port=U(b.port)||ze[b.protocol]||null}function Ac(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=ua(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=ec(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function ra(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function eb(b){var a= +b.indexOf("#");return-1==a?b:b.substr(0,a)}function Rb(b){return b.substr(0,eb(b).lastIndexOf("/")+1)}function Bc(b,a){this.$$html5=!0;a=a||"";var c=Rb(b);zc(b,this,b);this.$$parse=function(a){var e=ra(c,a);if(!v(e))throw Sb("ipthprfx",a,c);Ac(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Cb(this.$$search),b=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e; +if((e=ra(b,d))!==t)return d=e,(e=ra(a,e))!==t?c+(ra("/",e)||e):b+d;if((e=ra(c,d))!==t)return c+e;if(c==d+"/")return c}}function Tb(b,a){var c=Rb(b);zc(b,this,b);this.$$parse=function(d){var e=ra(b,d)||ra(c,d),e="#"==e.charAt(0)?ra(a,e):this.$$html5?e:"";if(!v(e))throw Sb("ihshprfx",d,a);Ac(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash? +"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(eb(b)==eb(a))return a}}function Ub(b,a){this.$$html5=!0;Tb.apply(this,arguments);var c=Rb(b);this.$$rewrite=function(d){var e;if(b==eb(d))return d;if(e=ra(c,d))return b+a+e;if(c===d+"/")return c};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function tb(b){return function(){return this[b]}} +function Cc(b,a){return function(c){if(x(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Wd(){var b="",a=!1;this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return y(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",k.absUrl(),a)}var k,m,h=d.baseHref(),l=d.url(),n;a?(n=l.substring(0,l.indexOf("/",l.indexOf("//")+2))+(h||"/"),m=e.history?Bc:Ub):(n= +eb(l),m=Tb);k=new m(n,"#"+b);k.$$parse(k.$$rewrite(l));var p=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var e=w(a.target);"a"!==K(e[0].nodeName);)if(e[0]===f[0]||!(e=e.parent())[0])return;var g=e.prop("href");T(g)&&"[object SVGAnimatedString]"===g.toString()&&(g=ua(g.animVal).href);if(!p.test(g)){if(m===Ub){var h=e.attr("href")||e.attr("xlink:href");if(h&&0>h.indexOf("://"))if(g="#"+b,"/"==h[0])g=n+g+h;else if("#"==h[0])g=n+g+(k.path()||"/")+h; +else{var l=k.path().split("/"),h=h.split("/");2!==l.length||l[1]||(l.length=1);for(var q=0;qe?Dc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,f){var g=0,k;do k=Dc(d[g++],d[g++],d[g++],d[g++],d[g++],c,a)(b,f),f=t,b=k;while(ga)for(b in h++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(r--,delete e[b])}else e!==d&&(e=d,h++);return h},function(){n?(n=!1,b(d,d,c)):b(d,g,c);if(k)if(T(d))if(Pa(d)){g=Array(d.length);for(var a=0;at&&(w=4-t,O[w]||(O[w]=[]),B=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()): +d.exp,B+="; newVal: "+na(f)+"; oldVal: "+na(k),O[w].push(B));else if(d===c){z=!1;break a}}catch(y){p.$$phase=null,e(y)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((z||l.length)&&!t--)throw p.$$phase=null,a("infdig",b,na(O));}while(z||l.length);for(p.$$phase=null;r.length;)try{r.shift()()}catch(v){e(v)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(r(this.$$listenerCount, +Bb(null,l,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&&(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=E,this.$on= +this.$watch=function(){return E})}},$eval:function(a,b){return f(a)(this,b)},$evalAsync:function(a){p.$$phase||p.$$asyncQueue.length||g.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return m("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]= +c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){c[Ra(c,b)]=null;l(e,1,a)}},$emit:function(a,b){var c=[],d,f=this,g=!1,k={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){k.defaultPrevented=!0},defaultPrevented:!1},h=[k].concat(Ba.call(arguments,1)),l,m;do{d=f.$$listeners[a]||c;k.currentScope=f;l=0;for(m=d.length;lc.msieDocumentMode)throw xa("iequirks");var e=ha(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b}, +e.valueOf=Qa);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b,d(a,c))}};var f=e.parseAs,g=e.getTrusted,k=e.trustAs;r(ga,function(a,b){var c=K(b);e[Za("parse_as_"+c)]=function(b){return f(a,b)};e[Za("get_trusted_"+c)]=function(b){return g(a,b)};e[Za("trust_as_"+c)]=function(b){return k(a,b)}});return e}]}function ce(){this.$get=["$window","$document",function(b,a){var c={},d=U((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator|| +{}).userAgent),f=a[0]||{},g=f.documentMode,k,m=/^(Moz|webkit|O|ms)(?=[A-Z])/,h=f.body&&f.body.style,l=!1,n=!1;if(h){for(var p in h)if(l=m.exec(p)){k=l[0];k=k.substr(0,1).toUpperCase()+k.substr(1);break}k||(k="WebkitOpacity"in h&&"webkit");l=!!("transition"in h||k+"Transition"in h);n=!!("animation"in h||k+"Animation"in h);!d||l&&n||(l=v(f.body.style.webkitTransition),n=v(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!g||7< +g),hasEvent:function(a){if("input"==a&&9==Q)return!1;if(x(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:Xa(),vendorPrefix:k,transitions:l,animations:n,android:d,msie:Q,msieDocumentMode:g}}]}function ee(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,k,m){var h=c.defer(),l=h.promise,n=y(m)&&!m;k=a.defer(function(){try{h.resolve(e())}catch(a){h.reject(a),d(a)}finally{delete f[l.$$timeoutId]}n||b.$apply()},k);l.$$timeoutId=k;f[k]=h; +return l}var f={};e.cancel=function(b){return b&&b.$$timeoutId in f?(f[b.$$timeoutId].reject("canceled"),delete f[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return e}]}function ua(b,a){var c=b;Q&&(Y.setAttribute("href",c),c=Y.href);Y.setAttribute("href",c);return{href:Y.href,protocol:Y.protocol?Y.protocol.replace(/:$/,""):"",host:Y.host,search:Y.search?Y.search.replace(/^\?/,""):"",hash:Y.hash?Y.hash.replace(/^#/,""):"",hostname:Y.hostname,port:Y.port,pathname:"/"===Y.pathname.charAt(0)?Y.pathname: +"/"+Y.pathname}}function Pb(b){b=v(b)?ua(b):b;return b.protocol===Hc.protocol&&b.host===Hc.host}function fe(){this.$get=ba(W)}function mc(b){function a(d,e){if(T(d)){var f={};r(d,function(b,c){f[c]=a(c,b)});return f}return b.factory(d+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Ic);a("date",Jc);a("filter",Ce);a("json",De);a("limitTo",Ee);a("lowercase",Fe);a("number",Kc);a("orderBy",Lc);a("uppercase",Ge)}function Ce(){return function(b, +a,c){if(!J(b))return b;var d=typeof c,e=[];e.check=function(a){for(var b=0;bb;b=Math.abs(b);var g=b+"",k="",m=[],h=!1;if(-1!==g.indexOf("e")){var l=g.match(/([\d\.]+)e(-?)(\d+)/);l&&"-"==l[2]&& +l[3]>e+1?(g="0",b=0):(k=g,h=!0)}if(h)0b)&&(k=b.toFixed(e));else{g=(g.split(Nc)[1]||"").length;x(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);0===b&&(f=!1);b=(""+b).split(Nc);g=b[0];b=b[1]||"";var l=0,n=a.lgSize,p=a.gSize;if(g.length>=n+p)for(l=g.length-n,h=0;hb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Xb(e,a,d)}}function vb(b,a){return function(c,d){var e=c["get"+b](),f=Ia(a?"SHORT"+b:b);return d[f][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,k=b[8]? +a.setUTCFullYear:a.setFullYear,m=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=U(b[9]+b[10]),g=U(b[9]+b[11]));k.call(a,U(b[1]),U(b[2])-1,U(b[3]));f=U(b[4]||0)-f;g=U(b[5]||0)-g;k=U(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));m.call(a,f,g,k,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var f="",g=[],k,m;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;v(c)&&(c=He.test(c)?U(c):a(c));ib(c)&&(c=new Date(c)); +if(!ta(c))return c;for(;e;)(m=Ie.exec(e))?(g=g.concat(Ba.call(m,1)),e=g.pop()):(g.push(e),e=null);r(g,function(a){k=Je[a];f+=k?k(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return f}}function De(){return function(b){return na(b,!0)}}function Ee(){return function(b,a){if(!J(b)&&!v(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):U(a);if(v(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||q()});if(e.hasEvent("paste"))a.on("paste cut",q)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))?(s=RegExp(e[1],e[2]),e=function(a){return sa(d, +"pattern",d.$isEmpty(a)||s.test(a),a)}):e=function(c){var e=b.$eval(s);if(!e||!e.test)throw C("ngPattern")("noregexp",s,e,ia(a));return sa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var r=U(c.ngMinlength);e=function(a){return sa(d,"minlength",d.$isEmpty(a)||a.length>=r,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var u=U(c.ngMaxlength);e=function(a){return sa(d,"maxlength",d.$isEmpty(a)||a.length<=u,a)};d.$parsers.push(e); +d.$formatters.push(e)}}function Yb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dQ?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Ia(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xa=function(){if(y(Xa.isActive_))return Xa.isActive_;var b=!(!X.querySelector("[ng-csp]")&&!X.querySelector("[data-ng-csp]")); +if(!b)try{new Function("")}catch(a){b=!0}return Xa.isActive_=b},Yc=/[A-Z]/g,ad={full:"1.2.26",major:1,minor:2,dot:26,codeName:"captivating-disinterest"};S.expando="ng339";var ab=S.cache={},ne=1,sb=W.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},$a=W.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};S._data=function(b){return this.cache[b[this.expando]]||{}};var ie=/([\:\-\_]+(.))/g, +je=/^moz([A-Z])/,Hb=C("jqLite"),ke=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Ib=/<|&#?\w+;/,le=/<([\w:]+)/,me=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea={option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th= +ea.td;var La=S.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===X.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),S(W).on("load",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?w(this[b]):w(this[this.length+b])},length:0,push:Me,sort:[].sort,splice:[].splice},qb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){qb[K(b)]=b});var rc={};r("input select option textarea button form details".split(" "), +function(b){rc[Ia(b)]=!0});r({data:Mb,removeData:Lb},function(b,a){S[a]=b});r({data:Mb,inheritedData:pb,scope:function(b){return w.data(b,"$scope")||pb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return w.data(b,"$isolateScope")||w.data(b,"$isolateScopeNoTemplate")},controller:oc,injector:function(b){return pb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Nb,css:function(b,a,c){a=Za(a);if(y(c))b.style[a]=c;else{var d;8>=Q&&(d=b.currentStyle&&b.currentStyle[a], +""===d&&(d="auto"));d=d||b.style[a];8>=Q&&(d=""===d?t:d);return d}},attr:function(b,a,c){var d=K(a);if(qb[d])if(y(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||E).specified?d:t;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?t:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(x(d))return e?b[e]:"";b[e]=d}var a=[];9>Q?(a[1]= +"innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(x(a)){if("SELECT"===Ma(b)&&b.multiple){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(x(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Re={n:"\n",f:"\f",r:"\r", +t:"\t",v:"\v","'":"'",'"':'"'},Wb=function(a){this.options=a};Wb.prototype={constructor:Wb,lex:function(a){this.text=a;this.index=0;this.ch=t;this.lastCh=":";for(this.tokens=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=y(c)?"s "+c+"-"+this.index+" ["+ +this.text.substring(c,d)+"]":" "+d;throw la("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(fb.ZERO,a.fn, +this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Ec(d,this.options,this.text);return D(function(c,d,k){return e(k||a(c,d))},{assign:function(e,g,k){(k=a(e,k))||a.assign(e,k={});return ub(k,d,g,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,f){var g=a(e,f),k=d(e,f),m;ka(k,c.text);if(!g)return t;(g=va(g[k],c.text))&&(g.then&&c.options.unwrapPromises)&& +(m=g,"$$v"in g||(m.$$v=t,m.then(function(a){m.$$v=a})),g=g.$$v);return g},{assign:function(e,f,g){var k=ka(d(e,g),c.text);(g=va(a(e,g),c.text))||a.assign(e,g={});return g[k]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var k=[],m=c?c(f,g):f,h=0;ha.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Xb(Math[0< +a?"floor":"ceil"](a/60),2)+Xb(Math.abs(a%60),2))}},Ie=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,He=/^\-?\d+$/;Jc.$inject=["$locale"];var Fe=ba(K),Ge=ba(Ia);Lc.$inject=["$parse"];var dd=ba({restrict:"E",compile:function(a,c){8>=Q&&(c.href||c.name||c.$set("href",""),a.append(X.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===za.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)|| +a.preventDefault()})}}}),Fb={};r(qb,function(a,c){if("multiple"!=a){var d=pa("ng-"+c);Fb[d]=function(){return{priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});r(["src","srcset","href"],function(a){var c=pa("ng-"+a);Fb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,k=a;"href"===a&&"[object SVGAnimatedString]"===za.call(e.prop("href"))&&(k="xlinkHref",f.$attr[k]="xlink:href",g=null);f.$observe(c,function(c){c?(f.$set(k,c),Q&&g&&e.prop(g,f[k])):"href"=== +a&&f.$set(k,null)})}}}});var yb={$addControl:E,$removeControl:E,$setValidity:E,$setDirty:E,$setPristine:E};Oc.$inject=["$element","$attrs","$scope","$animate"];var Rc=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var k=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};sb(e[0],"submit",k);e.on("$destroy",function(){c(function(){$a(e[0],"submit",k)},0,!1)})}var m=e.parent().controller("form"), +h=f.name||f.ngForm;h&&ub(a,h,g,h);if(m)e.on("$destroy",function(){m.$removeControl(g);h&&ub(a,h,t,h);D(g,yb)})}}}}}]},ed=Rc(),rd=Rc(!0),Se=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Te=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Ue=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Sc={text:Ab,number:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Ue.test(a))return e.$setValidity("number", +!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return t});Ke(e,"number",Ve,null,e.$$validityState);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return sa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a),e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return sa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return sa(e,"number",e.$isEmpty(a)|| +ib(a),a)})},url:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return sa(e,"url",e.$isEmpty(a)||Se.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return sa(e,"email",e.$isEmpty(a)||Te.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){x(d.name)&&c.attr("name",hb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue}; +d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;v(f)||(f=!0);v(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:E,button:E,submit:E,reset:E,file:E},Ve=["badInput"],jc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel", +link:function(d,e,f,g){g&&(Sc[K(f.type)]||Sc.text)(d,e,f,g,c,a)}}}],wb="ng-valid",xb="ng-invalid",Oa="ng-pristine",zb="ng-dirty",We=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,f,g){function k(a,c){c=c?"-"+mb(c,"-"):"";g.removeClass(e,(a?xb:wb)+c);g.addClass(e,(a?wb:xb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name= +d.name;var m=f(d.ngModel),h=m.assign;if(!h)throw C("ngModel")("nonassign",d.ngModel,ia(e));this.$render=E;this.$isEmpty=function(a){return x(a)||""===a||null===a||a!==a};var l=e.inheritedData("$formController")||yb,n=0,p=this.$error={};e.addClass(Oa);k(!0);this.$setValidity=function(a,c){p[a]!==!c&&(c?(p[a]&&n--,n||(k(!0),this.$valid=!0,this.$invalid=!1)):(k(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,k(c,a),l.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine= +!0;g.removeClass(e,zb);g.addClass(e,Oa)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,g.removeClass(e,Oa),g.addClass(e,zb),l.$setDirty());r(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,h(a,d),r(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var q=this;a.$watch(function(){var c=m(a);if(q.$modelValue!==c){var d=q.$formatters,e=d.length;for(q.$modelValue=c;e--;)c=d[e](c);q.$viewValue!==c&&(q.$viewValue= +c,q.$render())}return c})}],Gd=function(){return{require:["ngModel","^?form"],controller:We,link:function(a,c,d,e){var f=e[0],g=e[1]||yb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},Id=ba({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),kc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required", +!0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},Hd=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!x(a)){var c=[];a&&r(a.split(f),function(a){a&&c.push(aa(a))});return c}});e.$formatters.push(function(a){return J(a)?a.join(", "):t});e.$isEmpty=function(a){return!a||!a.length}}}},Xe=/^(true|false|\d+)$/,Jd=function(){return{priority:100, +compile:function(a,c){return Xe.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},jd=ya({compile:function(a){a.addClass("ng-binding");return function(a,d,e){d.data("$binding",e.ngBind);a.$watch(e.ngBind,function(a){d.text(a==t?"":a)})}}}),ld=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}], +kd=["$sce","$parse",function(a,c){return{compile:function(d){d.addClass("ng-binding");return function(d,f,g){f.data("$binding",g.ngBindHtml);var k=c(g.ngBindHtml);d.$watch(function(){return(k(d)||"").toString()},function(c){f.html(a.getTrustedHtml(k(d))||"")})}}}}],md=Yb("",!0),od=Yb("Odd",0),nd=Yb("Even",1),pd=ya({compile:function(a,c){c.$set("ngCloak",t);a.removeClass("ng-cloak")}}),qd=[function(){return{scope:!0,controller:"@",priority:500}}],lc={},Ye={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "), +function(a){var c=pa("ng-"+a);lc[c]=["$parse","$rootScope",function(d,e){return{compile:function(f,g){var k=d(g[c]);return function(c,d){d.on(a,function(d){var f=function(){k(c,{$event:d})};Ye[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var td=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var k,m,h;c.$watch(e.ngIf,function(f){Ua(f)?m||(m=c.$new(),g(m,function(c){c[c.length++]=X.createComment(" end ngIf: "+e.ngIf+ +" ");k={clone:c};a.enter(c,d.parent(),d)})):(h&&(h.remove(),h=null),m&&(m.$destroy(),m=null),k&&(h=Eb(k.clone),a.leave(h,function(){h=null}),k=null))})}}}],ud=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,f){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Va.noop,compile:function(g,k){var m=k.ngInclude||k.src,h=k.onload||"",l=k.autoscroll;return function(g,k,q,r,F){var u=0,t,w,R,z=function(){w&&(w.remove(),w=null);t&&(t.$destroy(),t=null); +R&&(e.leave(R,function(){w=null}),w=R,R=null)};g.$watch(f.parseAsResourceUrl(m),function(f){var m=function(){!y(l)||l&&!g.$eval(l)||d()},q=++u;f?(a.get(f,{cache:c}).success(function(a){if(q===u){var c=g.$new();r.template=a;a=F(c,function(a){z();e.enter(a,null,k,m)});t=c;R=a;t.$emit("$includeContentLoaded");g.$eval(h)}}).error(function(){q===u&&z()}),g.$emit("$includeContentRequested")):(z(),r.template=null)})}}}}],Kd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude", +link:function(c,d,e,f){d.html(f.template);a(d.contents())(c)}}}],vd=ya({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),wd=ya({terminal:!0,priority:1E3}),xd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var k=g.count,m=g.$attr.when&&f.attr(g.$attr.when),h=g.offset||0,l=e.$eval(m)||{},n={},p=c.startSymbol(),q=c.endSymbol(),s=/^when(Minus)?(.+)$/;r(g,function(a,c){s.test(c)&&(l[K(c.replace("when","").replace("Minus","-"))]= +f.attr(g.$attr[c]))});r(l,function(a,e){n[e]=c(a.replace(d,p+k+"-"+h+q))});e.$watch(function(){var c=parseFloat(e.$eval(k));if(isNaN(c))return"";c in l||(c=a.pluralCat(c-h));return n[c](e,f,!0)},function(a){f.text(a)})}}}],yd=["$parse","$animate",function(a,c){var d=C("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,link:function(e,f,g,k,m){var h=g.ngRepeat,l=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,q,s,t,u,A={$id:Ka};if(!l)throw d("iexp", +h);g=l[1];k=l[2];(l=l[3])?(n=a(l),p=function(a,c,d){u&&(A[u]=a);A[t]=c;A.$index=d;return n(e,A)}):(q=function(a,c){return Ka(c)},s=function(a){return a});l=g.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!l)throw d("iidexp",g);t=l[3]||l[1];u=l[2];var y={};e.$watchCollection(k,function(a){var g,k,l=f[0],n,A={},B,I,H,v,E,C,x,J=[];if(Pa(a))C=a,E=p||q;else{E=p||s;C=[];for(H in a)a.hasOwnProperty(H)&&"$"!=H.charAt(0)&&C.push(H);C.sort()}B=C.length;k=J.length=C.length;for(g=0;gB;)d=t.pop(),p.removeOption(d.label),d.element.remove()}for(;z.length>M;)z.pop()[0].element.remove()}var h;if(!(h=s.match(d)))throw Ze("iexp",s,ia(f));var l=c(h[2]||h[1]),m=h[4]||h[6],n=h[5],r=c(h[3]||""),u=c(h[2]? +h[1]:m),w=c(h[7]),x=h[8]?c(h[8]):null,z=[[{element:f,label:""}]];F&&(a(F)(e),F.removeClass("ng-scope"),F.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=w(e)||[],d={},h,l,p,r,s,v,y;if(q)for(l=[],r=0,v=z.length;r@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}'); //# sourceMappingURL=angular.min.js.map diff --git a/bower_components/angular/angular.min.js.gzip b/bower_components/angular/angular.min.js.gzip old mode 100755 new mode 100644 index 5daa0cdc93f8c3f207689eed4fd93cc6b007b21d..2cfe6b78e8110dde8a314a589e08d5a8e27b2af6 GIT binary patch literal 39810 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 >T1}^S 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%0DP_J$*(3aXuaS&^J!a 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

P8W$j|{F))cucbQ0LuWex_UqnT}`oic`R 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","<=",">=","&&","||","&","|","!","ESCAPE","lex","ch","lastCh","tokens","is","readString","peek","readNumber","isIdent","readIdent","was","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","isExpOperator","start","end","colStr","peekCh","ident","lastDot","peekIndex","methodName","quote","rawString","hex","rep","ZERO","assignment","logicalOR","functionCall","fieldAccess","objectIndex","filterChain","this.filterChain","primary","statements","expect","consume","arrayDeclaration","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","ternaryFn","left","middle","binaryFn","statement","argsFn","fnInvoke","ternary","logicalAND","equality","relational","additive","multiplicative","unary","field","indexFn","o","safe","contextGetter","fnPtr","elementFns","allConstant","elementFn","keyValues","ampmGetter","getHours","AMPMS","timeZoneGetter","zone","getTimezoneOffset","paddedZone","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","formDirectiveFactory","isNgForm","formElement","action","preventDefaultListener","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","inputType","numberInputType","minValidator","maxValidator","urlInputType","urlValidator","emailInputType","emailValidator","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","NgModelController","$modelValue","NaN","$viewChangeListeners","ngModelGet","ngModel","ngModelSet","this.$isEmpty","inheritedData","this.$setValidity","this.$setPristine","this.$setViewValue","ngModelWatch","formatters","ctrls","modelCtrl","formCtrl","ngChange","required","ngList","viewValue","CONSTANT_VALUE_REGEXP","tpl","tplAttr","ngValue","ngValueConstantLink","ngValueLink","valueWatchAction","ngBind","ngBindWatchAction","ngBindTemplate","ngBindHtml","getStringValue","ngBindHtmlWatchAction","getTrustedHtml","$transclude","previousElements","ngIf","ngIfWatchAction","$anchorScroll","srcExp","ngInclude","onloadExp","autoScrollExp","autoscroll","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","newScope","$compile","ngInit","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","ngRepeat","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","valueIdentifier","keyIdentifier","hashFnLocals","lhs","rhs","trackByExp","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","arrayLength","collectionKeys","nextBlockOrder","trackByIdFn","trackById","$first","$last","$middle","$odd","$even","ngShow","ngShowWatchAction","ngHide","ngHideWatchAction","ngStyle","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","selectedScopes","ngSwitch","ngSwitchWatchAction","change","selectedTransclude","selectedScope","caseElement","anchor","ngSwitchWhen","$attrs","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","items","selectMultipleWatch","setupAsOptions","render","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","modelValue","valuesFn","keyName","groupIndex","selectedSet","lastElement","trackFn","trackIndex","valueName","groupByFn","modelCast","label","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","existingOption","optionTemplate","optionsExp","track","optionElement","ngOptions","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"] +"names":["window","document","undefined","minErr","isArrayLike","obj","isWindow","length","nodeType","isString","isArray","forEach","iterator","context","key","isFunction","hasOwnProperty","call","sortedKeys","keys","push","sort","forEachSorted","i","reverseParams","iteratorFn","value","nextUid","index","uid","digit","charCodeAt","join","String","fromCharCode","unshift","setHashKey","h","$$hashKey","extend","dst","arguments","int","str","parseInt","inherit","parent","extra","noop","identity","$","valueFn","isUndefined","isDefined","isObject","isNumber","isDate","toString","isRegExp","location","alert","setInterval","isElement","node","nodeName","prop","attr","find","map","results","list","indexOf","array","arrayRemove","splice","copy","source","destination","stackSource","stackDest","$evalAsync","$watch","ngMinErr","result","Date","getTime","RegExp","match","lastIndex","shallowCopy","src","charAt","equals","o1","o2","t1","t2","isNaN","keySet","bind","self","fn","curryArgs","slice","startIndex","apply","concat","toJsonReplacer","val","toJson","pretty","JSON","stringify","fromJson","json","parse","toBoolean","v","lowercase","startingTag","element","jqLite","clone","empty","e","elemHtml","append","html","TEXT_NODE","replace","tryDecodeURIComponent","decodeURIComponent","parseKeyValue","keyValue","key_value","split","toKeyValue","parts","arrayValue","encodeUriQuery","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","angularInit","bootstrap","elements","appElement","module","names","NG_APP_CLASS_REGEXP","name","getElementById","querySelectorAll","exec","className","attributes","modules","doBootstrap","injector","tag","$provide","createInjector","invoke","scope","compile","animate","$apply","data","NG_DEFER_BOOTSTRAP","test","angular","resumeBootstrap","angular.resumeBootstrap","extraModules","snake_case","separator","SNAKE_CASE_REGEXP","letter","pos","toLowerCase","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","constructor","assertNotHasOwnProperty","getter","path","bindFnToScope","lastInstance","len","getBlockElements","nodes","startNode","endNode","nextSibling","setupModuleLoader","$injectorMinErr","$$minErr","factory","requires","configFn","invokeLater","provider","method","insertMethod","invokeQueue","moduleInstance","runBlocks","config","run","block","publishExternalAPI","version","uppercase","csp","angularModule","$LocaleProvider","ngModule","$$SanitizeUriProvider","$CompileProvider","directive","htmlAnchorDirective","inputDirective","formDirective","scriptDirective","selectDirective","styleDirective","optionDirective","ngBindDirective","ngBindHtmlDirective","ngBindTemplateDirective","ngClassDirective","ngClassEvenDirective","ngClassOddDirective","ngCloakDirective","ngControllerDirective","ngFormDirective","ngHideDirective","ngIfDirective","ngIncludeDirective","ngInitDirective","ngNonBindableDirective","ngPluralizeDirective","ngRepeatDirective","ngShowDirective","ngStyleDirective","ngSwitchDirective","ngSwitchWhenDirective","ngSwitchDefaultDirective","ngOptionsDirective","ngTranscludeDirective","ngModelDirective","ngListDirective","ngChangeDirective","requiredDirective","ngValueDirective","ngIncludeFillContentDirective","ngAttributeAliasDirectives","ngEventDirectives","$AnchorScrollProvider","$AnimateProvider","$BrowserProvider","$CacheFactoryProvider","$ControllerProvider","$DocumentProvider","$ExceptionHandlerProvider","$FilterProvider","$InterpolateProvider","$IntervalProvider","$HttpProvider","$HttpBackendProvider","$LocationProvider","$LogProvider","$ParseProvider","$RootScopeProvider","$QProvider","$SceProvider","$SceDelegateProvider","$SnifferProvider","$TemplateCacheProvider","$TimeoutProvider","$WindowProvider","$$RAFProvider","$$AsyncCallbackProvider","camelCase","SPECIAL_CHARS_REGEXP","_","offset","toUpperCase","MOZ_HACK_REGEXP","jqLitePatchJQueryRemove","dispatchThis","filterElems","getterIfNoArguments","removePatch","param","filter","fireEvent","set","setIndex","setLength","childIndex","children","shift","triggerHandler","childLength","jQuery","originalJqFn","$original","JQLite","trim","jqLiteMinErr","parsed","SINGLE_TAG_REGEXP","fragment","createDocumentFragment","HTML_REGEXP","tmp","appendChild","createElement","TAG_NAME_REGEXP","wrap","wrapMap","_default","innerHTML","XHTML_TAG_REGEXP","removeChild","firstChild","lastChild","j","jj","childNodes","textContent","createTextNode","jqLiteAddNodes","jqLiteClone","cloneNode","jqLiteDealoc","jqLiteRemoveData","jqLiteOff","type","unsupported","events","jqLiteExpandoStore","handle","eventHandler","removeEventListenerFn","expandoId","ng339","expandoStore","jqCache","$destroy","jqId","jqLiteData","isSetter","keyDefined","isSimpleGetter","jqLiteHasClass","selector","getAttribute","jqLiteRemoveClass","cssClasses","setAttribute","cssClass","jqLiteAddClass","existingClasses","root","jqLiteController","jqLiteInheritedData","documentElement","ii","parentNode","host","jqLiteEmpty","getBooleanAttrName","booleanAttr","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","createEventHandler","event","preventDefault","event.preventDefault","returnValue","stopPropagation","event.stopPropagation","cancelBubble","target","srcElement","defaultPrevented","prevent","isDefaultPrevented","event.isDefaultPrevented","eventHandlersCopy","msie","elem","hashKey","nextUidFn","objType","HashMap","isolatedUid","this.nextUid","put","annotate","$inject","fnText","STRIP_COMMENTS","argDecl","FN_ARGS","FN_ARG_SPLIT","FN_ARG","all","underscore","last","modulesToLoad","supportObject","delegate","provider_","providerInjector","instantiate","$get","providerCache","providerSuffix","factoryFn","loadModules","moduleFn","loadedModules","get","_runBlocks","_invokeQueue","invokeArgs","message","stack","createInternalInjector","cache","getService","serviceName","INSTANTIATING","err","locals","args","Type","Constructor","returnedValue","prototype","instance","has","service","$injector","constant","instanceCache","decorator","decorFn","origProvider","orig$get","origProvider.$get","origInstance","instanceInjector","servicename","autoScrollingEnabled","disableAutoScrolling","this.disableAutoScrolling","$window","$location","$rootScope","getFirstAnchor","scroll","hash","elm","scrollIntoView","getElementsByName","scrollTo","autoScrollWatch","autoScrollWatchAction","$$rAF","$timeout","supported","Browser","$log","$sniffer","completeOutstandingRequest","outstandingRequestCount","outstandingRequestCallbacks","pop","error","startPoller","interval","setTimeout","check","pollFns","pollFn","pollTimeout","fireUrlChange","newLocation","lastBrowserUrl","url","urlChangeListeners","listener","rawDocument","history","clearTimeout","pendingDeferIds","isMock","$$completeOutstandingRequest","$$incOutstandingRequestCount","self.$$incOutstandingRequestCount","notifyWhenNoOutstandingRequests","self.notifyWhenNoOutstandingRequests","callback","addPollFn","self.addPollFn","href","baseElement","self.url","replaceState","pushState","urlChangeInit","onUrlChange","self.onUrlChange","on","hashchange","$$checkUrlChange","baseHref","self.baseHref","lastCookies","lastCookieString","cookiePath","cookies","self.cookies","cookieLength","cookie","escape","warn","cookieArray","unescape","substring","defer","self.defer","delay","timeoutId","cancel","self.defer.cancel","deferId","$document","this.$get","cacheFactory","cacheId","options","refresh","entry","freshEnd","staleEnd","n","link","p","nextEntry","prevEntry","caches","size","stats","capacity","Number","MAX_VALUE","lruHash","lruEntry","remove","removeAll","destroy","info","cacheFactory.info","cacheFactory.get","$cacheFactory","$$sanitizeUriProvider","hasDirectives","Suffix","COMMENT_DIRECTIVE_REGEXP","CLASS_DIRECTIVE_REGEXP","EVENT_HANDLER_ATTR_REGEXP","this.directive","registerDirective","directiveFactory","$exceptionHandler","directives","priority","require","controller","restrict","aHrefSanitizationWhitelist","this.aHrefSanitizationWhitelist","regexp","imgSrcSanitizationWhitelist","this.imgSrcSanitizationWhitelist","$interpolate","$http","$templateCache","$parse","$controller","$sce","$animate","$$sanitizeUri","$compileNodes","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","nodeValue","compositeLinkFn","compileNodes","safeAddClass","publicLinkFn","cloneConnectFn","transcludeControllers","parentBoundTranscludeFn","$linkNode","JQLitePrototype","eq","$element","addClass","nodeList","$rootElement","childLinkFn","childScope","childBoundTranscludeFn","nodeListLength","stableNodeList","Array","linkFns","nodeLinkFn","$new","transcludeOnThisElement","createBoundTranscludeFn","transclude","templateOnThisElement","attrs","linkFnFound","Attributes","collectDirectives","applyDirectivesToNode","$$element","terminal","previousBoundTranscludeFn","boundTranscludeFn","transcludedScope","cloneFn","controllers","scopeCreated","$$transcluded","attrsMap","$attr","addDirective","directiveNormalize","nodeName_","isNgAttr","nAttrs","attrStartName","attrEndName","specified","ngAttrName","NG_ATTR_BINDING","substr","directiveNName","nName","addAttrInterpolateDirective","addTextInterpolateDirective","byPriority","groupScan","attrStart","attrEnd","depth","hasAttribute","$compileMinErr","groupElementsLinkFnWrapper","linkFn","compileNode","templateAttrs","jqCollection","originalReplaceDirective","preLinkFns","postLinkFns","addLinkFns","pre","post","directiveName","newIsolateScopeDirective","$$isolateScope","cloneAndAnnotateFn","getControllers","elementControllers","retrievalMethod","optional","linkNode","controllersBoundTransclude","cloneAttachFn","hasElementTranscludeDirective","isolateScope","LOCAL_REGEXP","templateDirective","$$originalDirective","definition","scopeName","attrName","mode","lastValue","parentGet","parentSet","compare","$$isolateBindings","$observe","$$observers","$$scope","literal","a","b","assign","parentValueWatch","parentValue","controllerDirectives","controllerInstance","controllerAs","$scope","scopeToChild","template","templateUrl","terminalPriority","newScopeDirective","nonTlbTranscludeDirective","hasTranscludeDirective","hasTemplate","$compileNode","$template","childTranscludeFn","$$start","$$end","directiveValue","assertNoDuplicate","$$tlb","createComment","replaceWith","replaceDirective","contents","denormalizeTemplate","newTemplateAttrs","templateDirectives","unprocessedDirectives","markDirectivesAsIsolate","mergeTemplateAttributes","compileTemplateUrl","Math","max","tDirectives","startAttrName","endAttrName","srcAttr","dstAttr","$set","tAttrs","linkQueue","afterTemplateNodeLinkFn","afterTemplateChildLinkFn","beforeTemplateCompileNode","origAsyncDirective","derivedSyncDirective","getTrustedResourceUrl","success","content","tempTemplateAttrs","beforeTemplateLinkNode","linkRootElement","oldClasses","response","code","headers","delayedNodeLinkFn","ignoreChildLinkFn","rootElement","diff","what","previousDirective","text","interpolateFn","textInterpolateCompileFn","templateNode","hasCompileParent","textInterpolateLinkFn","bindings","interpolateFnWatchAction","getTrustedContext","attrNormalizedName","HTML","RESOURCE_URL","attrInterpolatePreLinkFn","$$inter","newValue","oldValue","$updateClass","elementsToRemove","newNode","firstElementToRemove","removeCount","j2","replaceChild","expando","k","kk","annotation","$addClass","classVal","$removeClass","removeClass","newClasses","toAdd","tokenDifference","toRemove","setClass","writeAttr","booleanKey","removeAttr","listeners","startSymbol","endSymbol","PREFIX_REGEXP","str1","str2","values","tokens1","tokens2","token","CNTRL_REG","register","this.register","expression","identifier","exception","cause","parseHeaders","line","headersGetter","headersObj","transformData","fns","JSON_START","JSON_END","PROTECTION_PREFIX","CONTENT_TYPE_APPLICATION_JSON","defaults","d","interceptorFactories","interceptors","responseInterceptorFactories","responseInterceptors","$httpBackend","$browser","$q","requestConfig","transformResponse","resp","status","reject","transformRequest","mergeHeaders","defHeaders","reqHeaders","defHeaderName","reqHeaderName","common","lowercaseDefHeaderName","execHeaders","headerContent","headerFn","header","chain","serverRequest","reqData","withCredentials","sendReq","then","promise","when","reversedInterceptors","interceptor","request","requestError","responseError","thenFn","rejectFn","promise.success","promise.error","done","headersString","statusText","resolvePromise","$$phase","deferred","resolve","removePendingReq","idx","pendingRequests","cachedResp","buildUrl","params","defaultCache","xsrfValue","urlIsSameOrigin","xsrfCookieName","xsrfHeaderName","timeout","responseType","toISOString","interceptorFactory","responseFn","createShortMethods","createShortMethodsWithData","createXhr","XMLHttpRequest","ActiveXObject","createHttpBackend","callbacks","$browserDefer","jsonpReq","callbackId","script","async","body","called","addEventListenerFn","onreadystatechange","script.onreadystatechange","readyState","ABORTED","timeoutRequest","jsonpDone","xhr","abort","completeRequest","urlResolve","protocol","counter","open","setRequestHeader","xhr.onreadystatechange","responseHeaders","getAllResponseHeaders","responseText","send","this.startSymbol","this.endSymbol","mustHaveExpression","trustedContext","endIndex","hasInterpolation","startSymbolLength","exp","endSymbolLength","$interpolateMinErr","part","getTrusted","valueOf","newErr","$interpolate.startSymbol","$interpolate.endSymbol","count","invokeApply","clearInterval","iteration","skipApply","$$intervalId","tick","notify","intervals","interval.cancel","short","pluralCat","num","encodePath","segments","parseAbsoluteUrl","absoluteUrl","locationObj","appBase","parsedUrl","$$protocol","$$host","hostname","$$port","port","DEFAULT_PORTS","parseAppUrl","relativeUrl","prefixed","$$path","pathname","$$search","search","$$hash","beginsWith","begin","whole","stripHash","stripFile","lastIndexOf","LocationHtml5Url","basePrefix","$$html5","appBaseNoFile","$$parse","this.$$parse","pathUrl","$locationMinErr","$$compose","this.$$compose","$$url","$$absUrl","$$rewrite","this.$$rewrite","appUrl","prevAppUrl","LocationHashbangUrl","hashPrefix","withoutBaseUrl","withoutHashUrl","windowsFilePathExp","firstPathSegmentMatch","LocationHashbangInHtml5Url","locationGetter","property","locationGetterSetter","preprocess","html5Mode","this.hashPrefix","prefix","this.html5Mode","afterLocationChange","oldUrl","$broadcast","absUrl","LocationMode","initialUrl","IGNORE_URI_REGEXP","ctrlKey","metaKey","which","absHref","animVal","rewrittenUrl","newUrl","$digest","changeCounter","$locationWatch","currentReplace","$$replace","debug","debugEnabled","this.debugEnabled","flag","formatError","Error","sourceURL","consoleLog","console","logFn","log","hasApply","arg1","arg2","ensureSafeMemberName","fullExpression","$parseMinErr","ensureSafeObject","Object","setter","setValue","fullExp","propertyObj","unwrapPromises","promiseWarning","$$v","cspSafeGetterFn","key0","key1","key2","key3","key4","cspSafePromiseEnabledGetter","pathVal","cspSafeGetter","getterFn","getterFnCache","pathKeys","pathKeysLength","evaledFnGetter","Function","$parseOptions","this.unwrapPromises","logPromiseWarnings","this.logPromiseWarnings","$filter","promiseWarningCache","parsedExpression","lexer","Lexer","parser","Parser","qFactory","nextTick","exceptionHandler","defaultCallback","defaultErrback","pending","ref","createInternalRejectedPromise","progress","errback","progressback","wrappedCallback","wrappedErrback","wrappedProgressback","catch","finally","makePromise","resolved","handleCallback","isResolved","callbackOutput","promises","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","webkitCancelRequestAnimationFrame","rafSupported","raf","id","timer","TTL","$rootScopeMinErr","lastDirtyWatch","digestTtl","this.digestTtl","Scope","$id","$parent","$$watchers","$$nextSibling","$$prevSibling","$$childHead","$$childTail","$root","$$destroyed","$$asyncQueue","$$postDigestQueue","$$listeners","$$listenerCount","beginPhase","phase","compileToFn","decrementListenerCount","current","initWatchVal","isolate","child","$$childScopeClass","this.$$childScopeClass","watchExp","objectEquality","watcher","listenFn","watcher.fn","newVal","oldVal","originalFn","deregisterWatch","$watchCollection","veryOldValue","trackVeryOldValue","changeDetected","objGetter","internalArray","internalObject","initRun","oldLength","$watchCollectionWatch","newLength","bothNaN","$watchCollectionAction","watch","watchers","asyncQueue","postDigestQueue","dirty","ttl","watchLog","logIdx","logMsg","asyncTask","$eval","next","$on","this.$watch","expr","$$postDigest","namedListeners","$emit","listenerArgs","array1","currentScope","sanitizeUri","uri","isImage","regex","normalizedVal","adjustMatcher","matcher","$sceMinErr","adjustMatchers","matchers","adjustedMatchers","SCE_CONTEXTS","resourceUrlWhitelist","resourceUrlBlacklist","this.resourceUrlWhitelist","this.resourceUrlBlacklist","generateHolderType","Base","holderType","trustedValue","$$unwrapTrustedValue","this.$$unwrapTrustedValue","holderType.prototype.valueOf","holderType.prototype.toString","htmlSanitizer","trustedValueHolderBase","byType","CSS","URL","JS","trustAs","maybeTrusted","allowed","enabled","this.enabled","$sceDelegate","msieDocumentMode","sce","isEnabled","sce.isEnabled","sce.getTrusted","parseAs","sce.parseAs","sceParseAsTrusted","enumValue","lName","eventSupport","android","userAgent","navigator","boxee","documentMode","vendorPrefix","vendorRegex","bodyStyle","style","transitions","animations","webkitTransition","webkitAnimation","hasEvent","divElm","deferreds","$$timeoutId","timeout.cancel","base","urlParsingNode","requestUrl","originUrl","filters","suffix","currencyFilter","dateFilter","filterFilter","jsonFilter","limitToFilter","lowercaseFilter","numberFilter","orderByFilter","uppercaseFilter","comparator","comparatorType","predicates","predicates.check","objKey","filtered","$locale","formats","NUMBER_FORMATS","amount","currencySymbol","CURRENCY_SYM","formatNumber","PATTERNS","GROUP_SEP","DECIMAL_SEP","number","fractionSize","pattern","groupSep","decimalSep","isFinite","isNegative","abs","numStr","formatedText","hasExponent","toFixed","fractionLen","min","minFrac","maxFrac","round","fraction","lgroup","lgSize","group","gSize","negPre","posPre","negSuf","posSuf","padNumber","digits","neg","dateGetter","date","dateStrGetter","shortForm","jsonStringToDate","string","R_ISO8601_STR","tzHour","tzMin","dateSetter","setUTCFullYear","setFullYear","timeSetter","setUTCHours","setHours","m","s","ms","parseFloat","format","DATETIME_FORMATS","NUMBER_STRING","DATE_FORMATS_SPLIT","DATE_FORMATS","object","input","limit","Infinity","out","sortPredicate","reverseOrder","reverseComparator","comp","descending","v1","v2","predicate","arrayCopy","ngDirective","FormController","toggleValidCss","isValid","validationErrorKey","VALID_CLASS","INVALID_CLASS","form","parentForm","nullFormCtrl","invalidCount","errors","$error","controls","$name","ngForm","$dirty","$pristine","$valid","$invalid","$addControl","PRISTINE_CLASS","form.$addControl","control","$removeControl","form.$removeControl","queue","validationToken","$setValidity","form.$setValidity","$setDirty","form.$setDirty","DIRTY_CLASS","$setPristine","form.$setPristine","validate","ctrl","validatorName","validity","testFlags","flags","addNativeHtml5Validators","badFlags","ignoreFlags","$$hasNativeValidators","$parsers","validator","textInputType","VALIDITY_STATE_PROPERTY","placeholder","noevent","$$validityState","composing","ev","ngTrim","revalidate","$viewValue","$setViewValue","deferListener","keyCode","$render","ctrl.$render","$isEmpty","ngPattern","patternValidator","patternObj","$formatters","ngMinlength","minlength","minLengthValidator","ngMaxlength","maxlength","maxLengthValidator","classDirective","arrayDifference","arrayClasses","classes","digestClassCounts","classCounts","classesToUpdate","ngClassWatchAction","$index","old$index","mod","isActive_","active","querySelector","addEventListener","attachEvent","removeEventListener","detachEvent","_data","JQLite._data","optgroup","option","tbody","tfoot","colgroup","caption","thead","th","td","ready","trigger","fired","removeAttribute","css","currentStyle","lowercasedName","getNamedItem","ret","getText","textProp","NODE_TYPE_TEXT_PROPERTY","$dv","multiple","selected","nodeCount","onFn","eventFns","contains","compareDocumentPosition","adown","bup","eventmap","related","relatedTarget","one","off","replaceNode","insertBefore","contentDocument","prepend","wrapNode","after","newElement","toggleClass","condition","classCondition","nextElementSibling","getElementsByTagName","extraParameters","dummyEvent","handlerArgs","eventName","eventFnsCopy","arg3","unbind","$animateMinErr","$$selectors","classNameFilter","this.classNameFilter","$$classNameFilter","$$asyncCallback","enter","leave","move","add","PATH_MATCH","paramValue","CALL","APPLY","BIND","OPERATORS","null","true","false","+","-","*","/","%","^","===","!==","==","!=","<",">","<=",">=","&&","||","&","|","!","ESCAPE","lex","ch","lastCh","tokens","is","readString","peek","readNumber","isIdent","readIdent","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","was","isExpOperator","start","end","colStr","peekCh","ident","lastDot","peekIndex","methodName","quote","rawString","hex","rep","ZERO","statements","primary","expect","filterChain","consume","arrayDeclaration","functionCall","objectIndex","fieldAccess","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","ternaryFn","left","middle","binaryFn","statement","argsFn","fnInvoke","assignment","ternary","logicalOR","logicalAND","equality","relational","additive","multiplicative","unary","field","o","indexFn","contextGetter","fnPtr","elementFns","allConstant","elementFn","keyValues","ampmGetter","getHours","AMPMS","timeZoneGetter","zone","getTimezoneOffset","paddedZone","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","formDirectiveFactory","isNgForm","formElement","action","preventDefaultListener","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","inputType","numberInputType","numberBadFlags","minValidator","maxValidator","urlInputType","urlValidator","emailInputType","emailValidator","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","NgModelController","$modelValue","NaN","$viewChangeListeners","ngModelGet","ngModel","ngModelSet","this.$isEmpty","inheritedData","this.$setValidity","this.$setPristine","this.$setViewValue","ngModelWatch","formatters","ctrls","modelCtrl","formCtrl","ngChange","required","ngList","viewValue","CONSTANT_VALUE_REGEXP","tpl","tplAttr","ngValue","ngValueConstantLink","ngValueLink","valueWatchAction","templateElement","ngBind","ngBindWatchAction","ngBindTemplate","tElement","ngBindHtml","getStringValue","ngBindHtmlWatchAction","getTrustedHtml","forceAsyncEvents","ngEventHandler","$transclude","previousElements","ngIf","ngIfWatchAction","$anchorScroll","srcExp","ngInclude","onloadExp","onload","autoScrollExp","autoscroll","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","newScope","$compile","ngInit","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","ngRepeat","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","valueIdentifier","keyIdentifier","hashFnLocals","lhs","rhs","trackByExp","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","arrayLength","trackByIdFn","collectionKeys","nextBlockOrder","trackById","$first","$last","$middle","$odd","$even","ngShow","ngShowWatchAction","ngHide","ngHideWatchAction","ngStyle","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","selectedScopes","ngSwitch","ngSwitchWatchAction","change","selectedTransclude","selectedScope","caseElement","anchor","ngSwitchWhen","$attrs","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","items","selectMultipleWatch","setupAsOptions","render","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","existingOption","modelValue","valuesFn","keyName","groupIndex","selectedSet","trackFn","trackIndex","valueName","lastElement","groupByFn","modelCast","label","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","optionTemplate","optionsExp","track","optionElement","toDisplay","ngOptions","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"] } diff --git a/bower_components/angular/bower.json b/bower_components/angular/bower.json old mode 100755 new mode 100644 index 55a3b8e..63d30a9 --- a/bower_components/angular/bower.json +++ b/bower_components/angular/bower.json @@ -1,6 +1,6 @@ { "name": "angular", - "version": "1.2.16", + "version": "1.2.26", "main": "./angular.js", "dependencies": { } diff --git a/bower_components/angular/package.json b/bower_components/angular/package.json new file mode 100644 index 0000000..d305473 --- /dev/null +++ b/bower_components/angular/package.json @@ -0,0 +1,25 @@ +{ + "name": "angular", + "version": "", + "description": "HTML enhanced for web apps", + "main": "angular.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/angular/angular.js.git" + }, + "keywords": [ + "angular", + "framework", + "browser", + "client-side" + ], + "author": "Angular Core Team ", + "license": "MIT", + "bugs": { + "url": "https://github.com/angular/angular.js/issues" + }, + "homepage": "http://angularjs.org" +} diff --git a/dist/angular-notify.js b/dist/angular-notify.js index 58242fc..491d27e 100644 --- a/dist/angular-notify.js +++ b/dist/angular-notify.js @@ -20,11 +20,13 @@ angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile',' args.position = args.position ? args.position : position; args.container = args.container ? args.container : container; args.classes = args.classes ? args.classes : ''; + args.onClose = args.onClose ? args.onClose : function () {return;}; var scope = args.scope ? args.scope.$new() : $rootScope.$new(); scope.$message = args.message; scope.$classes = args.classes; scope.$messageTemplate = args.messageTemplate; + scope.$onClose = args.onClose; $http.get(args.templateUrl,{cache: $templateCache}).success(function(template){ @@ -66,6 +68,7 @@ angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile',' scope.$close = function(){ templateElement.css('opacity',0).attr('data-closing','true'); layoutMessages(); + scope.$onClose(); }; var layoutMessages = function(){ @@ -101,7 +104,7 @@ angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile',' }); var retVal = {}; - + retVal.close = function(){ if (scope.$close){ scope.$close(); diff --git a/dist/angular-notify.min.js b/dist/angular-notify.min.js index 29bbe45..a883fb5 100644 --- a/dist/angular-notify.min.js +++ b/dist/angular-notify.min.js @@ -1 +1 @@ -angular.module("cgNotify",[]).factory("notify",["$timeout","$http","$compile","$templateCache","$rootScope",function(a,b,c,d,e){var f=10,g=15,h=1e4,i="angular-notify.html",j="center",k=document.body,l=[],m=function(m){"object"!=typeof m&&(m={message:m}),m.templateUrl=m.templateUrl?m.templateUrl:i,m.position=m.position?m.position:j,m.container=m.container?m.container:k,m.classes=m.classes?m.classes:"";var n=m.scope?m.scope.$new():e.$new();n.$message=m.message,n.$classes=m.classes,n.$messageTemplate=m.messageTemplate,b.get(m.templateUrl,{cache:d}).success(function(b){var d=c(b)(n);if(d.bind("webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd",function(a){("opacity"===a.propertyName||a.originalEvent&&"opacity"===a.originalEvent.propertyName)&&(d.remove(),l.splice(l.indexOf(d),1),j())}),m.messageTemplate){for(var e,i=0;i=0;c--){var d=10,e=l[c],h=e[0].offsetHeight,i=b+h+d;e.attr("data-closing")?i+=20:b+=h+g,e.css("top",i+"px").css("margin-top","-"+(h+d)+"px").css("visibility","visible"),a++}};a(function(){j()}),h>0&&a(function(){n.$close()},h)}).error(function(a){throw new Error("Template specified for cgNotify ("+m.templateUrl+") could not be loaded. "+a)});var o={};return o.close=function(){n.$close&&n.$close()},Object.defineProperty(o,"message",{get:function(){return n.$message},set:function(a){n.$message=a}}),o};return m.config=function(a){f=angular.isUndefined(a.startTop)?f:a.startTop,g=angular.isUndefined(a.verticalSpacing)?g:a.verticalSpacing,h=angular.isUndefined(a.duration)?h:a.duration,i=a.templateUrl?a.templateUrl:i,j=angular.isUndefined(a.position)?j:a.position,k=a.container?a.container:k},m.closeAll=function(){for(var a=l.length-1;a>=0;a--){var b=l[a];b.css("opacity",0)}},m}]),angular.module("cgNotify").run(["$templateCache",function(a){"use strict";a.put("angular-notify.html",'

\n\n
\n {{$message}}\n
\n\n
\n \n
\n\n \n\n
')}]); \ No newline at end of file +angular.module("cgNotify",[]).factory("notify",["$timeout","$http","$compile","$templateCache","$rootScope",function(a,b,c,d,e){var f=10,g=15,h=1e4,i="angular-notify.html",j="center",k=document.body,l=[],m=function(m){"object"!=typeof m&&(m={message:m}),m.templateUrl=m.templateUrl?m.templateUrl:i,m.position=m.position?m.position:j,m.container=m.container?m.container:k,m.classes=m.classes?m.classes:"",m.onClose=m.onClose?m.onClose:function(){};var n=m.scope?m.scope.$new():e.$new();n.$message=m.message,n.$classes=m.classes,n.$messageTemplate=m.messageTemplate,n.$onClose=m.onClose,b.get(m.templateUrl,{cache:d}).success(function(b){var d=c(b)(n);if(d.bind("webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd",function(a){("opacity"===a.propertyName||a.originalEvent&&"opacity"===a.originalEvent.propertyName)&&(d.remove(),l.splice(l.indexOf(d),1),j())}),m.messageTemplate){for(var e,i=0;i=0;c--){var d=10,e=l[c],h=e[0].offsetHeight,i=b+h+d;e.attr("data-closing")?i+=20:b+=h+g,e.css("top",i+"px").css("margin-top","-"+(h+d)+"px").css("visibility","visible"),a++}};a(function(){j()}),h>0&&a(function(){n.$close()},h)}).error(function(a){throw new Error("Template specified for cgNotify ("+m.templateUrl+") could not be loaded. "+a)});var o={};return o.close=function(){n.$close&&n.$close()},Object.defineProperty(o,"message",{get:function(){return n.$message},set:function(a){n.$message=a}}),o};return m.config=function(a){f=angular.isUndefined(a.startTop)?f:a.startTop,g=angular.isUndefined(a.verticalSpacing)?g:a.verticalSpacing,h=angular.isUndefined(a.duration)?h:a.duration,i=a.templateUrl?a.templateUrl:i,j=angular.isUndefined(a.position)?j:a.position,k=a.container?a.container:k},m.closeAll=function(){for(var a=l.length-1;a>=0;a--){var b=l[a];b.css("opacity",0)}},m}]),angular.module("cgNotify").run(["$templateCache",function(a){"use strict";a.put("angular-notify.html",'
\n\n
\n {{$message}}\n
\n\n
\n \n
\n\n \n\n
')}]); \ No newline at end of file From ace30d36cbd701aa133acabeeae91340d59748a9 Mon Sep 17 00:00:00 2001 From: pedrombafonso Date: Thu, 9 Oct 2014 17:02:53 +0100 Subject: [PATCH 4/4] bump: version & docs --- README.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b63bc1..caa74f9 100755 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ The `messageTemplate` property is also included on the scope as `$messageTemplat ## Release History + * v2.0.3 - 09/10/2014 + * Added onClose() method to notify constructor. * v2.0.2 - 09/06/2014 * Default template redesigned with a Bootstrap look and feel. Default template now also includes a close button. * Default message location is now the top center. diff --git a/package.json b/package.json index bdd0088..b01e184 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-notify", - "version": "2.0.2", + "version": "2.0.3", "description": "A minimalistic notification service for angular.", "repository": { "type": "git",