angularjs-rails 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/angularjs-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/angular-animate.js +78 -54
  4. data/vendor/assets/javascripts/angular-aria.js +5 -5
  5. data/vendor/assets/javascripts/angular-cookies.js +4 -4
  6. data/vendor/assets/javascripts/angular-loader.js +6 -6
  7. data/vendor/assets/javascripts/angular-messages.js +15 -15
  8. data/vendor/assets/javascripts/angular-mocks.js +34 -32
  9. data/vendor/assets/javascripts/angular-resource.js +22 -22
  10. data/vendor/assets/javascripts/angular-route.js +8 -8
  11. data/vendor/assets/javascripts/angular-sanitize.js +94 -63
  12. data/vendor/assets/javascripts/angular-scenario.js +532 -497
  13. data/vendor/assets/javascripts/angular-touch.js +3 -3
  14. data/vendor/assets/javascripts/angular.js +516 -475
  15. data/vendor/assets/javascripts/unstable/angular-animate.js +78 -54
  16. data/vendor/assets/javascripts/unstable/angular-aria.js +5 -5
  17. data/vendor/assets/javascripts/unstable/angular-cookies.js +4 -4
  18. data/vendor/assets/javascripts/unstable/angular-loader.js +6 -6
  19. data/vendor/assets/javascripts/unstable/angular-messages.js +15 -15
  20. data/vendor/assets/javascripts/unstable/angular-mocks.js +34 -32
  21. data/vendor/assets/javascripts/unstable/angular-resource.js +22 -22
  22. data/vendor/assets/javascripts/unstable/angular-route.js +8 -8
  23. data/vendor/assets/javascripts/unstable/angular-sanitize.js +94 -63
  24. data/vendor/assets/javascripts/unstable/angular-scenario.js +532 -497
  25. data/vendor/assets/javascripts/unstable/angular-touch.js +3 -3
  26. data/vendor/assets/javascripts/unstable/angular.js +516 -475
  27. metadata +14 -14
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0
2
+ * @license AngularJS v1.3.1
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -39,7 +39,7 @@ var ngRouteModule = angular.module('ngRoute', ['ng']).
39
39
  * ## Dependencies
40
40
  * Requires the {@link ngRoute `ngRoute`} module to be installed.
41
41
  */
42
- function $RouteProvider(){
42
+ function $RouteProvider() {
43
43
  function inherit(parent, extra) {
44
44
  return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);
45
45
  }
@@ -188,7 +188,7 @@ function $RouteProvider(){
188
188
 
189
189
  path = path
190
190
  .replace(/([().])/g, '\\$1')
191
- .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option){
191
+ .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) {
192
192
  var optional = option === '?' ? option : null;
193
193
  var star = option === '*' ? option : null;
194
194
  keys.push({ name: key, optional: !!optional });
@@ -870,7 +870,7 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
870
870
  * Emitted every time the ngView content is reloaded.
871
871
  */
872
872
  ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
873
- function ngViewFactory( $route, $anchorScroll, $animate) {
873
+ function ngViewFactory($route, $anchorScroll, $animate) {
874
874
  return {
875
875
  restrict: 'ECA',
876
876
  terminal: true,
@@ -887,16 +887,16 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
887
887
  update();
888
888
 
889
889
  function cleanupLastView() {
890
- if(previousLeaveAnimation) {
890
+ if (previousLeaveAnimation) {
891
891
  $animate.cancel(previousLeaveAnimation);
892
892
  previousLeaveAnimation = null;
893
893
  }
894
894
 
895
- if(currentScope) {
895
+ if (currentScope) {
896
896
  currentScope.$destroy();
897
897
  currentScope = null;
898
898
  }
899
- if(currentElement) {
899
+ if (currentElement) {
900
900
  previousLeaveAnimation = $animate.leave(currentElement);
901
901
  previousLeaveAnimation.then(function() {
902
902
  previousLeaveAnimation = null;
@@ -920,7 +920,7 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
920
920
  // function is called before linking the content, which would apply child
921
921
  // directives to non existing elements.
922
922
  var clone = $transclude(newScope, function(clone) {
923
- $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter () {
923
+ $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() {
924
924
  if (angular.isDefined(autoScrollExp)
925
925
  && (!autoScrollExp || scope.$eval(autoScrollExp))) {
926
926
  $anchorScroll();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0
2
+ * @license AngularJS v1.3.1
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -45,16 +45,16 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
45
45
  * @kind function
46
46
  *
47
47
  * @description
48
- * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
48
+ * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are
49
49
  * then serialized back to properly escaped html string. This means that no unsafe input can make
50
50
  * it into the returned string, however, since our parser is more strict than a typical browser
51
51
  * parser, it's possible that some obscure input, which would be recognized as valid HTML by a
52
- * browser, won't make it through the sanitizer.
52
+ * browser, won't make it through the sanitizer. The input may also contain SVG markup.
53
53
  * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
54
54
  * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
55
55
  *
56
- * @param {string} html Html input.
57
- * @returns {string} Sanitized html.
56
+ * @param {string} html HTML input.
57
+ * @returns {string} Sanitized HTML.
58
58
  *
59
59
  * @example
60
60
  <example module="sanitizeExample" deps="angular-sanitize.js">
@@ -198,6 +198,12 @@ var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a
198
198
  "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
199
199
  "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
200
200
 
201
+ // SVG Elements
202
+ // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
203
+ var svgElements = makeMap("animate,animateColor,animateMotion,animateTransform,circle,defs," +
204
+ "desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient," +
205
+ "line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set," +
206
+ "stop,svg,switch,text,title,tspan,use");
201
207
 
202
208
  // Special Elements (can contain anything)
203
209
  var specialElements = makeMap("script,style");
@@ -206,16 +212,41 @@ var validElements = angular.extend({},
206
212
  voidElements,
207
213
  blockElements,
208
214
  inlineElements,
209
- optionalEndTagElements);
215
+ optionalEndTagElements,
216
+ svgElements);
210
217
 
211
218
  //Attributes that have href and hence need to be sanitized
212
- var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
213
- var validAttrs = angular.extend({}, uriAttrs, makeMap(
214
- 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
219
+ var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap,xlink:href");
220
+
221
+ var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
215
222
  'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
216
223
  'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
217
224
  'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
218
- 'valign,value,vspace,width'));
225
+ 'valign,value,vspace,width');
226
+
227
+ // SVG attributes (without "id" and "name" attributes)
228
+ // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
229
+ var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,'+
230
+ 'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,'+
231
+ 'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,'+
232
+ 'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,'+
233
+ 'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,'+
234
+ 'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,'+
235
+ 'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,'+
236
+ 'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,'+
237
+ 'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,'+
238
+ 'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,'+
239
+ 'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,'+
240
+ 'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,'+
241
+ 'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,'+
242
+ 'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,'+
243
+ 'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,'+
244
+ 'zoomAndPan');
245
+
246
+ var validAttrs = angular.extend({},
247
+ uriAttrs,
248
+ svgAttrs,
249
+ htmlAttrs);
219
250
 
220
251
  function makeMap(str) {
221
252
  var obj = {}, items = str.split(','), i;
@@ -236,7 +267,7 @@ function makeMap(str) {
236
267
  * @param {string} html string
237
268
  * @param {object} handler
238
269
  */
239
- function htmlParser( html, handler ) {
270
+ function htmlParser(html, handler) {
240
271
  if (typeof html !== 'string') {
241
272
  if (html === null || typeof html === 'undefined') {
242
273
  html = '';
@@ -247,50 +278,50 @@ function htmlParser( html, handler ) {
247
278
  var index, chars, match, stack = [], last = html, text;
248
279
  stack.last = function() { return stack[ stack.length - 1 ]; };
249
280
 
250
- while ( html ) {
281
+ while (html) {
251
282
  text = '';
252
283
  chars = true;
253
284
 
254
285
  // Make sure we're not in a script or style element
255
- if ( !stack.last() || !specialElements[ stack.last() ] ) {
286
+ if (!stack.last() || !specialElements[ stack.last() ]) {
256
287
 
257
288
  // Comment
258
- if ( html.indexOf("<!--") === 0 ) {
289
+ if (html.indexOf("<!--") === 0) {
259
290
  // comments containing -- are not allowed unless they terminate the comment
260
291
  index = html.indexOf("--", 4);
261
292
 
262
- if ( index >= 0 && html.lastIndexOf("-->", index) === index) {
263
- if (handler.comment) handler.comment( html.substring( 4, index ) );
264
- html = html.substring( index + 3 );
293
+ if (index >= 0 && html.lastIndexOf("-->", index) === index) {
294
+ if (handler.comment) handler.comment(html.substring(4, index));
295
+ html = html.substring(index + 3);
265
296
  chars = false;
266
297
  }
267
298
  // DOCTYPE
268
- } else if ( DOCTYPE_REGEXP.test(html) ) {
269
- match = html.match( DOCTYPE_REGEXP );
299
+ } else if (DOCTYPE_REGEXP.test(html)) {
300
+ match = html.match(DOCTYPE_REGEXP);
270
301
 
271
- if ( match ) {
272
- html = html.replace( match[0], '');
302
+ if (match) {
303
+ html = html.replace(match[0], '');
273
304
  chars = false;
274
305
  }
275
306
  // end tag
276
- } else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
277
- match = html.match( END_TAG_REGEXP );
307
+ } else if (BEGING_END_TAGE_REGEXP.test(html)) {
308
+ match = html.match(END_TAG_REGEXP);
278
309
 
279
- if ( match ) {
280
- html = html.substring( match[0].length );
281
- match[0].replace( END_TAG_REGEXP, parseEndTag );
310
+ if (match) {
311
+ html = html.substring(match[0].length);
312
+ match[0].replace(END_TAG_REGEXP, parseEndTag);
282
313
  chars = false;
283
314
  }
284
315
 
285
316
  // start tag
286
- } else if ( BEGIN_TAG_REGEXP.test(html) ) {
287
- match = html.match( START_TAG_REGEXP );
317
+ } else if (BEGIN_TAG_REGEXP.test(html)) {
318
+ match = html.match(START_TAG_REGEXP);
288
319
 
289
- if ( match ) {
320
+ if (match) {
290
321
  // We only have a valid start-tag if there is a '>'.
291
- if ( match[4] ) {
292
- html = html.substring( match[0].length );
293
- match[0].replace( START_TAG_REGEXP, parseStartTag );
322
+ if (match[4]) {
323
+ html = html.substring(match[0].length);
324
+ match[0].replace(START_TAG_REGEXP, parseStartTag);
294
325
  }
295
326
  chars = false;
296
327
  } else {
@@ -300,29 +331,29 @@ function htmlParser( html, handler ) {
300
331
  }
301
332
  }
302
333
 
303
- if ( chars ) {
334
+ if (chars) {
304
335
  index = html.indexOf("<");
305
336
 
306
- text += index < 0 ? html : html.substring( 0, index );
307
- html = index < 0 ? "" : html.substring( index );
337
+ text += index < 0 ? html : html.substring(0, index);
338
+ html = index < 0 ? "" : html.substring(index);
308
339
 
309
- if (handler.chars) handler.chars( decodeEntities(text) );
340
+ if (handler.chars) handler.chars(decodeEntities(text));
310
341
  }
311
342
 
312
343
  } else {
313
344
  html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
314
- function(all, text){
345
+ function(all, text) {
315
346
  text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
316
347
 
317
- if (handler.chars) handler.chars( decodeEntities(text) );
348
+ if (handler.chars) handler.chars(decodeEntities(text));
318
349
 
319
350
  return "";
320
351
  });
321
352
 
322
- parseEndTag( "", stack.last() );
353
+ parseEndTag("", stack.last());
323
354
  }
324
355
 
325
- if ( html == last ) {
356
+ if (html == last) {
326
357
  throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
327
358
  "of html: {0}", html);
328
359
  }
@@ -332,22 +363,22 @@ function htmlParser( html, handler ) {
332
363
  // Clean up any remaining tags
333
364
  parseEndTag();
334
365
 
335
- function parseStartTag( tag, tagName, rest, unary ) {
366
+ function parseStartTag(tag, tagName, rest, unary) {
336
367
  tagName = angular.lowercase(tagName);
337
- if ( blockElements[ tagName ] ) {
338
- while ( stack.last() && inlineElements[ stack.last() ] ) {
339
- parseEndTag( "", stack.last() );
368
+ if (blockElements[ tagName ]) {
369
+ while (stack.last() && inlineElements[ stack.last() ]) {
370
+ parseEndTag("", stack.last());
340
371
  }
341
372
  }
342
373
 
343
- if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
344
- parseEndTag( "", tagName );
374
+ if (optionalEndTagElements[ tagName ] && stack.last() == tagName) {
375
+ parseEndTag("", tagName);
345
376
  }
346
377
 
347
378
  unary = voidElements[ tagName ] || !!unary;
348
379
 
349
- if ( !unary )
350
- stack.push( tagName );
380
+ if (!unary)
381
+ stack.push(tagName);
351
382
 
352
383
  var attrs = {};
353
384
 
@@ -360,22 +391,22 @@ function htmlParser( html, handler ) {
360
391
 
361
392
  attrs[name] = decodeEntities(value);
362
393
  });
363
- if (handler.start) handler.start( tagName, attrs, unary );
394
+ if (handler.start) handler.start(tagName, attrs, unary);
364
395
  }
365
396
 
366
- function parseEndTag( tag, tagName ) {
397
+ function parseEndTag(tag, tagName) {
367
398
  var pos = 0, i;
368
399
  tagName = angular.lowercase(tagName);
369
- if ( tagName )
400
+ if (tagName)
370
401
  // Find the closest opened tag of the same type
371
- for ( pos = stack.length - 1; pos >= 0; pos-- )
372
- if ( stack[ pos ] == tagName )
402
+ for (pos = stack.length - 1; pos >= 0; pos--)
403
+ if (stack[ pos ] == tagName)
373
404
  break;
374
405
 
375
- if ( pos >= 0 ) {
406
+ if (pos >= 0) {
376
407
  // Close all the open elements, up the stack
377
- for ( i = stack.length - 1; i >= pos; i-- )
378
- if (handler.end) handler.end( stack[ i ] );
408
+ for (i = stack.length - 1; i >= pos; i--)
409
+ if (handler.end) handler.end(stack[ i ]);
379
410
 
380
411
  // Remove the open elements from the stack
381
412
  stack.length = pos;
@@ -421,12 +452,12 @@ function decodeEntities(value) {
421
452
  function encodeEntities(value) {
422
453
  return value.
423
454
  replace(/&/g, '&amp;').
424
- replace(SURROGATE_PAIR_REGEXP, function (value) {
455
+ replace(SURROGATE_PAIR_REGEXP, function(value) {
425
456
  var hi = value.charCodeAt(0);
426
457
  var low = value.charCodeAt(1);
427
458
  return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
428
459
  }).
429
- replace(NON_ALPHANUMERIC_REGEXP, function(value){
460
+ replace(NON_ALPHANUMERIC_REGEXP, function(value) {
430
461
  return '&#' + value.charCodeAt(0) + ';';
431
462
  }).
432
463
  replace(/</g, '&lt;').
@@ -443,11 +474,11 @@ function encodeEntities(value) {
443
474
  * comment: function(text) {}
444
475
  * }
445
476
  */
446
- function htmlSanitizeWriter(buf, uriValidator){
477
+ function htmlSanitizeWriter(buf, uriValidator) {
447
478
  var ignore = false;
448
479
  var out = angular.bind(buf, buf.push);
449
480
  return {
450
- start: function(tag, attrs, unary){
481
+ start: function(tag, attrs, unary) {
451
482
  tag = angular.lowercase(tag);
452
483
  if (!ignore && specialElements[tag]) {
453
484
  ignore = tag;
@@ -455,7 +486,7 @@ function htmlSanitizeWriter(buf, uriValidator){
455
486
  if (!ignore && validElements[tag] === true) {
456
487
  out('<');
457
488
  out(tag);
458
- angular.forEach(attrs, function(value, key){
489
+ angular.forEach(attrs, function(value, key) {
459
490
  var lkey=angular.lowercase(key);
460
491
  var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
461
492
  if (validAttrs[lkey] === true &&
@@ -470,7 +501,7 @@ function htmlSanitizeWriter(buf, uriValidator){
470
501
  out(unary ? '/>' : '>');
471
502
  }
472
503
  },
473
- end: function(tag){
504
+ end: function(tag) {
474
505
  tag = angular.lowercase(tag);
475
506
  if (!ignore && validElements[tag] === true) {
476
507
  out('</');
@@ -481,7 +512,7 @@ function htmlSanitizeWriter(buf, uriValidator){
481
512
  ignore = false;
482
513
  }
483
514
  },
484
- chars: function(chars){
515
+ chars: function(chars) {
485
516
  if (!ignore) {
486
517
  out(encodeEntities(chars));
487
518
  }
@@ -9190,7 +9190,7 @@ return jQuery;
9190
9190
  }));
9191
9191
 
9192
9192
  /**
9193
- * @license AngularJS v1.3.0
9193
+ * @license AngularJS v1.3.1
9194
9194
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9195
9195
  * License: MIT
9196
9196
  */
@@ -9229,12 +9229,12 @@ return jQuery;
9229
9229
 
9230
9230
  function minErr(module, ErrorConstructor) {
9231
9231
  ErrorConstructor = ErrorConstructor || Error;
9232
- return function () {
9232
+ return function() {
9233
9233
  var code = arguments[0],
9234
9234
  prefix = '[' + (module ? module + ':' : '') + code + '] ',
9235
9235
  template = arguments[1],
9236
9236
  templateArgs = arguments,
9237
- stringify = function (obj) {
9237
+ stringify = function(obj) {
9238
9238
  if (typeof obj === 'function') {
9239
9239
  return obj.toString().replace(/ \{[\s\S]*$/, '');
9240
9240
  } else if (typeof obj === 'undefined') {
@@ -9246,7 +9246,7 @@ function minErr(module, ErrorConstructor) {
9246
9246
  },
9247
9247
  message, i;
9248
9248
 
9249
- message = prefix + template.replace(/\{\d+\}/g, function (match) {
9249
+ message = prefix + template.replace(/\{\d+\}/g, function(match) {
9250
9250
  var index = +match.slice(1, -1), arg;
9251
9251
 
9252
9252
  if (index + 2 < templateArgs.length) {
@@ -9263,7 +9263,7 @@ function minErr(module, ErrorConstructor) {
9263
9263
  return match;
9264
9264
  });
9265
9265
 
9266
- message = message + '\nhttp://errors.angularjs.org/1.3.0/' +
9266
+ message = message + '\nhttp://errors.angularjs.org/1.3.1/' +
9267
9267
  (module ? module + '/' : '') + code;
9268
9268
  for (i = 2; i < arguments.length; i++) {
9269
9269
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -9322,12 +9322,11 @@ function minErr(module, ErrorConstructor) {
9322
9322
  isBoolean: true,
9323
9323
  isPromiseLike: true,
9324
9324
  trim: true,
9325
+ escapeForRegexp: true,
9325
9326
  isElement: true,
9326
9327
  makeMap: true,
9327
- size: true,
9328
9328
  includes: true,
9329
9329
  arrayRemove: true,
9330
- isLeafNode: true,
9331
9330
  copy: true,
9332
9331
  shallowCopy: true,
9333
9332
  equals: true,
@@ -9397,7 +9396,7 @@ var VALIDITY_STATE_PROPERTY = 'validity';
9397
9396
  * @param {string} string String to be converted to lowercase.
9398
9397
  * @returns {string} Lowercased string.
9399
9398
  */
9400
- var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
9399
+ var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
9401
9400
  var hasOwnProperty = Object.prototype.hasOwnProperty;
9402
9401
 
9403
9402
  /**
@@ -9410,7 +9409,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty;
9410
9409
  * @param {string} string String to be converted to uppercase.
9411
9410
  * @returns {string} Uppercased string.
9412
9411
  */
9413
- var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
9412
+ var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
9414
9413
 
9415
9414
 
9416
9415
  var manualLowercase = function(s) {
@@ -9493,6 +9492,11 @@ function isArrayLike(obj) {
9493
9492
  *
9494
9493
  * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
9495
9494
  * using the `hasOwnProperty` method.
9495
+ *
9496
+ * Unlike ES262's
9497
+ * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
9498
+ * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
9499
+ * return the value provided.
9496
9500
  *
9497
9501
  ```js
9498
9502
  var values = {name: 'misko', gender: 'male'};
@@ -9541,18 +9545,12 @@ function forEach(obj, iterator, context) {
9541
9545
  }
9542
9546
 
9543
9547
  function sortedKeys(obj) {
9544
- var keys = [];
9545
- for (var key in obj) {
9546
- if (obj.hasOwnProperty(key)) {
9547
- keys.push(key);
9548
- }
9549
- }
9550
- return keys.sort();
9548
+ return Object.keys(obj).sort();
9551
9549
  }
9552
9550
 
9553
9551
  function forEachSorted(obj, iterator, context) {
9554
9552
  var keys = sortedKeys(obj);
9555
- for ( var i = 0; i < keys.length; i++) {
9553
+ for (var i = 0; i < keys.length; i++) {
9556
9554
  iterator.call(context, obj[keys[i]], keys[i]);
9557
9555
  }
9558
9556
  return keys;
@@ -9607,6 +9605,7 @@ function setHashKey(obj, h) {
9607
9605
  * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
9608
9606
  * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
9609
9607
  * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
9608
+ * Note: Keep in mind that `angular.extend` does not support recursive merge (deep copy).
9610
9609
  *
9611
9610
  * @param {Object} dst Destination object.
9612
9611
  * @param {...Object} src Source object(s).
@@ -9693,7 +9692,7 @@ function valueFn(value) {return function() {return value;};}
9693
9692
  * @param {*} value Reference to check.
9694
9693
  * @returns {boolean} True if `value` is undefined.
9695
9694
  */
9696
- function isUndefined(value){return typeof value === 'undefined';}
9695
+ function isUndefined(value) {return typeof value === 'undefined';}
9697
9696
 
9698
9697
 
9699
9698
  /**
@@ -9708,7 +9707,7 @@ function isUndefined(value){return typeof value === 'undefined';}
9708
9707
  * @param {*} value Reference to check.
9709
9708
  * @returns {boolean} True if `value` is defined.
9710
9709
  */
9711
- function isDefined(value){return typeof value !== 'undefined';}
9710
+ function isDefined(value) {return typeof value !== 'undefined';}
9712
9711
 
9713
9712
 
9714
9713
  /**
@@ -9724,7 +9723,7 @@ function isDefined(value){return typeof value !== 'undefined';}
9724
9723
  * @param {*} value Reference to check.
9725
9724
  * @returns {boolean} True if `value` is an `Object` but not `null`.
9726
9725
  */
9727
- function isObject(value){
9726
+ function isObject(value) {
9728
9727
  // http://jsperf.com/isobject4
9729
9728
  return value !== null && typeof value === 'object';
9730
9729
  }
@@ -9742,7 +9741,7 @@ function isObject(value){
9742
9741
  * @param {*} value Reference to check.
9743
9742
  * @returns {boolean} True if `value` is a `String`.
9744
9743
  */
9745
- function isString(value){return typeof value === 'string';}
9744
+ function isString(value) {return typeof value === 'string';}
9746
9745
 
9747
9746
 
9748
9747
  /**
@@ -9757,7 +9756,7 @@ function isString(value){return typeof value === 'string';}
9757
9756
  * @param {*} value Reference to check.
9758
9757
  * @returns {boolean} True if `value` is a `Number`.
9759
9758
  */
9760
- function isNumber(value){return typeof value === 'number';}
9759
+ function isNumber(value) {return typeof value === 'number';}
9761
9760
 
9762
9761
 
9763
9762
  /**
@@ -9803,7 +9802,7 @@ var isArray = Array.isArray;
9803
9802
  * @param {*} value Reference to check.
9804
9803
  * @returns {boolean} True if `value` is a `Function`.
9805
9804
  */
9806
- function isFunction(value){return typeof value === 'function';}
9805
+ function isFunction(value) {return typeof value === 'function';}
9807
9806
 
9808
9807
 
9809
9808
  /**
@@ -9859,6 +9858,14 @@ var trim = function(value) {
9859
9858
  return isString(value) ? value.trim() : value;
9860
9859
  };
9861
9860
 
9861
+ // Copied from:
9862
+ // http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
9863
+ // Prereq: s is a string.
9864
+ var escapeForRegexp = function(s) {
9865
+ return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
9866
+ replace(/\x08/g, '\\x08');
9867
+ };
9868
+
9862
9869
 
9863
9870
  /**
9864
9871
  * @ngdoc function
@@ -9884,7 +9891,7 @@ function isElement(node) {
9884
9891
  */
9885
9892
  function makeMap(str) {
9886
9893
  var obj = {}, items = str.split(","), i;
9887
- for ( i = 0; i < items.length; i++ )
9894
+ for (i = 0; i < items.length; i++)
9888
9895
  obj[ items[i] ] = true;
9889
9896
  return obj;
9890
9897
  }
@@ -9894,34 +9901,6 @@ function nodeName_(element) {
9894
9901
  return lowercase(element.nodeName || element[0].nodeName);
9895
9902
  }
9896
9903
 
9897
-
9898
- /**
9899
- * @description
9900
- * Determines the number of elements in an array, the number of properties an object has, or
9901
- * the length of a string.
9902
- *
9903
- * Note: This function is used to augment the Object type in Angular expressions. See
9904
- * {@link angular.Object} for more information about Angular arrays.
9905
- *
9906
- * @param {Object|Array|string} obj Object, array, or string to inspect.
9907
- * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object
9908
- * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array.
9909
- */
9910
- function size(obj, ownPropsOnly) {
9911
- var count = 0, key;
9912
-
9913
- if (isArray(obj) || isString(obj)) {
9914
- return obj.length;
9915
- } else if (isObject(obj)) {
9916
- for (key in obj)
9917
- if (!ownPropsOnly || obj.hasOwnProperty(key))
9918
- count++;
9919
- }
9920
-
9921
- return count;
9922
- }
9923
-
9924
-
9925
9904
  function includes(array, obj) {
9926
9905
  return Array.prototype.indexOf.call(array, obj) != -1;
9927
9906
  }
@@ -9933,18 +9912,6 @@ function arrayRemove(array, value) {
9933
9912
  return value;
9934
9913
  }
9935
9914
 
9936
- function isLeafNode (node) {
9937
- if (node) {
9938
- switch (nodeName_(node)) {
9939
- case "option":
9940
- case "pre":
9941
- case "title":
9942
- return true;
9943
- }
9944
- }
9945
- return false;
9946
- }
9947
-
9948
9915
  /**
9949
9916
  * @ngdoc function
9950
9917
  * @name angular.copy
@@ -10042,7 +10009,7 @@ function copy(source, destination, stackSource, stackDest) {
10042
10009
  var result;
10043
10010
  if (isArray(source)) {
10044
10011
  destination.length = 0;
10045
- for ( var i = 0; i < source.length; i++) {
10012
+ for (var i = 0; i < source.length; i++) {
10046
10013
  result = copy(source[i], null, stackSource, stackDest);
10047
10014
  if (isObject(source[i])) {
10048
10015
  stackSource.push(source[i]);
@@ -10059,8 +10026,8 @@ function copy(source, destination, stackSource, stackDest) {
10059
10026
  delete destination[key];
10060
10027
  });
10061
10028
  }
10062
- for ( var key in source) {
10063
- if(source.hasOwnProperty(key)) {
10029
+ for (var key in source) {
10030
+ if (source.hasOwnProperty(key)) {
10064
10031
  result = copy(source[key], null, stackSource, stackDest);
10065
10032
  if (isObject(source[key])) {
10066
10033
  stackSource.push(source[key]);
@@ -10141,7 +10108,7 @@ function equals(o1, o2) {
10141
10108
  if (isArray(o1)) {
10142
10109
  if (!isArray(o2)) return false;
10143
10110
  if ((length = o1.length) == o2.length) {
10144
- for(key=0; key<length; key++) {
10111
+ for (key=0; key<length; key++) {
10145
10112
  if (!equals(o1[key], o2[key])) return false;
10146
10113
  }
10147
10114
  return true;
@@ -10154,12 +10121,12 @@ function equals(o1, o2) {
10154
10121
  } else {
10155
10122
  if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
10156
10123
  keySet = {};
10157
- for(key in o1) {
10124
+ for (key in o1) {
10158
10125
  if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
10159
10126
  if (!equals(o1[key], o2[key])) return false;
10160
10127
  keySet[key] = true;
10161
10128
  }
10162
- for(key in o2) {
10129
+ for (key in o2) {
10163
10130
  if (!keySet.hasOwnProperty(key) &&
10164
10131
  key.charAt(0) !== '$' &&
10165
10132
  o2[key] !== undefined &&
@@ -10307,14 +10274,14 @@ function startingTag(element) {
10307
10274
  // turns out IE does not let you set .html() on elements which
10308
10275
  // are not allowed to have children. So we just ignore it.
10309
10276
  element.empty();
10310
- } catch(e) {}
10277
+ } catch (e) {}
10311
10278
  var elemHtml = jqLite('<div>').append(element).html();
10312
10279
  try {
10313
10280
  return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
10314
10281
  elemHtml.
10315
10282
  match(/^(<[^>]+>)/)[1].
10316
10283
  replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
10317
- } catch(e) {
10284
+ } catch (e) {
10318
10285
  return lowercase(elemHtml);
10319
10286
  }
10320
10287
 
@@ -10334,7 +10301,7 @@ function startingTag(element) {
10334
10301
  function tryDecodeURIComponent(value) {
10335
10302
  try {
10336
10303
  return decodeURIComponent(value);
10337
- } catch(e) {
10304
+ } catch (e) {
10338
10305
  // Ignore any invalid uri component
10339
10306
  }
10340
10307
  }
@@ -10347,14 +10314,14 @@ function tryDecodeURIComponent(value) {
10347
10314
  function parseKeyValue(/**string*/keyValue) {
10348
10315
  var obj = {}, key_value, key;
10349
10316
  forEach((keyValue || "").split('&'), function(keyValue) {
10350
- if ( keyValue ) {
10317
+ if (keyValue) {
10351
10318
  key_value = keyValue.replace(/\+/g,'%20').split('=');
10352
10319
  key = tryDecodeURIComponent(key_value[0]);
10353
- if ( isDefined(key) ) {
10320
+ if (isDefined(key)) {
10354
10321
  var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
10355
10322
  if (!hasOwnProperty.call(obj, key)) {
10356
10323
  obj[key] = val;
10357
- } else if(isArray(obj[key])) {
10324
+ } else if (isArray(obj[key])) {
10358
10325
  obj[key].push(val);
10359
10326
  } else {
10360
10327
  obj[key] = [obj[key],val];
@@ -11191,7 +11158,7 @@ function setupModuleLoader(window) {
11191
11158
  config(configFn);
11192
11159
  }
11193
11160
 
11194
- return moduleInstance;
11161
+ return moduleInstance;
11195
11162
 
11196
11163
  /**
11197
11164
  * @param {string} provider
@@ -11314,15 +11281,15 @@ function setupModuleLoader(window) {
11314
11281
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11315
11282
  */
11316
11283
  var version = {
11317
- full: '1.3.0', // all of these placeholder strings will be replaced by grunt's
11284
+ full: '1.3.1', // all of these placeholder strings will be replaced by grunt's
11318
11285
  major: 1, // package task
11319
11286
  minor: 3,
11320
- dot: 0,
11321
- codeName: 'superluminal-nudge'
11287
+ dot: 1,
11288
+ codeName: 'spectral-lobster'
11322
11289
  };
11323
11290
 
11324
11291
 
11325
- function publishExternalAPI(angular){
11292
+ function publishExternalAPI(angular) {
11326
11293
  extend(angular, {
11327
11294
  'bootstrap': bootstrap,
11328
11295
  'copy': copy,
@@ -11448,7 +11415,7 @@ function publishExternalAPI(angular){
11448
11415
  $timeout: $TimeoutProvider,
11449
11416
  $window: $WindowProvider,
11450
11417
  $$rAF: $$RAFProvider,
11451
- $$asyncCallback : $$AsyncCallbackProvider
11418
+ $$asyncCallback: $$AsyncCallbackProvider
11452
11419
  });
11453
11420
  }
11454
11421
  ]);
@@ -11498,7 +11465,7 @@ function publishExternalAPI(angular){
11498
11465
  * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
11499
11466
  * - [`clone()`](http://api.jquery.com/clone/)
11500
11467
  * - [`contents()`](http://api.jquery.com/contents/)
11501
- * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyles()`
11468
+ * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`
11502
11469
  * - [`data()`](http://api.jquery.com/data/)
11503
11470
  * - [`detach()`](http://api.jquery.com/detach/)
11504
11471
  * - [`empty()`](http://api.jquery.com/empty/)
@@ -11576,7 +11543,7 @@ function jqNextId() { return ++jqId; }
11576
11543
 
11577
11544
  var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
11578
11545
  var MOZ_HACK_REGEXP = /^moz([A-Z])/;
11579
- var MOUSE_EVENT_MAP= { mouseleave : "mouseout", mouseenter : "mouseover"};
11546
+ var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"};
11580
11547
  var jqLiteMinErr = minErr('jqLite');
11581
11548
 
11582
11549
  /**
@@ -11705,7 +11672,7 @@ function jqLiteClone(element) {
11705
11672
  return element.cloneNode(true);
11706
11673
  }
11707
11674
 
11708
- function jqLiteDealoc(element, onlyDescendants){
11675
+ function jqLiteDealoc(element, onlyDescendants) {
11709
11676
  if (!onlyDescendants) jqLiteRemoveData(element);
11710
11677
 
11711
11678
  if (element.querySelectorAll) {
@@ -11812,7 +11779,7 @@ function jqLiteData(element, key, value) {
11812
11779
  function jqLiteHasClass(element, selector) {
11813
11780
  if (!element.getAttribute) return false;
11814
11781
  return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
11815
- indexOf( " " + selector + " " ) > -1);
11782
+ indexOf(" " + selector + " ") > -1);
11816
11783
  }
11817
11784
 
11818
11785
  function jqLiteRemoveClass(element, cssClasses) {
@@ -11871,13 +11838,13 @@ function jqLiteAddNodes(root, elements) {
11871
11838
 
11872
11839
 
11873
11840
  function jqLiteController(element, name) {
11874
- return jqLiteInheritedData(element, '$' + (name || 'ngController' ) + 'Controller');
11841
+ return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
11875
11842
  }
11876
11843
 
11877
11844
  function jqLiteInheritedData(element, name, value) {
11878
11845
  // if element is the document object work with the html element instead
11879
11846
  // this makes $(document).scope() possible
11880
- if(element.nodeType == NODE_TYPE_DOCUMENT) {
11847
+ if (element.nodeType == NODE_TYPE_DOCUMENT) {
11881
11848
  element = element.documentElement;
11882
11849
  }
11883
11850
  var names = isArray(name) ? name : [name];
@@ -11935,7 +11902,7 @@ var JQLitePrototype = JQLite.prototype = {
11935
11902
  }
11936
11903
 
11937
11904
  // check if document is already loaded
11938
- if (document.readyState === 'complete'){
11905
+ if (document.readyState === 'complete') {
11939
11906
  setTimeout(trigger);
11940
11907
  } else {
11941
11908
  this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
@@ -11943,12 +11910,11 @@ var JQLitePrototype = JQLite.prototype = {
11943
11910
  // jshint -W064
11944
11911
  JQLite(window).on('load', trigger); // fallback to window.onload for others
11945
11912
  // jshint +W064
11946
- this.on('DOMContentLoaded', trigger);
11947
11913
  }
11948
11914
  },
11949
11915
  toString: function() {
11950
11916
  var value = [];
11951
- forEach(this, function(e){ value.push('' + e);});
11917
+ forEach(this, function(e) { value.push('' + e);});
11952
11918
  return '[' + value.join(', ') + ']';
11953
11919
  },
11954
11920
 
@@ -11976,11 +11942,11 @@ forEach('input,select,option,textarea,button,form,details'.split(','), function(
11976
11942
  BOOLEAN_ELEMENTS[value] = true;
11977
11943
  });
11978
11944
  var ALIASED_ATTR = {
11979
- 'ngMinlength' : 'minlength',
11980
- 'ngMaxlength' : 'maxlength',
11981
- 'ngMin' : 'min',
11982
- 'ngMax' : 'max',
11983
- 'ngPattern' : 'pattern'
11945
+ 'ngMinlength': 'minlength',
11946
+ 'ngMaxlength': 'maxlength',
11947
+ 'ngMin': 'min',
11948
+ 'ngMax': 'max',
11949
+ 'ngPattern': 'pattern'
11984
11950
  };
11985
11951
 
11986
11952
  function getBooleanAttrName(element, name) {
@@ -12039,7 +12005,7 @@ forEach({
12039
12005
  }
12040
12006
  },
12041
12007
 
12042
- attr: function(element, name, value){
12008
+ attr: function(element, name, value) {
12043
12009
  var lowercasedName = lowercase(name);
12044
12010
  if (BOOLEAN_ATTR[lowercasedName]) {
12045
12011
  if (isDefined(value)) {
@@ -12092,7 +12058,7 @@ forEach({
12092
12058
  if (isUndefined(value)) {
12093
12059
  if (element.multiple && nodeName_(element) === 'select') {
12094
12060
  var result = [];
12095
- forEach(element.options, function (option) {
12061
+ forEach(element.options, function(option) {
12096
12062
  if (option.selected) {
12097
12063
  result.push(option.value || option.text);
12098
12064
  }
@@ -12113,7 +12079,7 @@ forEach({
12113
12079
  },
12114
12080
 
12115
12081
  empty: jqLiteEmpty
12116
- }, function(fn, name){
12082
+ }, function(fn, name) {
12117
12083
  /**
12118
12084
  * Properties: writes return selection, reads return first value
12119
12085
  */
@@ -12165,7 +12131,7 @@ forEach({
12165
12131
  });
12166
12132
 
12167
12133
  function createEventHandler(element, events) {
12168
- var eventHandler = function (event, type) {
12134
+ var eventHandler = function(event, type) {
12169
12135
  // jQuery specific api
12170
12136
  event.isDefaultPrevented = function() {
12171
12137
  return event.defaultPrevented;
@@ -12221,7 +12187,7 @@ function createEventHandler(element, events) {
12221
12187
  forEach({
12222
12188
  removeData: jqLiteRemoveData,
12223
12189
 
12224
- on: function jqLiteOn(element, type, fn, unsupported){
12190
+ on: function jqLiteOn(element, type, fn, unsupported) {
12225
12191
  if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
12226
12192
 
12227
12193
  // Do not add event handlers to non-elements because they will not be cleaned up.
@@ -12257,7 +12223,7 @@ forEach({
12257
12223
  var target = this, related = event.relatedTarget;
12258
12224
  // For mousenter/leave call the handler if related is outside the target.
12259
12225
  // NB: No relatedTarget if the mouse left/entered the browser window
12260
- if ( !related || (related !== target && !target.contains(related)) ){
12226
+ if (!related || (related !== target && !target.contains(related))) {
12261
12227
  handle(event, type);
12262
12228
  }
12263
12229
  });
@@ -12291,7 +12257,7 @@ forEach({
12291
12257
  replaceWith: function(element, replaceNode) {
12292
12258
  var index, parent = element.parentNode;
12293
12259
  jqLiteDealoc(element);
12294
- forEach(new JQLite(replaceNode), function(node){
12260
+ forEach(new JQLite(replaceNode), function(node) {
12295
12261
  if (index) {
12296
12262
  parent.insertBefore(node, index.nextSibling);
12297
12263
  } else {
@@ -12303,7 +12269,7 @@ forEach({
12303
12269
 
12304
12270
  children: function(element) {
12305
12271
  var children = [];
12306
- forEach(element.childNodes, function(element){
12272
+ forEach(element.childNodes, function(element) {
12307
12273
  if (element.nodeType === NODE_TYPE_ELEMENT)
12308
12274
  children.push(element);
12309
12275
  });
@@ -12329,7 +12295,7 @@ forEach({
12329
12295
  prepend: function(element, node) {
12330
12296
  if (element.nodeType === NODE_TYPE_ELEMENT) {
12331
12297
  var index = element.firstChild;
12332
- forEach(new JQLite(node), function(child){
12298
+ forEach(new JQLite(node), function(child) {
12333
12299
  element.insertBefore(child, index);
12334
12300
  });
12335
12301
  }
@@ -12366,7 +12332,7 @@ forEach({
12366
12332
 
12367
12333
  toggleClass: function(element, selector, condition) {
12368
12334
  if (selector) {
12369
- forEach(selector.split(' '), function(className){
12335
+ forEach(selector.split(' '), function(className) {
12370
12336
  var classCondition = condition;
12371
12337
  if (isUndefined(classCondition)) {
12372
12338
  classCondition = !jqLiteHasClass(element, className);
@@ -12431,14 +12397,14 @@ forEach({
12431
12397
  });
12432
12398
  }
12433
12399
  }
12434
- }, function(fn, name){
12400
+ }, function(fn, name) {
12435
12401
  /**
12436
12402
  * chaining functions
12437
12403
  */
12438
12404
  JQLite.prototype[name] = function(arg1, arg2, arg3) {
12439
12405
  var value;
12440
12406
 
12441
- for(var i = 0, ii = this.length; i < ii; i++) {
12407
+ for (var i = 0, ii = this.length; i < ii; i++) {
12442
12408
  if (isUndefined(value)) {
12443
12409
  value = fn(this[i], arg1, arg2, arg3);
12444
12410
  if (isDefined(value)) {
@@ -13235,7 +13201,7 @@ function createInjector(modulesToLoad, strictDi) {
13235
13201
  ////////////////////////////////////
13236
13202
  // Module Loading
13237
13203
  ////////////////////////////////////
13238
- function loadModules(modulesToLoad){
13204
+ function loadModules(modulesToLoad) {
13239
13205
  var runBlocks = [], moduleFn;
13240
13206
  forEach(modulesToLoad, function(module) {
13241
13207
  if (loadedModules.get(module)) return;
@@ -13243,7 +13209,7 @@ function createInjector(modulesToLoad, strictDi) {
13243
13209
 
13244
13210
  function runInvokeQueue(queue) {
13245
13211
  var i, ii;
13246
- for(i = 0, ii = queue.length; i < ii; i++) {
13212
+ for (i = 0, ii = queue.length; i < ii; i++) {
13247
13213
  var invokeArgs = queue[i],
13248
13214
  provider = providerInjector.get(invokeArgs[0]);
13249
13215
 
@@ -13323,7 +13289,7 @@ function createInjector(modulesToLoad, strictDi) {
13323
13289
  length, i,
13324
13290
  key;
13325
13291
 
13326
- for(i = 0, length = $inject.length; i < length; i++) {
13292
+ for (i = 0, length = $inject.length; i < length; i++) {
13327
13293
  key = $inject[i];
13328
13294
  if (typeof key !== 'string') {
13329
13295
  throw $injectorMinErr('itkn',
@@ -13539,7 +13505,6 @@ function $AnchorScrollProvider() {
13539
13505
  */
13540
13506
  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
13541
13507
  var document = $window.document;
13542
- var scrollScheduled = false;
13543
13508
 
13544
13509
  // Helper function to get first anchor from a NodeList
13545
13510
  // (using `Array#some()` instead of `angular#forEach()` since it's more performant
@@ -13713,7 +13678,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13713
13678
  * @return {RegExp} The current CSS className expression value. If null then there is no expression value
13714
13679
  */
13715
13680
  this.classNameFilter = function(expression) {
13716
- if(arguments.length === 1) {
13681
+ if (arguments.length === 1) {
13717
13682
  this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
13718
13683
  }
13719
13684
  return this.$$classNameFilter;
@@ -13808,7 +13773,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13808
13773
  * page}.
13809
13774
  */
13810
13775
  return {
13811
- animate : function(element, from, to) {
13776
+ animate: function(element, from, to) {
13812
13777
  applyStyles(element, { from: from, to: to });
13813
13778
  return asyncPromise();
13814
13779
  },
@@ -13829,7 +13794,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13829
13794
  * @param {object=} options an optional collection of styles that will be applied to the element.
13830
13795
  * @return {Promise} the animation callback promise
13831
13796
  */
13832
- enter : function(element, parent, after, options) {
13797
+ enter: function(element, parent, after, options) {
13833
13798
  applyStyles(element, options);
13834
13799
  after ? after.after(element)
13835
13800
  : parent.prepend(element);
@@ -13847,7 +13812,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13847
13812
  * @param {object=} options an optional collection of options that will be applied to the element.
13848
13813
  * @return {Promise} the animation callback promise
13849
13814
  */
13850
- leave : function(element, options) {
13815
+ leave: function(element, options) {
13851
13816
  element.remove();
13852
13817
  return asyncPromise();
13853
13818
  },
@@ -13870,7 +13835,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13870
13835
  * @param {object=} options an optional collection of options that will be applied to the element.
13871
13836
  * @return {Promise} the animation callback promise
13872
13837
  */
13873
- move : function(element, parent, after, options) {
13838
+ move: function(element, parent, after, options) {
13874
13839
  // Do not remove element before insert. Removing will cause data associated with the
13875
13840
  // element to be dropped. Insert will implicitly do the remove.
13876
13841
  return this.enter(element, parent, after, options);
@@ -13889,16 +13854,16 @@ var $AnimateProvider = ['$provide', function($provide) {
13889
13854
  * @param {object=} options an optional collection of options that will be applied to the element.
13890
13855
  * @return {Promise} the animation callback promise
13891
13856
  */
13892
- addClass : function(element, className, options) {
13857
+ addClass: function(element, className, options) {
13893
13858
  return this.setClass(element, className, [], options);
13894
13859
  },
13895
13860
 
13896
- $$addClassImmediately : function(element, className, options) {
13861
+ $$addClassImmediately: function(element, className, options) {
13897
13862
  element = jqLite(element);
13898
13863
  className = !isString(className)
13899
13864
  ? (isArray(className) ? className.join(' ') : '')
13900
13865
  : className;
13901
- forEach(element, function (element) {
13866
+ forEach(element, function(element) {
13902
13867
  jqLiteAddClass(element, className);
13903
13868
  });
13904
13869
  applyStyles(element, options);
@@ -13918,16 +13883,16 @@ var $AnimateProvider = ['$provide', function($provide) {
13918
13883
  * @param {object=} options an optional collection of options that will be applied to the element.
13919
13884
  * @return {Promise} the animation callback promise
13920
13885
  */
13921
- removeClass : function(element, className, options) {
13886
+ removeClass: function(element, className, options) {
13922
13887
  return this.setClass(element, [], className, options);
13923
13888
  },
13924
13889
 
13925
- $$removeClassImmediately : function(element, className, options) {
13890
+ $$removeClassImmediately: function(element, className, options) {
13926
13891
  element = jqLite(element);
13927
13892
  className = !isString(className)
13928
13893
  ? (isArray(className) ? className.join(' ') : '')
13929
13894
  : className;
13930
- forEach(element, function (element) {
13895
+ forEach(element, function(element) {
13931
13896
  jqLiteRemoveClass(element, className);
13932
13897
  });
13933
13898
  applyStyles(element, options);
@@ -13948,7 +13913,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13948
13913
  * @param {object=} options an optional collection of options that will be applied to the element.
13949
13914
  * @return {Promise} the animation callback promise
13950
13915
  */
13951
- setClass : function(element, add, remove, options) {
13916
+ setClass: function(element, add, remove, options) {
13952
13917
  var self = this;
13953
13918
  var STORAGE_KEY = '$$animateClasses';
13954
13919
  var createdCache = false;
@@ -13958,7 +13923,7 @@ var $AnimateProvider = ['$provide', function($provide) {
13958
13923
  if (!cache) {
13959
13924
  cache = {
13960
13925
  classes: {},
13961
- options : options
13926
+ options: options
13962
13927
  };
13963
13928
  createdCache = true;
13964
13929
  } else if (options && cache.options) {
@@ -13995,20 +13960,20 @@ var $AnimateProvider = ['$provide', function($provide) {
13995
13960
  return cache.promise;
13996
13961
  },
13997
13962
 
13998
- $$setClassImmediately : function(element, add, remove, options) {
13963
+ $$setClassImmediately: function(element, add, remove, options) {
13999
13964
  add && this.$$addClassImmediately(element, add);
14000
13965
  remove && this.$$removeClassImmediately(element, remove);
14001
13966
  applyStyles(element, options);
14002
13967
  return asyncPromise();
14003
13968
  },
14004
13969
 
14005
- enabled : noop,
14006
- cancel : noop
13970
+ enabled: noop,
13971
+ cancel: noop
14007
13972
  };
14008
13973
  }];
14009
13974
  }];
14010
13975
 
14011
- function $$AsyncCallbackProvider(){
13976
+ function $$AsyncCallbackProvider() {
14012
13977
  this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) {
14013
13978
  return $$rAF.supported
14014
13979
  ? function(fn) { return $$rAF(fn); }
@@ -14070,7 +14035,7 @@ function Browser(window, document, $log, $sniffer) {
14070
14035
  } finally {
14071
14036
  outstandingRequestCount--;
14072
14037
  if (outstandingRequestCount === 0) {
14073
- while(outstandingRequestCallbacks.length) {
14038
+ while (outstandingRequestCallbacks.length) {
14074
14039
  try {
14075
14040
  outstandingRequestCallbacks.pop()();
14076
14041
  } catch (e) {
@@ -14091,7 +14056,7 @@ function Browser(window, document, $log, $sniffer) {
14091
14056
  // force browser to execute all pollFns - this is needed so that cookies and other pollers fire
14092
14057
  // at some deterministic time in respect to the test runner's actions. Leaving things up to the
14093
14058
  // regular poller would result in flaky tests.
14094
- forEach(pollFns, function(pollFn){ pollFn(); });
14059
+ forEach(pollFns, function(pollFn) { pollFn(); });
14095
14060
 
14096
14061
  if (outstandingRequestCount === 0) {
14097
14062
  callback();
@@ -14133,7 +14098,7 @@ function Browser(window, document, $log, $sniffer) {
14133
14098
  */
14134
14099
  function startPoller(interval, setTimeout) {
14135
14100
  (function check() {
14136
- forEach(pollFns, function(pollFn){ pollFn(); });
14101
+ forEach(pollFns, function(pollFn) { pollFn(); });
14137
14102
  pollTimeout = setTimeout(check, interval);
14138
14103
  })();
14139
14104
  }
@@ -14468,9 +14433,9 @@ function Browser(window, document, $log, $sniffer) {
14468
14433
 
14469
14434
  }
14470
14435
 
14471
- function $BrowserProvider(){
14436
+ function $BrowserProvider() {
14472
14437
  this.$get = ['$window', '$log', '$sniffer', '$document',
14473
- function( $window, $log, $sniffer, $document){
14438
+ function($window, $log, $sniffer, $document) {
14474
14439
  return new Browser($window, $document, $log, $sniffer);
14475
14440
  }];
14476
14441
  }
@@ -14844,7 +14809,8 @@ function $CacheFactoryProvider() {
14844
14809
  * ```
14845
14810
  *
14846
14811
  * **Note:** the `script` tag containing the template does not need to be included in the `head` of
14847
- * the document, but it must be below the `ng-app` definition.
14812
+ * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
14813
+ * element with ng-app attribute), otherwise the template will be ignored.
14848
14814
  *
14849
14815
  * Adding via the $templateCache service:
14850
14816
  *
@@ -15038,7 +15004,9 @@ function $TemplateCacheProvider() {
15038
15004
  * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
15039
15005
  * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent
15040
15006
  * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You
15041
- * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional.
15007
+ * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. If
15008
+ * you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use
15009
+ * `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional).
15042
15010
  *
15043
15011
  * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
15044
15012
  * If no `attr` name is specified then the attribute name is assumed to be the same as the
@@ -15554,8 +15522,8 @@ $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
15554
15522
  function $CompileProvider($provide, $$sanitizeUriProvider) {
15555
15523
  var hasDirectives = {},
15556
15524
  Suffix = 'Directive',
15557
- COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,
15558
- CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/,
15525
+ COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\w\-]+)\s+(.*)$/,
15526
+ CLASS_DIRECTIVE_REGEXP = /(([\w\-]+)(?:\:([^;]+))?;?)/,
15559
15527
  ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
15560
15528
  REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
15561
15529
 
@@ -15565,7 +15533,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15565
15533
  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
15566
15534
 
15567
15535
  function parseIsolateBindings(scope, directiveName) {
15568
- var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
15536
+ var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/;
15569
15537
 
15570
15538
  var bindings = {};
15571
15539
 
@@ -15580,9 +15548,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15580
15548
  }
15581
15549
 
15582
15550
  bindings[scopeName] = {
15583
- attrName: match[3] || scopeName,
15584
- mode: match[1],
15585
- optional: match[2] === '?'
15551
+ mode: match[1][0],
15552
+ collection: match[2] === '*',
15553
+ optional: match[3] === '?',
15554
+ attrName: match[4] || scopeName
15586
15555
  };
15587
15556
  });
15588
15557
 
@@ -15728,7 +15697,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15728
15697
  */
15729
15698
  var debugInfoEnabled = true;
15730
15699
  this.debugInfoEnabled = function(enabled) {
15731
- if(isDefined(enabled)) {
15700
+ if (isDefined(enabled)) {
15732
15701
  debugInfoEnabled = enabled;
15733
15702
  return this;
15734
15703
  }
@@ -15772,8 +15741,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15772
15741
  *
15773
15742
  * @param {string} classVal The className value that will be added to the element
15774
15743
  */
15775
- $addClass : function(classVal) {
15776
- if(classVal && classVal.length > 0) {
15744
+ $addClass: function(classVal) {
15745
+ if (classVal && classVal.length > 0) {
15777
15746
  $animate.addClass(this.$$element, classVal);
15778
15747
  }
15779
15748
  },
@@ -15789,8 +15758,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15789
15758
  *
15790
15759
  * @param {string} classVal The className value that will be removed from the element
15791
15760
  */
15792
- $removeClass : function(classVal) {
15793
- if(classVal && classVal.length > 0) {
15761
+ $removeClass: function(classVal) {
15762
+ if (classVal && classVal.length > 0) {
15794
15763
  $animate.removeClass(this.$$element, classVal);
15795
15764
  }
15796
15765
  },
@@ -15807,7 +15776,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15807
15776
  * @param {string} newClasses The current CSS className value
15808
15777
  * @param {string} oldClasses The former CSS className value
15809
15778
  */
15810
- $updateClass : function(newClasses, oldClasses) {
15779
+ $updateClass: function(newClasses, oldClasses) {
15811
15780
  var toAdd = tokenDifference(newClasses, oldClasses);
15812
15781
  if (toAdd && toAdd.length) {
15813
15782
  $animate.addClass(this.$$element, toAdd);
@@ -15837,13 +15806,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15837
15806
  booleanKey = getBooleanAttrName(node, key),
15838
15807
  aliasedKey = getAliasedAttrName(node, key),
15839
15808
  observer = key,
15840
- normalizedVal,
15841
15809
  nodeName;
15842
15810
 
15843
15811
  if (booleanKey) {
15844
15812
  this.$$element.prop(key, value);
15845
15813
  attrName = booleanKey;
15846
- } else if(aliasedKey) {
15814
+ } else if (aliasedKey) {
15847
15815
  this[aliasedKey] = value;
15848
15816
  observer = aliasedKey;
15849
15817
  }
@@ -15884,9 +15852,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15884
15852
  for (var i=0; i<nbrUrisWith2parts; i++) {
15885
15853
  var innerIdx = i*2;
15886
15854
  // sanitize the uri
15887
- result += $$sanitizeUri(trim( rawUris[innerIdx]), true);
15855
+ result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
15888
15856
  // add the descriptor
15889
- result += ( " " + trim(rawUris[innerIdx+1]));
15857
+ result += (" " + trim(rawUris[innerIdx+1]));
15890
15858
  }
15891
15859
 
15892
15860
  // split the last item into uri and descriptor
@@ -15896,7 +15864,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15896
15864
  result += $$sanitizeUri(trim(lastTuple[0]), true);
15897
15865
 
15898
15866
  // and add the last descriptor if any
15899
- if( lastTuple.length === 2) {
15867
+ if (lastTuple.length === 2) {
15900
15868
  result += (" " + trim(lastTuple[1]));
15901
15869
  }
15902
15870
  this[key] = value = result;
@@ -15947,7 +15915,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15947
15915
 
15948
15916
  listeners.push(fn);
15949
15917
  $rootScope.$evalAsync(function() {
15950
- if (!listeners.$$inter) {
15918
+ if (!listeners.$$inter && attrs.hasOwnProperty(key)) {
15951
15919
  // no one registered attribute interpolation function, so lets call it manually
15952
15920
  fn(attrs[key]);
15953
15921
  }
@@ -15963,7 +15931,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15963
15931
  function safeAddClass($element, className) {
15964
15932
  try {
15965
15933
  $element.addClass(className);
15966
- } catch(e) {
15934
+ } catch (e) {
15967
15935
  // ignore, since it means that we are trying to set class on
15968
15936
  // SVG element, where class name is read-only.
15969
15937
  }
@@ -16017,7 +15985,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16017
15985
  }
16018
15986
  // We can not compile top level text elements since text nodes can be merged and we will
16019
15987
  // not be able to attach scope data to them, so we will wrap them in <span>
16020
- forEach($compileNodes, function(node, index){
15988
+ forEach($compileNodes, function(node, index) {
16021
15989
  if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */ ) {
16022
15990
  $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
16023
15991
  }
@@ -16027,7 +15995,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16027
15995
  maxPriority, ignoreDirective, previousCompileContext);
16028
15996
  compile.$$addScopeClass($compileNodes);
16029
15997
  var namespace = null;
16030
- return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){
15998
+ return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement) {
16031
15999
  assertArg(scope, 'scope');
16032
16000
  if (!namespace) {
16033
16001
  namespace = detectNamespaceForChildElements(futureParentElement);
@@ -16152,7 +16120,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16152
16120
  stableNodeList = nodeList;
16153
16121
  }
16154
16122
 
16155
- for(i = 0, ii = linkFns.length; i < ii;) {
16123
+ for (i = 0, ii = linkFns.length; i < ii;) {
16156
16124
  node = stableNodeList[linkFns[i++]];
16157
16125
  nodeLinkFn = linkFns[i++];
16158
16126
  childLinkFn = linkFns[i++];
@@ -16165,7 +16133,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16165
16133
  childScope = scope;
16166
16134
  }
16167
16135
 
16168
- if ( nodeLinkFn.transcludeOnThisElement ) {
16136
+ if (nodeLinkFn.transcludeOnThisElement) {
16169
16137
  childBoundTranscludeFn = createBoundTranscludeFn(
16170
16138
  scope, nodeLinkFn.transclude, parentBoundTranscludeFn,
16171
16139
  nodeLinkFn.elementTranscludeOnThisElement);
@@ -16220,7 +16188,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16220
16188
  match,
16221
16189
  className;
16222
16190
 
16223
- switch(nodeType) {
16191
+ switch (nodeType) {
16224
16192
  case NODE_TYPE_ELEMENT: /* Element */
16225
16193
  // use the node name: <directive>
16226
16194
  addDirective(directives,
@@ -16312,7 +16280,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16312
16280
  var nodes = [];
16313
16281
  var depth = 0;
16314
16282
  if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
16315
- var startNode = node;
16316
16283
  do {
16317
16284
  if (!node) {
16318
16285
  throw $compileMinErr('uterdir',
@@ -16396,7 +16363,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16396
16363
  directiveValue;
16397
16364
 
16398
16365
  // executes all directives on the current element
16399
- for(var i = 0, ii = directives.length; i < ii; i++) {
16366
+ for (var i = 0, ii = directives.length; i < ii; i++) {
16400
16367
  directive = directives[i];
16401
16368
  var attrStart = directive.$$start;
16402
16369
  var attrEnd = directive.$$end;
@@ -16640,7 +16607,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16640
16607
  "Controller '{0}', required by directive '{1}', can't be found!",
16641
16608
  require, directiveName);
16642
16609
  }
16643
- return value;
16610
+ return value || null;
16644
16611
  } else if (isArray(require)) {
16645
16612
  value = [];
16646
16613
  forEach(require, function(require) {
@@ -16702,8 +16669,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16702
16669
  }
16703
16670
 
16704
16671
  if (newIsolateScopeDirective) {
16705
- var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
16706
-
16707
16672
  compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||
16708
16673
  templateDirective === newIsolateScopeDirective.$$originalDirective)));
16709
16674
  compile.$$addScopeClass($element, true);
@@ -16729,7 +16694,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16729
16694
  isolateBindingContext[scopeName] = value;
16730
16695
  });
16731
16696
  attrs.$$observers[attrName].$$scope = scope;
16732
- if( attrs[attrName] ) {
16697
+ if (attrs[attrName]) {
16733
16698
  // If the attribute has been provided then we trigger an interpolation to ensure
16734
16699
  // the value is there for use in the link fn
16735
16700
  isolateBindingContext[scopeName] = $interpolate(attrs[attrName])(scope);
@@ -16744,7 +16709,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16744
16709
  if (parentGet.literal) {
16745
16710
  compare = equals;
16746
16711
  } else {
16747
- compare = function(a,b) { return a === b || (a !== a && b !== b); };
16712
+ compare = function(a, b) { return a === b || (a !== a && b !== b); };
16748
16713
  }
16749
16714
  parentSet = parentGet.assign || function() {
16750
16715
  // reset the change, or we will throw this exception on every $digest
@@ -16768,7 +16733,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16768
16733
  return lastValue = parentValue;
16769
16734
  };
16770
16735
  parentValueWatch.$stateful = true;
16771
- var unwatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
16736
+ var unwatch;
16737
+ if (definition.collection) {
16738
+ unwatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
16739
+ } else {
16740
+ unwatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
16741
+ }
16772
16742
  isolateScope.$on('$destroy', unwatch);
16773
16743
  break;
16774
16744
 
@@ -16789,7 +16759,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16789
16759
  }
16790
16760
 
16791
16761
  // PRELINKING
16792
- for(i = 0, ii = preLinkFns.length; i < ii; i++) {
16762
+ for (i = 0, ii = preLinkFns.length; i < ii; i++) {
16793
16763
  linkFn = preLinkFns[i];
16794
16764
  invokeLinkFn(linkFn,
16795
16765
  linkFn.isolateScope ? isolateScope : scope,
@@ -16810,7 +16780,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16810
16780
  childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
16811
16781
 
16812
16782
  // POSTLINKING
16813
- for(i = postLinkFns.length - 1; i >= 0; i--) {
16783
+ for (i = postLinkFns.length - 1; i >= 0; i--) {
16814
16784
  linkFn = postLinkFns[i];
16815
16785
  invokeLinkFn(linkFn,
16816
16786
  linkFn.isolateScope ? isolateScope : scope,
@@ -16870,11 +16840,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16870
16840
  if (name === ignoreDirective) return null;
16871
16841
  var match = null;
16872
16842
  if (hasDirectives.hasOwnProperty(name)) {
16873
- for(var directive, directives = $injector.get(name + Suffix),
16843
+ for (var directive, directives = $injector.get(name + Suffix),
16874
16844
  i = 0, ii = directives.length; i<ii; i++) {
16875
16845
  try {
16876
16846
  directive = directives[i];
16877
- if ( (maxPriority === undefined || maxPriority > directive.priority) &&
16847
+ if ((maxPriority === undefined || maxPriority > directive.priority) &&
16878
16848
  directive.restrict.indexOf(location) != -1) {
16879
16849
  if (startAttrName) {
16880
16850
  directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
@@ -16882,7 +16852,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16882
16852
  tDirectives.push(directive);
16883
16853
  match = directive;
16884
16854
  }
16885
- } catch(e) { $exceptionHandler(e); }
16855
+ } catch (e) { $exceptionHandler(e); }
16886
16856
  }
16887
16857
  }
16888
16858
  return match;
@@ -16899,7 +16869,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16899
16869
  */
16900
16870
  function directiveIsMultiElement(name) {
16901
16871
  if (hasDirectives.hasOwnProperty(name)) {
16902
- for(var directive, directives = $injector.get(name + Suffix),
16872
+ for (var directive, directives = $injector.get(name + Suffix),
16903
16873
  i = 0, ii = directives.length; i<ii; i++) {
16904
16874
  directive = directives[i];
16905
16875
  if (directive.multiElement) {
@@ -17016,7 +16986,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17016
16986
  });
17017
16987
  afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
17018
16988
 
17019
- while(linkQueue.length) {
16989
+ while (linkQueue.length) {
17020
16990
  var scope = linkQueue.shift(),
17021
16991
  beforeTemplateLinkNode = linkQueue.shift(),
17022
16992
  linkRootElement = linkQueue.shift(),
@@ -17115,7 +17085,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17115
17085
 
17116
17086
  function wrapTemplate(type, template) {
17117
17087
  type = lowercase(type || 'html');
17118
- switch(type) {
17088
+ switch (type) {
17119
17089
  case 'svg':
17120
17090
  case 'math':
17121
17091
  var wrapper = document.createElement('div');
@@ -17196,7 +17166,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17196
17166
  //skip animations when the first digest occurs (when
17197
17167
  //both the new and the old values are the same) since
17198
17168
  //the CSS classes are the non-interpolated values
17199
- if(name === 'class' && newValue != oldValue) {
17169
+ if (name === 'class' && newValue != oldValue) {
17200
17170
  attr.$updateClass(newValue, oldValue);
17201
17171
  } else {
17202
17172
  attr.$set(name, newValue);
@@ -17226,7 +17196,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17226
17196
  i, ii;
17227
17197
 
17228
17198
  if ($rootElement) {
17229
- for(i = 0, ii = $rootElement.length; i < ii; i++) {
17199
+ for (i = 0, ii = $rootElement.length; i < ii; i++) {
17230
17200
  if ($rootElement[i] == firstElementToRemove) {
17231
17201
  $rootElement[i++] = newNode;
17232
17202
  for (var j = i, j2 = j + removeCount - 1,
@@ -17301,14 +17271,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17301
17271
  function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {
17302
17272
  try {
17303
17273
  linkFn(scope, $element, attrs, controllers, transcludeFn);
17304
- } catch(e) {
17274
+ } catch (e) {
17305
17275
  $exceptionHandler(e, startingTag($element));
17306
17276
  }
17307
17277
  }
17308
17278
  }];
17309
17279
  }
17310
17280
 
17311
- var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i;
17281
+ var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
17312
17282
  /**
17313
17283
  * Converts all accepted directives format into proper directive name.
17314
17284
  * All of these will become 'myDirective':
@@ -17374,7 +17344,7 @@ function nodesetLinkingFn(
17374
17344
  /* NodeList */ nodeList,
17375
17345
  /* Element */ rootElement,
17376
17346
  /* function(Function) */ boundTranscludeFn
17377
- ){}
17347
+ ) {}
17378
17348
 
17379
17349
  function directiveLinkingFn(
17380
17350
  /* nodesetLinkingFn */ nodesetLinkingFn,
@@ -17382,7 +17352,7 @@ function directiveLinkingFn(
17382
17352
  /* Node */ node,
17383
17353
  /* Element */ rootElement,
17384
17354
  /* function(Function) */ boundTranscludeFn
17385
- ){}
17355
+ ) {}
17386
17356
 
17387
17357
  function tokenDifference(str1, str2) {
17388
17358
  var values = '',
@@ -17390,10 +17360,10 @@ function tokenDifference(str1, str2) {
17390
17360
  tokens2 = str2.split(/\s+/);
17391
17361
 
17392
17362
  outer:
17393
- for(var i = 0; i < tokens1.length; i++) {
17363
+ for (var i = 0; i < tokens1.length; i++) {
17394
17364
  var token = tokens1[i];
17395
- for(var j = 0; j < tokens2.length; j++) {
17396
- if(token == tokens2[j]) continue outer;
17365
+ for (var j = 0; j < tokens2.length; j++) {
17366
+ if (token == tokens2[j]) continue outer;
17397
17367
  }
17398
17368
  values += (values.length > 0 ? ' ' : '') + token;
17399
17369
  }
@@ -17499,7 +17469,7 @@ function $ControllerProvider() {
17499
17469
  identifier = ident;
17500
17470
  }
17501
17471
 
17502
- if(isString(expression)) {
17472
+ if (isString(expression)) {
17503
17473
  match = expression.match(CNTRL_REG),
17504
17474
  constructor = match[1],
17505
17475
  identifier = identifier || match[3];
@@ -17585,8 +17555,8 @@ function $ControllerProvider() {
17585
17555
  </file>
17586
17556
  </example>
17587
17557
  */
17588
- function $DocumentProvider(){
17589
- this.$get = ['$window', function(window){
17558
+ function $DocumentProvider() {
17559
+ this.$get = ['$window', function(window) {
17590
17560
  return jqLite(window.document);
17591
17561
  }];
17592
17562
  }
@@ -17607,8 +17577,8 @@ function $DocumentProvider(){
17607
17577
  * ## Example:
17608
17578
  *
17609
17579
  * ```js
17610
- * angular.module('exceptionOverride', []).factory('$exceptionHandler', function () {
17611
- * return function (exception, cause) {
17580
+ * angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
17581
+ * return function(exception, cause) {
17612
17582
  * exception.message += ' (caused by "' + cause + '")';
17613
17583
  * throw exception;
17614
17584
  * };
@@ -17639,6 +17609,25 @@ function $ExceptionHandlerProvider() {
17639
17609
  }];
17640
17610
  }
17641
17611
 
17612
+ var APPLICATION_JSON = 'application/json';
17613
+ var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
17614
+ var JSON_START = /^\s*(\[|\{[^\{])/;
17615
+ var JSON_END = /[\}\]]\s*$/;
17616
+ var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
17617
+
17618
+ function defaultHttpResponseTransform(data, headers) {
17619
+ if (isString(data)) {
17620
+ // strip json vulnerability protection prefix
17621
+ data = data.replace(JSON_PROTECTION_PREFIX, '');
17622
+ var contentType = headers('Content-Type');
17623
+ if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
17624
+ (JSON_START.test(data) && JSON_END.test(data))) {
17625
+ data = fromJson(data);
17626
+ }
17627
+ }
17628
+ return data;
17629
+ }
17630
+
17642
17631
  /**
17643
17632
  * Parse headers into key value object
17644
17633
  *
@@ -17725,12 +17714,6 @@ function isSuccess(status) {
17725
17714
  * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
17726
17715
  * */
17727
17716
  function $HttpProvider() {
17728
- var JSON_START = /^\s*(\[|\{[^\{])/,
17729
- JSON_END = /[\}\]]\s*$/,
17730
- PROTECTION_PREFIX = /^\)\]\}',?\n/,
17731
- APPLICATION_JSON = 'application/json',
17732
- CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
17733
-
17734
17717
  /**
17735
17718
  * @ngdoc property
17736
17719
  * @name $httpProvider#defaults
@@ -17754,18 +17737,7 @@ function $HttpProvider() {
17754
17737
  **/
17755
17738
  var defaults = this.defaults = {
17756
17739
  // transform incoming response data
17757
- transformResponse: [function defaultHttpResponseTransform(data, headers) {
17758
- if (isString(data)) {
17759
- // strip json vulnerability protection prefix
17760
- data = data.replace(PROTECTION_PREFIX, '');
17761
- var contentType = headers('Content-Type');
17762
- if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
17763
- (JSON_START.test(data) && JSON_END.test(data))) {
17764
- data = fromJson(data);
17765
- }
17766
- }
17767
- return data;
17768
- }],
17740
+ transformResponse: [defaultHttpResponseTransform],
17769
17741
 
17770
17742
  // transform outgoing request data
17771
17743
  transformRequest: [function(d) {
@@ -17815,9 +17787,18 @@ function $HttpProvider() {
17815
17787
  };
17816
17788
 
17817
17789
  /**
17818
- * Are ordered by request, i.e. they are applied in the same order as the
17790
+ * @ngdoc property
17791
+ * @name $httpProvider#interceptors
17792
+ * @description
17793
+ *
17794
+ * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}
17795
+ * pre-processing of request or postprocessing of responses.
17796
+ *
17797
+ * These service factories are ordered by request, i.e. they are applied in the same order as the
17819
17798
  * array, on request, but reverse order, on response.
17820
- */
17799
+ *
17800
+ * {@link ng.$http#interceptors Interceptors detailed info}
17801
+ **/
17821
17802
  var interceptorFactories = this.interceptors = [];
17822
17803
 
17823
17804
  this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
@@ -18384,7 +18365,7 @@ function $HttpProvider() {
18384
18365
  }
18385
18366
  });
18386
18367
 
18387
- while(chain.length) {
18368
+ while (chain.length) {
18388
18369
  var thenFn = chain.shift();
18389
18370
  var rejectFn = chain.shift();
18390
18371
 
@@ -18699,7 +18680,7 @@ function $HttpProvider() {
18699
18680
  status: status,
18700
18681
  headers: headersGetter(headers),
18701
18682
  config: config,
18702
- statusText : statusText
18683
+ statusText: statusText
18703
18684
  });
18704
18685
  }
18705
18686
 
@@ -18720,7 +18701,7 @@ function $HttpProvider() {
18720
18701
 
18721
18702
  forEach(value, function(v) {
18722
18703
  if (isObject(v)) {
18723
- if (isDate(v)){
18704
+ if (isDate(v)) {
18724
18705
  v = v.toISOString();
18725
18706
  } else {
18726
18707
  v = toJson(v);
@@ -18730,7 +18711,7 @@ function $HttpProvider() {
18730
18711
  encodeUriQuery(v));
18731
18712
  });
18732
18713
  });
18733
- if(parts.length > 0) {
18714
+ if (parts.length > 0) {
18734
18715
  url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
18735
18716
  }
18736
18717
  return url;
@@ -18817,7 +18798,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
18817
18798
  statusText);
18818
18799
  };
18819
18800
 
18820
- var requestError = function () {
18801
+ var requestError = function() {
18821
18802
  // The response is always empty
18822
18803
  // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
18823
18804
  completeRequest(callback, -1, null, null, '');
@@ -18959,7 +18940,7 @@ function $InterpolateProvider() {
18959
18940
  * @param {string=} value new value to set the starting symbol to.
18960
18941
  * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
18961
18942
  */
18962
- this.startSymbol = function(value){
18943
+ this.startSymbol = function(value) {
18963
18944
  if (value) {
18964
18945
  startSymbol = value;
18965
18946
  return this;
@@ -18977,7 +18958,7 @@ function $InterpolateProvider() {
18977
18958
  * @param {string=} value new value to set the ending symbol to.
18978
18959
  * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
18979
18960
  */
18980
- this.endSymbol = function(value){
18961
+ this.endSymbol = function(value) {
18981
18962
  if (value) {
18982
18963
  endSymbol = value;
18983
18964
  return this;
@@ -19103,9 +19084,9 @@ function $InterpolateProvider() {
19103
19084
  concat = [],
19104
19085
  expressionPositions = [];
19105
19086
 
19106
- while(index < textLength) {
19107
- if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) &&
19108
- ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) {
19087
+ while (index < textLength) {
19088
+ if (((startIndex = text.indexOf(startSymbol, index)) != -1) &&
19089
+ ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1)) {
19109
19090
  if (index !== startIndex) {
19110
19091
  concat.push(unescapeText(text.substring(index, startIndex)));
19111
19092
  }
@@ -19139,20 +19120,20 @@ function $InterpolateProvider() {
19139
19120
 
19140
19121
  if (!mustHaveExpression || expressions.length) {
19141
19122
  var compute = function(values) {
19142
- for(var i = 0, ii = expressions.length; i < ii; i++) {
19123
+ for (var i = 0, ii = expressions.length; i < ii; i++) {
19143
19124
  if (allOrNothing && isUndefined(values[i])) return;
19144
19125
  concat[expressionPositions[i]] = values[i];
19145
19126
  }
19146
19127
  return concat.join('');
19147
19128
  };
19148
19129
 
19149
- var getValue = function (value) {
19130
+ var getValue = function(value) {
19150
19131
  return trustedContext ?
19151
19132
  $sce.getTrusted(trustedContext, value) :
19152
19133
  $sce.valueOf(value);
19153
19134
  };
19154
19135
 
19155
- var stringify = function (value) {
19136
+ var stringify = function(value) {
19156
19137
  if (value == null) { // null || undefined
19157
19138
  return '';
19158
19139
  }
@@ -19180,7 +19161,7 @@ function $InterpolateProvider() {
19180
19161
  }
19181
19162
 
19182
19163
  return compute(values);
19183
- } catch(err) {
19164
+ } catch (err) {
19184
19165
  var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
19185
19166
  err.toString());
19186
19167
  $exceptionHandler(newErr);
@@ -19190,7 +19171,7 @@ function $InterpolateProvider() {
19190
19171
  // all of these properties are undocumented for now
19191
19172
  exp: text, //just for compatibility with regular watchers created via $watch
19192
19173
  expressions: expressions,
19193
- $$watchDelegate: function (scope, listener, objectEquality) {
19174
+ $$watchDelegate: function(scope, listener, objectEquality) {
19194
19175
  var lastValue;
19195
19176
  return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
19196
19177
  var currValue = compute(values);
@@ -19211,7 +19192,7 @@ function $InterpolateProvider() {
19211
19192
  function parseStringifyInterceptor(value) {
19212
19193
  try {
19213
19194
  return stringify(getValue(value));
19214
- } catch(err) {
19195
+ } catch (err) {
19215
19196
  var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
19216
19197
  err.toString());
19217
19198
  $exceptionHandler(newErr);
@@ -19450,7 +19431,7 @@ function $IntervalProvider() {
19450
19431
  *
19451
19432
  * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
19452
19433
  */
19453
- function $LocaleProvider(){
19434
+ function $LocaleProvider() {
19454
19435
  this.$get = function() {
19455
19436
  return {
19456
19437
  id: 'en-us',
@@ -19493,7 +19474,7 @@ function $LocaleProvider(){
19493
19474
  SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','),
19494
19475
  AMPMS: ['AM','PM'],
19495
19476
  medium: 'MMM d, y h:mm:ss a',
19496
- short: 'M/d/yy h:mm a',
19477
+ 'short': 'M/d/yy h:mm a',
19497
19478
  fullDate: 'EEEE, MMMM d, y',
19498
19479
  longDate: 'MMMM d, y',
19499
19480
  mediumDate: 'MMM d, y',
@@ -19608,7 +19589,7 @@ function LocationHtml5Url(appBase, basePrefix) {
19608
19589
 
19609
19590
  /**
19610
19591
  * Parse given html5 (regular) url string into properties
19611
- * @param {string} newAbsoluteUrl HTML5 url
19592
+ * @param {string} url HTML5 url
19612
19593
  * @private
19613
19594
  */
19614
19595
  this.$$parse = function(url) {
@@ -19649,14 +19630,14 @@ function LocationHtml5Url(appBase, basePrefix) {
19649
19630
  var appUrl, prevAppUrl;
19650
19631
  var rewrittenUrl;
19651
19632
 
19652
- if ( (appUrl = beginsWith(appBase, url)) !== undefined ) {
19633
+ if ((appUrl = beginsWith(appBase, url)) !== undefined) {
19653
19634
  prevAppUrl = appUrl;
19654
- if ( (appUrl = beginsWith(basePrefix, appUrl)) !== undefined ) {
19635
+ if ((appUrl = beginsWith(basePrefix, appUrl)) !== undefined) {
19655
19636
  rewrittenUrl = appBaseNoFile + (beginsWith('/', appUrl) || appUrl);
19656
19637
  } else {
19657
19638
  rewrittenUrl = appBase + prevAppUrl;
19658
19639
  }
19659
- } else if ( (appUrl = beginsWith(appBaseNoFile, url)) !== undefined ) {
19640
+ } else if ((appUrl = beginsWith(appBaseNoFile, url)) !== undefined) {
19660
19641
  rewrittenUrl = appBaseNoFile + appUrl;
19661
19642
  } else if (appBaseNoFile == url + '/') {
19662
19643
  rewrittenUrl = appBaseNoFile;
@@ -19718,7 +19699,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
19718
19699
  * Inside of Angular, we're always using pathnames that
19719
19700
  * do not include drive names for routing.
19720
19701
  */
19721
- function removeWindowsDriveName (path, url, base) {
19702
+ function removeWindowsDriveName(path, url, base) {
19722
19703
  /*
19723
19704
  Matches paths for file protocol on windows,
19724
19705
  such as /C:/foo/bar, and captures only /foo/bar.
@@ -19755,7 +19736,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
19755
19736
  };
19756
19737
 
19757
19738
  this.$$parseLinkUrl = function(url, relHref) {
19758
- if(stripHash(appBase) == stripHash(url)) {
19739
+ if (stripHash(appBase) == stripHash(url)) {
19759
19740
  this.$$parse(url);
19760
19741
  return true;
19761
19742
  }
@@ -19790,11 +19771,11 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) {
19790
19771
  var rewrittenUrl;
19791
19772
  var appUrl;
19792
19773
 
19793
- if ( appBase == stripHash(url) ) {
19774
+ if (appBase == stripHash(url)) {
19794
19775
  rewrittenUrl = url;
19795
- } else if ( (appUrl = beginsWith(appBaseNoFile, url)) ) {
19776
+ } else if ((appUrl = beginsWith(appBaseNoFile, url))) {
19796
19777
  rewrittenUrl = appBase + hashPrefix + appUrl;
19797
- } else if ( appBaseNoFile === url + '/') {
19778
+ } else if (appBaseNoFile === url + '/') {
19798
19779
  rewrittenUrl = appBaseNoFile;
19799
19780
  }
19800
19781
  if (rewrittenUrl) {
@@ -20041,7 +20022,7 @@ var locationPrototype = {
20041
20022
  }
20042
20023
  };
20043
20024
 
20044
- forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function (Location) {
20025
+ forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {
20045
20026
  Location.prototype = Object.create(locationPrototype);
20046
20027
 
20047
20028
  /**
@@ -20133,7 +20114,7 @@ function locationGetterSetter(property, preprocess) {
20133
20114
  * @description
20134
20115
  * Use the `$locationProvider` to configure how the application deep linking paths are stored.
20135
20116
  */
20136
- function $LocationProvider(){
20117
+ function $LocationProvider() {
20137
20118
  var hashPrefix = '',
20138
20119
  html5Mode = {
20139
20120
  enabled: false,
@@ -20240,7 +20221,7 @@ function $LocationProvider(){
20240
20221
  */
20241
20222
 
20242
20223
  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement',
20243
- function( $rootScope, $browser, $sniffer, $rootElement) {
20224
+ function($rootScope, $browser, $sniffer, $rootElement) {
20244
20225
  var $location,
20245
20226
  LocationMode,
20246
20227
  baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
@@ -20441,7 +20422,7 @@ function $LocationProvider(){
20441
20422
  * @description
20442
20423
  * Use the `$logProvider` to configure how the application logs messages
20443
20424
  */
20444
- function $LogProvider(){
20425
+ function $LogProvider() {
20445
20426
  var debug = true,
20446
20427
  self = this;
20447
20428
 
@@ -20461,7 +20442,7 @@ function $LogProvider(){
20461
20442
  }
20462
20443
  };
20463
20444
 
20464
- this.$get = ['$window', function($window){
20445
+ this.$get = ['$window', function($window) {
20465
20446
  return {
20466
20447
  /**
20467
20448
  * @ngdoc method
@@ -20506,7 +20487,7 @@ function $LogProvider(){
20506
20487
  * @description
20507
20488
  * Write a debug message
20508
20489
  */
20509
- debug: (function () {
20490
+ debug: (function() {
20510
20491
  var fn = consoleLog('debug');
20511
20492
 
20512
20493
  return function() {
@@ -20659,7 +20640,7 @@ CONSTANTS['this'].sharedGetter = true;
20659
20640
 
20660
20641
  //Operators - will be wrapped by binaryFn/unaryFn/assignment/filter
20661
20642
  var OPERATORS = extend(createMap(), {
20662
- '+':function(self, locals, a,b){
20643
+ '+':function(self, locals, a, b) {
20663
20644
  a=a(self, locals); b=b(self, locals);
20664
20645
  if (isDefined(a)) {
20665
20646
  if (isDefined(b)) {
@@ -20668,24 +20649,24 @@ var OPERATORS = extend(createMap(), {
20668
20649
  return a;
20669
20650
  }
20670
20651
  return isDefined(b)?b:undefined;},
20671
- '-':function(self, locals, a,b){
20652
+ '-':function(self, locals, a, b) {
20672
20653
  a=a(self, locals); b=b(self, locals);
20673
20654
  return (isDefined(a)?a:0)-(isDefined(b)?b:0);
20674
20655
  },
20675
- '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},
20676
- '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},
20677
- '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
20678
- '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
20679
- '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
20680
- '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
20681
- '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},
20682
- '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},
20683
- '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},
20684
- '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},
20685
- '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},
20686
- '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},
20687
- '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},
20688
- '!':function(self, locals, a){return !a(self, locals);},
20656
+ '*':function(self, locals, a, b) {return a(self, locals)*b(self, locals);},
20657
+ '/':function(self, locals, a, b) {return a(self, locals)/b(self, locals);},
20658
+ '%':function(self, locals, a, b) {return a(self, locals)%b(self, locals);},
20659
+ '===':function(self, locals, a, b) {return a(self, locals)===b(self, locals);},
20660
+ '!==':function(self, locals, a, b) {return a(self, locals)!==b(self, locals);},
20661
+ '==':function(self, locals, a, b) {return a(self, locals)==b(self, locals);},
20662
+ '!=':function(self, locals, a, b) {return a(self, locals)!=b(self, locals);},
20663
+ '<':function(self, locals, a, b) {return a(self, locals)<b(self, locals);},
20664
+ '>':function(self, locals, a, b) {return a(self, locals)>b(self, locals);},
20665
+ '<=':function(self, locals, a, b) {return a(self, locals)<=b(self, locals);},
20666
+ '>=':function(self, locals, a, b) {return a(self, locals)>=b(self, locals);},
20667
+ '&&':function(self, locals, a, b) {return a(self, locals)&&b(self, locals);},
20668
+ '||':function(self, locals, a, b) {return a(self, locals)||b(self, locals);},
20669
+ '!':function(self, locals, a) {return !a(self, locals);},
20689
20670
 
20690
20671
  //Tokenized as operators but parsed as assignment/filters
20691
20672
  '=':true,
@@ -20700,14 +20681,14 @@ var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'
20700
20681
  /**
20701
20682
  * @constructor
20702
20683
  */
20703
- var Lexer = function (options) {
20684
+ var Lexer = function(options) {
20704
20685
  this.options = options;
20705
20686
  };
20706
20687
 
20707
20688
  Lexer.prototype = {
20708
20689
  constructor: Lexer,
20709
20690
 
20710
- lex: function (text) {
20691
+ lex: function(text) {
20711
20692
  this.text = text;
20712
20693
  this.index = 0;
20713
20694
  this.ch = undefined;
@@ -20944,13 +20925,13 @@ function isConstant(exp) {
20944
20925
  /**
20945
20926
  * @constructor
20946
20927
  */
20947
- var Parser = function (lexer, $filter, options) {
20928
+ var Parser = function(lexer, $filter, options) {
20948
20929
  this.lexer = lexer;
20949
20930
  this.$filter = $filter;
20950
20931
  this.options = options;
20951
20932
  };
20952
20933
 
20953
- Parser.ZERO = extend(function () {
20934
+ Parser.ZERO = extend(function() {
20954
20935
  return 0;
20955
20936
  }, {
20956
20937
  sharedGetter: true,
@@ -20960,7 +20941,7 @@ Parser.ZERO = extend(function () {
20960
20941
  Parser.prototype = {
20961
20942
  constructor: Parser,
20962
20943
 
20963
- parse: function (text) {
20944
+ parse: function(text) {
20964
20945
  this.text = text;
20965
20946
  this.tokens = this.lexer.lex(text);
20966
20947
 
@@ -20976,7 +20957,7 @@ Parser.prototype = {
20976
20957
  return value;
20977
20958
  },
20978
20959
 
20979
- primary: function () {
20960
+ primary: function() {
20980
20961
  var primary;
20981
20962
  if (this.expect('(')) {
20982
20963
  primary = this.filterChain();
@@ -21039,7 +21020,7 @@ Parser.prototype = {
21039
21020
  return false;
21040
21021
  },
21041
21022
 
21042
- expect: function(e1, e2, e3, e4){
21023
+ expect: function(e1, e2, e3, e4) {
21043
21024
  var token = this.peek(e1, e2, e3, e4);
21044
21025
  if (token) {
21045
21026
  this.tokens.shift();
@@ -21048,7 +21029,7 @@ Parser.prototype = {
21048
21029
  return false;
21049
21030
  },
21050
21031
 
21051
- consume: function(e1){
21032
+ consume: function(e1) {
21052
21033
  if (!this.expect(e1)) {
21053
21034
  this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
21054
21035
  }
@@ -21170,7 +21151,7 @@ Parser.prototype = {
21170
21151
  if ((token = this.expect(':'))) {
21171
21152
  var right = this.assignment();
21172
21153
 
21173
- return extend(function $parseTernary(self, locals){
21154
+ return extend(function $parseTernary(self, locals) {
21174
21155
  return left(self, locals) ? middle(self, locals) : right(self, locals);
21175
21156
  }, {
21176
21157
  constant: left.constant && middle.constant && right.constant
@@ -21330,7 +21311,7 @@ Parser.prototype = {
21330
21311
  },
21331
21312
 
21332
21313
  // This is used with json array declaration
21333
- arrayDeclaration: function () {
21314
+ arrayDeclaration: function() {
21334
21315
  var elementFns = [];
21335
21316
  if (this.peekToken().text !== ']') {
21336
21317
  do {
@@ -21357,7 +21338,7 @@ Parser.prototype = {
21357
21338
  });
21358
21339
  },
21359
21340
 
21360
- object: function () {
21341
+ object: function() {
21361
21342
  var keys = [], valueFns = [];
21362
21343
  if (this.peekToken().text !== '}') {
21363
21344
  do {
@@ -21506,6 +21487,12 @@ function getterFn(path, options, fullExp) {
21506
21487
  return fn;
21507
21488
  }
21508
21489
 
21490
+ var objectValueOf = Object.prototype.valueOf;
21491
+
21492
+ function getValueOf(value) {
21493
+ return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
21494
+ }
21495
+
21509
21496
  ///////////////////////////////////
21510
21497
 
21511
21498
  /**
@@ -21652,7 +21639,7 @@ function $ParseProvider() {
21652
21639
  // attempt to convert the value to a primitive type
21653
21640
  // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
21654
21641
  // be cheaply dirty-checked
21655
- newValue = newValue.valueOf();
21642
+ newValue = getValueOf(newValue);
21656
21643
 
21657
21644
  if (typeof newValue === 'object') {
21658
21645
  // objects/arrays are not supported - deep-watching them would be too expensive
@@ -21679,7 +21666,7 @@ function $ParseProvider() {
21679
21666
  var newInputValue = inputExpressions(scope);
21680
21667
  if (!expressionInputDirtyCheck(newInputValue, oldInputValue)) {
21681
21668
  lastResult = parsedExpression(scope);
21682
- oldInputValue = newInputValue && newInputValue.valueOf();
21669
+ oldInputValue = newInputValue && getValueOf(newInputValue);
21683
21670
  }
21684
21671
  return lastResult;
21685
21672
  }, listener, objectEquality);
@@ -21696,7 +21683,7 @@ function $ParseProvider() {
21696
21683
  for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
21697
21684
  var newInputValue = inputExpressions[i](scope);
21698
21685
  if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) {
21699
- oldInputValueOfValues[i] = newInputValue && newInputValue.valueOf();
21686
+ oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
21700
21687
  }
21701
21688
  }
21702
21689
 
@@ -21718,7 +21705,7 @@ function $ParseProvider() {
21718
21705
  listener.apply(this, arguments);
21719
21706
  }
21720
21707
  if (isDefined(value)) {
21721
- scope.$$postDigest(function () {
21708
+ scope.$$postDigest(function() {
21722
21709
  if (isDefined(lastValue)) {
21723
21710
  unwatch();
21724
21711
  }
@@ -21737,15 +21724,15 @@ function $ParseProvider() {
21737
21724
  listener.call(this, value, old, scope);
21738
21725
  }
21739
21726
  if (isAllDefined(value)) {
21740
- scope.$$postDigest(function () {
21741
- if(isAllDefined(lastValue)) unwatch();
21727
+ scope.$$postDigest(function() {
21728
+ if (isAllDefined(lastValue)) unwatch();
21742
21729
  });
21743
21730
  }
21744
21731
  }, objectEquality);
21745
21732
 
21746
21733
  function isAllDefined(value) {
21747
21734
  var allDefined = true;
21748
- forEach(value, function (val) {
21735
+ forEach(value, function(val) {
21749
21736
  if (!isDefined(val)) allDefined = false;
21750
21737
  });
21751
21738
  return allDefined;
@@ -22109,7 +22096,7 @@ function qFactory(nextTick, exceptionHandler) {
22109
22096
  } else {
22110
22097
  promise.reject(state.value);
22111
22098
  }
22112
- } catch(e) {
22099
+ } catch (e) {
22113
22100
  promise.reject(e);
22114
22101
  exceptionHandler(e);
22115
22102
  }
@@ -22159,7 +22146,7 @@ function qFactory(nextTick, exceptionHandler) {
22159
22146
  this.promise.$$state.status = 1;
22160
22147
  scheduleProcessQueue(this.promise.$$state);
22161
22148
  }
22162
- } catch(e) {
22149
+ } catch (e) {
22163
22150
  fns[1](e);
22164
22151
  exceptionHandler(e);
22165
22152
  }
@@ -22187,7 +22174,7 @@ function qFactory(nextTick, exceptionHandler) {
22187
22174
  callback = callbacks[i][3];
22188
22175
  try {
22189
22176
  result.notify(isFunction(callback) ? callback(progress) : progress);
22190
- } catch(e) {
22177
+ } catch (e) {
22191
22178
  exceptionHandler(e);
22192
22179
  }
22193
22180
  }
@@ -22252,7 +22239,7 @@ function qFactory(nextTick, exceptionHandler) {
22252
22239
  var callbackOutput = null;
22253
22240
  try {
22254
22241
  if (isFunction(callback)) callbackOutput = callback();
22255
- } catch(e) {
22242
+ } catch (e) {
22256
22243
  return makePromise(e, false);
22257
22244
  }
22258
22245
  if (isPromiseLike(callbackOutput)) {
@@ -22360,7 +22347,7 @@ function qFactory(nextTick, exceptionHandler) {
22360
22347
  return $Q;
22361
22348
  }
22362
22349
 
22363
- function $$RAFProvider(){ //rAF
22350
+ function $$RAFProvider() { //rAF
22364
22351
  this.$get = ['$window', '$timeout', function($window, $timeout) {
22365
22352
  var requestAnimationFrame = $window.requestAnimationFrame ||
22366
22353
  $window.webkitRequestAnimationFrame ||
@@ -22459,7 +22446,7 @@ function $$RAFProvider(){ //rAF
22459
22446
  * They also provide an event emission/broadcast and subscription facility. See the
22460
22447
  * {@link guide/scope developer guide on scopes}.
22461
22448
  */
22462
- function $RootScopeProvider(){
22449
+ function $RootScopeProvider() {
22463
22450
  var TTL = 10;
22464
22451
  var $rootScopeMinErr = minErr('$rootScope');
22465
22452
  var lastDirtyWatch = null;
@@ -22473,7 +22460,7 @@ function $RootScopeProvider(){
22473
22460
  };
22474
22461
 
22475
22462
  this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
22476
- function( $injector, $exceptionHandler, $parse, $browser) {
22463
+ function($injector, $exceptionHandler, $parse, $browser) {
22477
22464
 
22478
22465
  /**
22479
22466
  * @ngdoc type
@@ -22816,7 +22803,7 @@ function $RootScopeProvider(){
22816
22803
  if (!watchExpressions.length) {
22817
22804
  // No expressions means we call the listener ASAP
22818
22805
  var shouldCall = true;
22819
- self.$evalAsync(function () {
22806
+ self.$evalAsync(function() {
22820
22807
  if (shouldCall) listener(newValues, newValues, self);
22821
22808
  });
22822
22809
  return function deregisterWatchGroup() {
@@ -22833,7 +22820,7 @@ function $RootScopeProvider(){
22833
22820
  });
22834
22821
  }
22835
22822
 
22836
- forEach(watchExpressions, function (expr, i) {
22823
+ forEach(watchExpressions, function(expr, i) {
22837
22824
  var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
22838
22825
  newValues[i] = value;
22839
22826
  oldValues[i] = oldValue;
@@ -23005,7 +22992,7 @@ function $RootScopeProvider(){
23005
22992
  if (oldLength > newLength) {
23006
22993
  // we used to have more keys, need to find them and destroy them.
23007
22994
  changeDetected++;
23008
- for(key in oldValue) {
22995
+ for (key in oldValue) {
23009
22996
  if (!newValue.hasOwnProperty(key)) {
23010
22997
  oldLength--;
23011
22998
  delete oldValue[key];
@@ -23125,7 +23112,7 @@ function $RootScopeProvider(){
23125
23112
  dirty = false;
23126
23113
  current = target;
23127
23114
 
23128
- while(asyncQueue.length) {
23115
+ while (asyncQueue.length) {
23129
23116
  try {
23130
23117
  asyncTask = asyncQueue.shift();
23131
23118
  asyncTask.scope.$eval(asyncTask.expression);
@@ -23182,7 +23169,7 @@ function $RootScopeProvider(){
23182
23169
  // this piece should be kept in sync with the traversal in $broadcast
23183
23170
  if (!(next = (current.$$childHead ||
23184
23171
  (current !== target && current.$$nextSibling)))) {
23185
- while(current !== target && !(next = current.$$nextSibling)) {
23172
+ while (current !== target && !(next = current.$$nextSibling)) {
23186
23173
  current = current.$parent;
23187
23174
  }
23188
23175
  }
@@ -23190,7 +23177,7 @@ function $RootScopeProvider(){
23190
23177
 
23191
23178
  // `break traverseScopesLoop;` takes us to here
23192
23179
 
23193
- if((dirty || asyncQueue.length) && !(ttl--)) {
23180
+ if ((dirty || asyncQueue.length) && !(ttl--)) {
23194
23181
  clearPhase();
23195
23182
  throw $rootScopeMinErr('infdig',
23196
23183
  '{0} $digest() iterations reached. Aborting!\n' +
@@ -23202,7 +23189,7 @@ function $RootScopeProvider(){
23202
23189
 
23203
23190
  clearPhase();
23204
23191
 
23205
- while(postDigestQueue.length) {
23192
+ while (postDigestQueue.length) {
23206
23193
  try {
23207
23194
  postDigestQueue.shift()();
23208
23195
  } catch (e) {
@@ -23358,7 +23345,7 @@ function $RootScopeProvider(){
23358
23345
  asyncQueue.push({scope: this, expression: expr});
23359
23346
  },
23360
23347
 
23361
- $$postDigest : function(fn) {
23348
+ $$postDigest: function(fn) {
23362
23349
  postDigestQueue.push(fn);
23363
23350
  },
23364
23351
 
@@ -23495,8 +23482,11 @@ function $RootScopeProvider(){
23495
23482
 
23496
23483
  var self = this;
23497
23484
  return function() {
23498
- namedListeners[namedListeners.indexOf(listener)] = null;
23499
- decrementListenerCount(self, 1, name);
23485
+ var indexOfListener = namedListeners.indexOf(listener);
23486
+ if (indexOfListener !== -1) {
23487
+ namedListeners[indexOfListener] = null;
23488
+ decrementListenerCount(self, 1, name);
23489
+ }
23500
23490
  };
23501
23491
  },
23502
23492
 
@@ -23628,7 +23618,7 @@ function $RootScopeProvider(){
23628
23618
 
23629
23619
  try {
23630
23620
  listeners[i].apply(null, listenerArgs);
23631
- } catch(e) {
23621
+ } catch (e) {
23632
23622
  $exceptionHandler(e);
23633
23623
  }
23634
23624
  }
@@ -23639,7 +23629,7 @@ function $RootScopeProvider(){
23639
23629
  // (though it differs due to having the extra check for $$listenerCount)
23640
23630
  if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
23641
23631
  (current !== target && current.$$nextSibling)))) {
23642
- while(current !== target && !(next = current.$$nextSibling)) {
23632
+ while (current !== target && !(next = current.$$nextSibling)) {
23643
23633
  current = current.$parent;
23644
23634
  }
23645
23635
  }
@@ -23693,7 +23683,7 @@ function $RootScopeProvider(){
23693
23683
  while (applyAsyncQueue.length) {
23694
23684
  try {
23695
23685
  applyAsyncQueue.shift()();
23696
- } catch(e) {
23686
+ } catch (e) {
23697
23687
  $exceptionHandler(e);
23698
23688
  }
23699
23689
  }
@@ -23794,15 +23784,6 @@ var SCE_CONTEXTS = {
23794
23784
 
23795
23785
  // Helper functions follow.
23796
23786
 
23797
- // Copied from:
23798
- // http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962
23799
- // Prereq: s is a string.
23800
- function escapeForRegexp(s) {
23801
- return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
23802
- replace(/\x08/g, '\\x08');
23803
- }
23804
-
23805
-
23806
23787
  function adjustMatcher(matcher) {
23807
23788
  if (matcher === 'self') {
23808
23789
  return matcher;
@@ -23938,7 +23919,7 @@ function $SceDelegateProvider() {
23938
23919
  * @description
23939
23920
  * Sets/Gets the whitelist of trusted resource URLs.
23940
23921
  */
23941
- this.resourceUrlWhitelist = function (value) {
23922
+ this.resourceUrlWhitelist = function(value) {
23942
23923
  if (arguments.length) {
23943
23924
  resourceUrlWhitelist = adjustMatchers(value);
23944
23925
  }
@@ -23972,7 +23953,7 @@ function $SceDelegateProvider() {
23972
23953
  * Sets/Gets the blacklist of trusted resource URLs.
23973
23954
  */
23974
23955
 
23975
- this.resourceUrlBlacklist = function (value) {
23956
+ this.resourceUrlBlacklist = function(value) {
23976
23957
  if (arguments.length) {
23977
23958
  resourceUrlBlacklist = adjustMatchers(value);
23978
23959
  }
@@ -24453,7 +24434,7 @@ function $SceProvider() {
24453
24434
  * @description
24454
24435
  * Enables/disables SCE and returns the current value.
24455
24436
  */
24456
- this.enabled = function (value) {
24437
+ this.enabled = function(value) {
24457
24438
  if (arguments.length) {
24458
24439
  enabled = !!value;
24459
24440
  }
@@ -24507,11 +24488,11 @@ function $SceProvider() {
24507
24488
  * sce.js and sceSpecs.js would need to be aware of this detail.
24508
24489
  */
24509
24490
 
24510
- this.$get = ['$document', '$parse', '$sceDelegate', function(
24511
- $document, $parse, $sceDelegate) {
24491
+ this.$get = ['$parse', '$sceDelegate', function(
24492
+ $parse, $sceDelegate) {
24512
24493
  // Prereq: Ensure that we're not running in IE<11 quirks mode. In that mode, IE < 11 allow
24513
24494
  // the "expression(javascript expression)" syntax which is insecure.
24514
- if (enabled && $document[0].documentMode < 8) {
24495
+ if (enabled && msie < 8) {
24515
24496
  throw $sceMinErr('iequirks',
24516
24497
  'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
24517
24498
  'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
@@ -24531,7 +24512,7 @@ function $SceProvider() {
24531
24512
  * @description
24532
24513
  * Returns a boolean indicating if SCE is enabled.
24533
24514
  */
24534
- sce.isEnabled = function () {
24515
+ sce.isEnabled = function() {
24535
24516
  return enabled;
24536
24517
  };
24537
24518
  sce.trustAs = $sceDelegate.trustAs;
@@ -24567,7 +24548,7 @@ function $SceProvider() {
24567
24548
  if (parsed.literal && parsed.constant) {
24568
24549
  return parsed;
24569
24550
  } else {
24570
- return $parse(expr, function (value) {
24551
+ return $parse(expr, function(value) {
24571
24552
  return sce.getTrusted(type, value);
24572
24553
  });
24573
24554
  }
@@ -24820,15 +24801,15 @@ function $SceProvider() {
24820
24801
  getTrusted = sce.getTrusted,
24821
24802
  trustAs = sce.trustAs;
24822
24803
 
24823
- forEach(SCE_CONTEXTS, function (enumValue, name) {
24804
+ forEach(SCE_CONTEXTS, function(enumValue, name) {
24824
24805
  var lName = lowercase(name);
24825
- sce[camelCase("parse_as_" + lName)] = function (expr) {
24806
+ sce[camelCase("parse_as_" + lName)] = function(expr) {
24826
24807
  return parse(enumValue, expr);
24827
24808
  };
24828
- sce[camelCase("get_trusted_" + lName)] = function (value) {
24809
+ sce[camelCase("get_trusted_" + lName)] = function(value) {
24829
24810
  return getTrusted(enumValue, value);
24830
24811
  };
24831
- sce[camelCase("trust_as_" + lName)] = function (value) {
24812
+ sce[camelCase("trust_as_" + lName)] = function(value) {
24832
24813
  return trustAs(enumValue, value);
24833
24814
  };
24834
24815
  });
@@ -24859,22 +24840,22 @@ function $SnifferProvider() {
24859
24840
  boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
24860
24841
  document = $document[0] || {},
24861
24842
  vendorPrefix,
24862
- vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
24843
+ vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/,
24863
24844
  bodyStyle = document.body && document.body.style,
24864
24845
  transitions = false,
24865
24846
  animations = false,
24866
24847
  match;
24867
24848
 
24868
24849
  if (bodyStyle) {
24869
- for(var prop in bodyStyle) {
24870
- if(match = vendorRegex.exec(prop)) {
24850
+ for (var prop in bodyStyle) {
24851
+ if (match = vendorRegex.exec(prop)) {
24871
24852
  vendorPrefix = match[0];
24872
24853
  vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
24873
24854
  break;
24874
24855
  }
24875
24856
  }
24876
24857
 
24877
- if(!vendorPrefix) {
24858
+ if (!vendorPrefix) {
24878
24859
  vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit';
24879
24860
  }
24880
24861
 
@@ -24915,8 +24896,8 @@ function $SnifferProvider() {
24915
24896
  },
24916
24897
  csp: csp(),
24917
24898
  vendorPrefix: vendorPrefix,
24918
- transitions : transitions,
24919
- animations : animations,
24899
+ transitions: transitions,
24900
+ animations: animations,
24920
24901
  android: android
24921
24902
  };
24922
24903
  }];
@@ -24947,13 +24928,29 @@ function $TemplateRequestProvider() {
24947
24928
  var self = handleRequestFn;
24948
24929
  self.totalPendingRequests++;
24949
24930
 
24950
- return $http.get(tpl, { cache : $templateCache })
24951
- .then(function(response) {
24952
- var html = response.data;
24953
- if(!html || html.length === 0) {
24954
- return handleError();
24931
+ var transformResponse = $http.defaults && $http.defaults.transformResponse;
24932
+
24933
+ if (isArray(transformResponse)) {
24934
+ var original = transformResponse;
24935
+ transformResponse = [];
24936
+ for (var i=0; i<original.length; ++i) {
24937
+ var transformer = original[i];
24938
+ if (transformer !== defaultHttpResponseTransform) {
24939
+ transformResponse.push(transformer);
24955
24940
  }
24941
+ }
24942
+ } else if (transformResponse === defaultHttpResponseTransform) {
24943
+ transformResponse = null;
24944
+ }
24945
+
24946
+ var httpOptions = {
24947
+ cache: $templateCache,
24948
+ transformResponse: transformResponse
24949
+ };
24956
24950
 
24951
+ return $http.get(tpl, httpOptions)
24952
+ .then(function(response) {
24953
+ var html = response.data;
24957
24954
  self.totalPendingRequests--;
24958
24955
  $templateCache.put(tpl, html);
24959
24956
  return html;
@@ -25007,7 +25004,7 @@ function $$TestabilityProvider() {
25007
25004
  if (dataBinding) {
25008
25005
  forEach(dataBinding, function(bindingName) {
25009
25006
  if (opt_exactMatch) {
25010
- var matcher = new RegExp('(^|\\s)' + expression + '(\\s|\\||$)');
25007
+ var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)');
25011
25008
  if (matcher.test(bindingName)) {
25012
25009
  matches.push(binding);
25013
25010
  }
@@ -25129,7 +25126,7 @@ function $TimeoutProvider() {
25129
25126
  timeoutId = $browser.defer(function() {
25130
25127
  try {
25131
25128
  deferred.resolve(fn());
25132
- } catch(e) {
25129
+ } catch (e) {
25133
25130
  deferred.reject(e);
25134
25131
  $exceptionHandler(e);
25135
25132
  }
@@ -25295,7 +25292,7 @@ function urlIsSameOrigin(requestUrl) {
25295
25292
  <file name="index.html">
25296
25293
  <script>
25297
25294
  angular.module('windowExample', [])
25298
- .controller('ExampleController', ['$scope', '$window', function ($scope, $window) {
25295
+ .controller('ExampleController', ['$scope', '$window', function($scope, $window) {
25299
25296
  $scope.greeting = 'Hello, World!';
25300
25297
  $scope.doGreeting = function(greeting) {
25301
25298
  $window.alert(greeting);
@@ -25316,7 +25313,7 @@ function urlIsSameOrigin(requestUrl) {
25316
25313
  </file>
25317
25314
  </example>
25318
25315
  */
25319
- function $WindowProvider(){
25316
+ function $WindowProvider() {
25320
25317
  this.$get = valueFn(window);
25321
25318
  }
25322
25319
 
@@ -25425,7 +25422,7 @@ function $FilterProvider($provide) {
25425
25422
  * of the registered filter instances.
25426
25423
  */
25427
25424
  function register(name, factory) {
25428
- if(isObject(name)) {
25425
+ if (isObject(name)) {
25429
25426
  var filters = {};
25430
25427
  forEach(name, function(filter, key) {
25431
25428
  filters[key] = register(key, filter);
@@ -25592,7 +25589,7 @@ function filterFilter() {
25592
25589
 
25593
25590
  predicates.check = function(value, index) {
25594
25591
  for (var j = 0; j < predicates.length; j++) {
25595
- if(!predicates[j](value, index)) {
25592
+ if (!predicates[j](value, index)) {
25596
25593
  return false;
25597
25594
  }
25598
25595
  }
@@ -25621,7 +25618,7 @@ function filterFilter() {
25621
25618
  }
25622
25619
  }
25623
25620
 
25624
- var search = function(obj, text){
25621
+ var search = function(obj, text) {
25625
25622
  if (typeof text === 'string' && text.charAt(0) === '!') {
25626
25623
  return !search(obj, text.substr(1));
25627
25624
  }
@@ -25635,7 +25632,7 @@ function filterFilter() {
25635
25632
  case 'object':
25636
25633
  return comparator(obj, text);
25637
25634
  default:
25638
- for ( var objKey in obj) {
25635
+ for (var objKey in obj) {
25639
25636
  if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
25640
25637
  return true;
25641
25638
  }
@@ -25644,7 +25641,7 @@ function filterFilter() {
25644
25641
  }
25645
25642
  return false;
25646
25643
  case 'array':
25647
- for ( var i = 0; i < obj.length; i++) {
25644
+ for (var i = 0; i < obj.length; i++) {
25648
25645
  if (search(obj[i], text)) {
25649
25646
  return true;
25650
25647
  }
@@ -25679,7 +25676,7 @@ function filterFilter() {
25679
25676
  return array;
25680
25677
  }
25681
25678
  var filtered = [];
25682
- for ( var j = 0; j < array.length; j++) {
25679
+ for (var j = 0; j < array.length; j++) {
25683
25680
  var value = array[j];
25684
25681
  if (predicates.check(value, j)) {
25685
25682
  filtered.push(value);
@@ -25744,7 +25741,7 @@ function filterFilter() {
25744
25741
  currencyFilter.$inject = ['$locale'];
25745
25742
  function currencyFilter($locale) {
25746
25743
  var formats = $locale.NUMBER_FORMATS;
25747
- return function(amount, currencySymbol, fractionSize){
25744
+ return function(amount, currencySymbol, fractionSize) {
25748
25745
  if (isUndefined(currencySymbol)) {
25749
25746
  currencySymbol = formats.CURRENCY_SYM;
25750
25747
  }
@@ -25891,7 +25888,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
25891
25888
  }
25892
25889
 
25893
25890
  // format fraction part.
25894
- while(fraction.length < fractionSize) {
25891
+ while (fraction.length < fractionSize) {
25895
25892
  fraction += '0';
25896
25893
  }
25897
25894
 
@@ -25916,7 +25913,7 @@ function padNumber(num, digits, trim) {
25916
25913
  num = -num;
25917
25914
  }
25918
25915
  num = '' + num;
25919
- while(num.length < digits) num = '0' + num;
25916
+ while (num.length < digits) num = '0' + num;
25920
25917
  if (trim)
25921
25918
  num = num.substr(num.length - digits);
25922
25919
  return neg + num;
@@ -25929,7 +25926,7 @@ function dateGetter(name, size, offset, trim) {
25929
25926
  var value = date['get' + name]();
25930
25927
  if (offset > 0 || value > -offset)
25931
25928
  value += offset;
25932
- if (value === 0 && offset == -12 ) value = 12;
25929
+ if (value === 0 && offset == -12) value = 12;
25933
25930
  return padNumber(value, size, trim);
25934
25931
  };
25935
25932
  }
@@ -26154,7 +26151,7 @@ function dateFilter($locale) {
26154
26151
  return date;
26155
26152
  }
26156
26153
 
26157
- while(format) {
26154
+ while (format) {
26158
26155
  match = DATE_FORMATS_SPLIT.exec(format);
26159
26156
  if (match) {
26160
26157
  parts = concat(parts, match, 1);
@@ -26169,7 +26166,7 @@ function dateFilter($locale) {
26169
26166
  date = new Date(date.getTime());
26170
26167
  date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
26171
26168
  }
26172
- forEach(parts, function(value){
26169
+ forEach(parts, function(value) {
26173
26170
  fn = DATE_FORMATS[value];
26174
26171
  text += fn ? fn(date, $locale.DATETIME_FORMATS)
26175
26172
  : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
@@ -26322,7 +26319,7 @@ var uppercaseFilter = valueFn(uppercase);
26322
26319
  </file>
26323
26320
  </example>
26324
26321
  */
26325
- function limitToFilter(){
26322
+ function limitToFilter() {
26326
26323
  return function(input, limit) {
26327
26324
  if (isNumber(input)) input = input.toString();
26328
26325
  if (!isArray(input) && !isString(input)) return input;
@@ -26483,42 +26480,42 @@ function limitToFilter(){
26483
26480
  </example>
26484
26481
  */
26485
26482
  orderByFilter.$inject = ['$parse'];
26486
- function orderByFilter($parse){
26483
+ function orderByFilter($parse) {
26487
26484
  return function(array, sortPredicate, reverseOrder) {
26488
26485
  if (!(isArrayLike(array))) return array;
26489
26486
  sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
26490
26487
  if (sortPredicate.length === 0) { sortPredicate = ['+']; }
26491
- sortPredicate = sortPredicate.map(function(predicate){
26488
+ sortPredicate = sortPredicate.map(function(predicate) {
26492
26489
  var descending = false, get = predicate || identity;
26493
26490
  if (isString(predicate)) {
26494
26491
  if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) {
26495
26492
  descending = predicate.charAt(0) == '-';
26496
26493
  predicate = predicate.substring(1);
26497
26494
  }
26498
- if ( predicate === '' ) {
26495
+ if (predicate === '') {
26499
26496
  // Effectively no predicate was passed so we compare identity
26500
- return reverseComparator(function(a,b) {
26497
+ return reverseComparator(function(a, b) {
26501
26498
  return compare(a, b);
26502
26499
  }, descending);
26503
26500
  }
26504
26501
  get = $parse(predicate);
26505
26502
  if (get.constant) {
26506
26503
  var key = get();
26507
- return reverseComparator(function(a,b) {
26504
+ return reverseComparator(function(a, b) {
26508
26505
  return compare(a[key], b[key]);
26509
26506
  }, descending);
26510
26507
  }
26511
26508
  }
26512
- return reverseComparator(function(a,b){
26509
+ return reverseComparator(function(a, b) {
26513
26510
  return compare(get(a),get(b));
26514
26511
  }, descending);
26515
26512
  });
26516
26513
  var arrayCopy = [];
26517
- for ( var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); }
26514
+ for (var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); }
26518
26515
  return arrayCopy.sort(reverseComparator(comparator, reverseOrder));
26519
26516
 
26520
- function comparator(o1, o2){
26521
- for ( var i = 0; i < sortPredicate.length; i++) {
26517
+ function comparator(o1, o2) {
26518
+ for (var i = 0; i < sortPredicate.length; i++) {
26522
26519
  var comp = sortPredicate[i](o1, o2);
26523
26520
  if (comp !== 0) return comp;
26524
26521
  }
@@ -26526,10 +26523,10 @@ function orderByFilter($parse){
26526
26523
  }
26527
26524
  function reverseComparator(comp, descending) {
26528
26525
  return descending
26529
- ? function(a,b){return comp(b,a);}
26526
+ ? function(a, b) {return comp(b,a);}
26530
26527
  : comp;
26531
26528
  }
26532
- function compare(v1, v2){
26529
+ function compare(v1, v2) {
26533
26530
  var t1 = typeof v1;
26534
26531
  var t2 = typeof v2;
26535
26532
  if (t1 == t2) {
@@ -26581,7 +26578,7 @@ var htmlAnchorDirective = valueFn({
26581
26578
  // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
26582
26579
  var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
26583
26580
  'xlink:href' : 'href';
26584
- element.on('click', function(event){
26581
+ element.on('click', function(event) {
26585
26582
  // if we have no href url, then don't navigate anywhere.
26586
26583
  if (!element.attr(href)) {
26587
26584
  event.preventDefault();
@@ -27060,6 +27057,11 @@ function nullFormRenameControl(control, name) {
27060
27057
  * - `pattern`
27061
27058
  * - `required`
27062
27059
  * - `url`
27060
+ * - `date`
27061
+ * - `datetimelocal`
27062
+ * - `time`
27063
+ * - `week`
27064
+ * - `month`
27063
27065
  *
27064
27066
  * @description
27065
27067
  * `FormController` keeps track of all its controls and nested forms as well as the state of them,
@@ -27248,7 +27250,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
27248
27250
  * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
27249
27251
  * saving or resetting it.
27250
27252
  */
27251
- form.$setPristine = function () {
27253
+ form.$setPristine = function() {
27252
27254
  $animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
27253
27255
  form.$dirty = false;
27254
27256
  form.$pristine = true;
@@ -27271,7 +27273,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
27271
27273
  * Setting a form controls back to their untouched state is often useful when setting the form
27272
27274
  * back to its pristine state.
27273
27275
  */
27274
- form.$setUntouched = function () {
27276
+ form.$setUntouched = function() {
27275
27277
  forEach(controls, function(control) {
27276
27278
  control.$setUntouched();
27277
27279
  });
@@ -27284,7 +27286,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
27284
27286
  * @description
27285
27287
  * Sets the form to its submitted state.
27286
27288
  */
27287
- form.$setSubmitted = function () {
27289
+ form.$setSubmitted = function() {
27288
27290
  $animate.addClass(element, SUBMITTED_CLASS);
27289
27291
  form.$submitted = true;
27290
27292
  parentForm.$setSubmitted();
@@ -27561,7 +27563,6 @@ var inputType = {
27561
27563
  * @description
27562
27564
  * Standard HTML text input with angular data binding, inherited by most of the `input` elements.
27563
27565
  *
27564
- * *NOTE* Not every feature offered is available for all input types.
27565
27566
  *
27566
27567
  * @param {string} ngModel Assignable angular expression to data-bind to.
27567
27568
  * @param {string=} name Property name of the form under which the control is published.
@@ -27645,7 +27646,10 @@ var inputType = {
27645
27646
  * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601
27646
27647
  * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many
27647
27648
  * modern browsers do not yet support this input type, it is important to provide cues to users on the
27648
- * expected input format via a placeholder or label. The model must always be a Date object.
27649
+ * expected input format via a placeholder or label.
27650
+ *
27651
+ * The model must always be a Date object, otherwise Angular will throw an error.
27652
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
27649
27653
  *
27650
27654
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
27651
27655
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -27733,7 +27737,10 @@ var inputType = {
27733
27737
  * @description
27734
27738
  * Input with datetime validation and transformation. In browsers that do not yet support
27735
27739
  * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
27736
- * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`. The model must be a Date object.
27740
+ * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.
27741
+ *
27742
+ * The model must always be a Date object, otherwise Angular will throw an error.
27743
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
27737
27744
  *
27738
27745
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
27739
27746
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -27824,6 +27831,9 @@ var inputType = {
27824
27831
  * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a
27825
27832
  * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.
27826
27833
  *
27834
+ * The model must always be a Date object, otherwise Angular will throw an error.
27835
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
27836
+ *
27827
27837
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
27828
27838
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
27829
27839
  *
@@ -27910,7 +27920,10 @@ var inputType = {
27910
27920
  * @description
27911
27921
  * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support
27912
27922
  * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
27913
- * week format (yyyy-W##), for example: `2013-W02`. The model must always be a Date object.
27923
+ * week format (yyyy-W##), for example: `2013-W02`.
27924
+ *
27925
+ * The model must always be a Date object, otherwise Angular will throw an error.
27926
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
27914
27927
  *
27915
27928
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
27916
27929
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -27996,8 +28009,12 @@ var inputType = {
27996
28009
  * @description
27997
28010
  * Input with month validation and transformation. In browsers that do not yet support
27998
28011
  * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
27999
- * month format (yyyy-MM), for example: `2009-01`. The model must always be a Date object. In the event the model is
28000
- * not set to the first of the month, the first of that model's month is assumed.
28012
+ * month format (yyyy-MM), for example: `2009-01`.
28013
+ *
28014
+ * The model must always be a Date object, otherwise Angular will throw an error.
28015
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
28016
+ * If the model is not set to the first of the month, the next view to model update will set it
28017
+ * to the first of the month.
28001
28018
  *
28002
28019
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
28003
28020
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -28086,6 +28103,8 @@ var inputType = {
28086
28103
  * Text input with number validation and transformation. Sets the `number` validation
28087
28104
  * error if not a valid number.
28088
28105
  *
28106
+ * The model must always be a number, otherwise Angular will throw an error.
28107
+ *
28089
28108
  * @param {string} ngModel Assignable angular expression to data-bind to.
28090
28109
  * @param {string=} name Property name of the form under which the control is published.
28091
28110
  * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
@@ -28164,6 +28183,12 @@ var inputType = {
28164
28183
  * Text input with URL validation. Sets the `url` validation error key if the content is not a
28165
28184
  * valid URL.
28166
28185
  *
28186
+ * <div class="alert alert-warning">
28187
+ * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex
28188
+ * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify
28189
+ * the built-in validators (see the {@link guide/forms Forms guide})
28190
+ * </div>
28191
+ *
28167
28192
  * @param {string} ngModel Assignable angular expression to data-bind to.
28168
28193
  * @param {string=} name Property name of the form under which the control is published.
28169
28194
  * @param {string=} required Sets `required` validation error key if the value is not entered.
@@ -28241,6 +28266,12 @@ var inputType = {
28241
28266
  * Text input with email validation. Sets the `email` validation error key if not a valid email
28242
28267
  * address.
28243
28268
  *
28269
+ * <div class="alert alert-warning">
28270
+ * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex
28271
+ * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can
28272
+ * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})
28273
+ * </div>
28274
+ *
28244
28275
  * @param {string} ngModel Assignable angular expression to data-bind to.
28245
28276
  * @param {string=} name Property name of the form under which the control is published.
28246
28277
  * @param {string=} required Sets `required` validation error key if the value is not entered.
@@ -28419,19 +28450,6 @@ var inputType = {
28419
28450
  'file': noop
28420
28451
  };
28421
28452
 
28422
- function testFlags(validity, flags) {
28423
- var i, flag;
28424
- if (flags) {
28425
- for (i=0; i<flags.length; ++i) {
28426
- flag = flags[i];
28427
- if (validity[flag]) {
28428
- return true;
28429
- }
28430
- }
28431
- }
28432
- return false;
28433
- }
28434
-
28435
28453
  function stringBasedInputType(ctrl) {
28436
28454
  ctrl.$formatters.push(function(value) {
28437
28455
  return ctrl.$isEmpty(value) ? value : value.toString();
@@ -28444,7 +28462,6 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28444
28462
  }
28445
28463
 
28446
28464
  function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28447
- var validity = element.prop(VALIDITY_STATE_PROPERTY);
28448
28465
  var placeholder = element[0].placeholder, noevent = {};
28449
28466
  var type = lowercase(element[0].type);
28450
28467
 
@@ -28881,10 +28898,14 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
28881
28898
  * @restrict E
28882
28899
  *
28883
28900
  * @description
28884
- * HTML input element control with angular data-binding. Input control follows HTML5 input types
28885
- * and polyfills the HTML5 validation behavior for older browsers.
28901
+ * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,
28902
+ * input state control, and validation.
28903
+ * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.
28886
28904
  *
28887
- * *NOTE* Not every feature offered is available for all input types.
28905
+ * <div class="alert alert-warning">
28906
+ * **Note:** Not every feature offered is available for all input types.
28907
+ * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.
28908
+ * </div>
28888
28909
  *
28889
28910
  * @param {string} ngModel Assignable angular expression to data-bind to.
28890
28911
  * @param {string=} name Property name of the form under which the control is published.
@@ -29020,19 +29041,20 @@ var VALID_CLASS = 'ng-valid',
29020
29041
  * @name ngModel.NgModelController
29021
29042
  *
29022
29043
  * @property {string} $viewValue Actual string value in the view.
29023
- * @property {*} $modelValue The value in the model, that the control is bound to.
29044
+ * @property {*} $modelValue The value in the model that the control is bound to.
29024
29045
  * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
29025
- the control reads value from the DOM. Each function is called, in turn, passing the value
29026
- through to the next. The last return value is used to populate the model.
29027
- Used to sanitize / convert the value as well as validation. For validation,
29028
- the parsers should update the validity state using
29029
- {@link ngModel.NgModelController#$setValidity $setValidity()},
29030
- and return `undefined` for invalid values.
29046
+ the control reads value from the DOM. The functions are called in array order, each passing the value
29047
+ through to the next. The last return value is forwarded to the $validators collection.
29048
+ Used to sanitize / convert the value.
29049
+ Returning undefined from a parser means a parse error occurred. No $validators will
29050
+ run and the 'ngModel' will not be updated until the parse error is resolved. The parse error is stored
29051
+ in 'ngModel.$error.parse'.
29031
29052
 
29032
29053
  *
29033
29054
  * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
29034
- the model value changes. Each function is called, in turn, passing the value through to the
29035
- next. Used to format / convert values for display in the control and validation.
29055
+ the model value changes. The functions are called in reverse array order, each passing the value through to the
29056
+ next. The last return value is used as the actual DOM value.
29057
+ Used to format / convert values for display in the control.
29036
29058
  * ```js
29037
29059
  * function formatter(value) {
29038
29060
  * if (value) {
@@ -29063,8 +29085,9 @@ var VALID_CLASS = 'ng-valid',
29063
29085
  * is expected to return a promise when it is run during the model validation process. Once the promise
29064
29086
  * is delivered then the validation status will be set to true when fulfilled and false when rejected.
29065
29087
  * When the asynchronous validators are triggered, each of the validators will run in parallel and the model
29066
- * value will only be updated once all validators have been fulfilled. Also, keep in mind that all
29067
- * asynchronous validators will only run once all synchronous validators have passed.
29088
+ * value will only be updated once all validators have been fulfilled. As long as an asynchronous validator
29089
+ * is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators
29090
+ * will only run once all synchronous validators have passed.
29068
29091
  *
29069
29092
  * Please note that if $http is used then it is important that the server returns a success HTTP response code
29070
29093
  * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.
@@ -29120,7 +29143,7 @@ var VALID_CLASS = 'ng-valid',
29120
29143
  *
29121
29144
  * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
29122
29145
  * module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
29123
- * However, as we are using `$sce` the model can still decide to to provide unsafe content if it marks
29146
+ * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks
29124
29147
  * that content using the `$sce` service.
29125
29148
  *
29126
29149
  * <example name="NgModelController" module="customControl" deps="angular-sanitize.js">
@@ -29307,19 +29330,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29307
29330
  * @name ngModel.NgModelController#$setValidity
29308
29331
  *
29309
29332
  * @description
29310
- * Change the validity state, and notifies the form.
29333
+ * Change the validity state, and notify the form.
29311
29334
  *
29312
- * This method can be called within $parsers/$formatters. However, if possible, please use the
29313
- * `ngModel.$validators` pipeline which is designed to call this method automatically.
29335
+ * This method can be called within $parsers/$formatters or a custom validation implementation.
29336
+ * However, in most cases it should be sufficient to use the `ngModel.$validators` and
29337
+ * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.
29314
29338
  *
29315
- * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign
29316
- * to `$error[validationErrorKey]` and `$pending[validationErrorKey]`
29317
- * so that it is available for data-binding.
29339
+ * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned
29340
+ * to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`
29341
+ * (for unfulfilled `$asyncValidators`), so that it is available for data-binding.
29318
29342
  * The `validationErrorKey` should be in camelCase and will get converted into dash-case
29319
29343
  * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
29320
29344
  * class and can be bound to as `{{someForm.someControl.$error.myError}}` .
29321
29345
  * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),
29322
- * or skipped (null).
29346
+ * or skipped (null). Pending is used for unfulfilled `$asyncValidators`.
29347
+ * Skipped is used by Angular when validators do not run because of parse errors and
29348
+ * when `$asyncValidators` do not run because any of the `$validators` failed.
29323
29349
  */
29324
29350
  addSetValidityMethod({
29325
29351
  ctrl: this,
@@ -29345,7 +29371,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29345
29371
  * state (ng-pristine class). A model is considered to be pristine when the model has not been changed
29346
29372
  * from when first compiled within then form.
29347
29373
  */
29348
- this.$setPristine = function () {
29374
+ this.$setPristine = function() {
29349
29375
  ctrl.$dirty = false;
29350
29376
  ctrl.$pristine = true;
29351
29377
  $animate.removeClass($element, DIRTY_CLASS);
@@ -29414,13 +29440,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29414
29440
  * angular.module('cancel-update-example', [])
29415
29441
  *
29416
29442
  * .controller('CancelUpdateController', ['$scope', function($scope) {
29417
- * $scope.resetWithCancel = function (e) {
29443
+ * $scope.resetWithCancel = function(e) {
29418
29444
  * if (e.keyCode == 27) {
29419
29445
  * $scope.myForm.myInput1.$rollbackViewValue();
29420
29446
  * $scope.myValue = '';
29421
29447
  * }
29422
29448
  * };
29423
- * $scope.resetWithoutCancel = function (e) {
29449
+ * $scope.resetWithoutCancel = function(e) {
29424
29450
  * if (e.keyCode == 27) {
29425
29451
  * $scope.myValue = '';
29426
29452
  * }
@@ -29599,7 +29625,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29599
29625
  var parserValid = isUndefined(modelValue) ? undefined : true;
29600
29626
 
29601
29627
  if (parserValid) {
29602
- for(var i = 0; i < ctrl.$parsers.length; i++) {
29628
+ for (var i = 0; i < ctrl.$parsers.length; i++) {
29603
29629
  modelValue = ctrl.$parsers[i](modelValue);
29604
29630
  if (isUndefined(modelValue)) {
29605
29631
  parserValid = false;
@@ -29640,7 +29666,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29640
29666
  forEach(ctrl.$viewChangeListeners, function(listener) {
29641
29667
  try {
29642
29668
  listener();
29643
- } catch(e) {
29669
+ } catch (e) {
29644
29670
  $exceptionHandler(e);
29645
29671
  }
29646
29672
  });
@@ -29743,7 +29769,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29743
29769
  idx = formatters.length;
29744
29770
 
29745
29771
  var viewValue = modelValue;
29746
- while(idx--) {
29772
+ while (idx--) {
29747
29773
  viewValue = formatters[idx](viewValue);
29748
29774
  }
29749
29775
  if (ctrl.$viewValue !== viewValue) {
@@ -29764,6 +29790,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29764
29790
  * @name ngModel
29765
29791
  *
29766
29792
  * @element input
29793
+ * @priority 1
29767
29794
  *
29768
29795
  * @description
29769
29796
  * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a
@@ -29785,7 +29812,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29785
29812
  *
29786
29813
  * For best practices on using `ngModel`, see:
29787
29814
  *
29788
- * - [https://github.com/angular/angular.js/wiki/Understanding-Scopes]
29815
+ * - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)
29789
29816
  *
29790
29817
  * For basic examples, how to use `ngModel`, see:
29791
29818
  *
@@ -29808,10 +29835,15 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29808
29835
  * The following CSS classes are added and removed on the associated input/select/textarea element
29809
29836
  * depending on the validity of the model.
29810
29837
  *
29811
- * - `ng-valid` is set if the model is valid.
29812
- * - `ng-invalid` is set if the model is invalid.
29813
- * - `ng-pristine` is set if the model is pristine.
29814
- * - `ng-dirty` is set if the model is dirty.
29838
+ * - `ng-valid`: the model is valid
29839
+ * - `ng-invalid`: the model is invalid
29840
+ * - `ng-valid-[key]`: for each valid key added by `$setValidity`
29841
+ * - `ng-invalid-[key]`: for each invalid key added by `$setValidity`
29842
+ * - `ng-pristine`: the control hasn't been interacted with yet
29843
+ * - `ng-dirty`: the control has been interacted with
29844
+ * - `ng-touched`: the control has been blurred
29845
+ * - `ng-untouched`: the control hasn't been blurred
29846
+ * - `ng-pending`: any `$asyncValidators` are unfulfilled
29815
29847
  *
29816
29848
  * Keep in mind that ngAnimate can detect each of these classes when added and removed.
29817
29849
  *
@@ -29905,7 +29937,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29905
29937
  .controller('ExampleController', ['$scope', function($scope) {
29906
29938
  var _name = 'Brian';
29907
29939
  $scope.user = {
29908
- name: function (newName) {
29940
+ name: function(newName) {
29909
29941
  if (angular.isDefined(newName)) {
29910
29942
  _name = newName;
29911
29943
  }
@@ -30272,9 +30304,9 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
30272
30304
  * @name ngValue
30273
30305
  *
30274
30306
  * @description
30275
- * Binds the given expression to the value of `input[select]` or `input[radio]`, so
30276
- * that when the element is selected, the `ngModel` of that element is set to the
30277
- * bound value.
30307
+ * Binds the given expression to the value of `option` or `input[radio]`, so
30308
+ * that when the element is selected, the `ngModel` of that element is set to
30309
+ * the bound value.
30278
30310
  *
30279
30311
  * `ngValue` is useful when dynamically generating lists of radio buttons using `ng-repeat`, as
30280
30312
  * shown below.
@@ -30407,7 +30439,7 @@ var ngValueDirective = function() {
30407
30439
  .controller('ExampleController', ['$scope', function($scope) {
30408
30440
  $scope.user = { name: 'say', data: '' };
30409
30441
 
30410
- $scope.cancel = function (e) {
30442
+ $scope.cancel = function(e) {
30411
30443
  if (e.keyCode == 27) {
30412
30444
  $scope.userForm.userName.$rollbackViewValue();
30413
30445
  }
@@ -30481,7 +30513,7 @@ var ngValueDirective = function() {
30481
30513
  .controller('ExampleController', ['$scope', function($scope) {
30482
30514
  var _name = 'Brian';
30483
30515
  $scope.user = {
30484
- name: function (newName) {
30516
+ name: function(newName) {
30485
30517
  return angular.isDefined(newName) ? (_name = newName) : _name;
30486
30518
  }
30487
30519
  };
@@ -30704,7 +30736,7 @@ var ngBindDirective = ['$compile', function($compile) {
30704
30736
  <file name="index.html">
30705
30737
  <script>
30706
30738
  angular.module('bindExample', [])
30707
- .controller('ExampleController', ['$scope', function ($scope) {
30739
+ .controller('ExampleController', ['$scope', function($scope) {
30708
30740
  $scope.salutation = 'Hello';
30709
30741
  $scope.name = 'World';
30710
30742
  }]);
@@ -30859,10 +30891,10 @@ function classDirective(name, selector) {
30859
30891
  attr.$removeClass(newClasses);
30860
30892
  }
30861
30893
 
30862
- function digestClassCounts (classes, count) {
30894
+ function digestClassCounts(classes, count) {
30863
30895
  var classCounts = element.data('$classCounts') || {};
30864
30896
  var classesToUpdate = [];
30865
- forEach(classes, function (className) {
30897
+ forEach(classes, function(className) {
30866
30898
  if (count > 0 || classCounts[className]) {
30867
30899
  classCounts[className] = (classCounts[className] || 0) + count;
30868
30900
  if (classCounts[className] === +(count > 0)) {
@@ -30874,7 +30906,7 @@ function classDirective(name, selector) {
30874
30906
  return classesToUpdate.join(' ');
30875
30907
  }
30876
30908
 
30877
- function updateClasses (oldClasses, newClasses) {
30909
+ function updateClasses(oldClasses, newClasses) {
30878
30910
  var toAdd = arrayDifference(newClasses, oldClasses);
30879
30911
  var toRemove = arrayDifference(oldClasses, newClasses);
30880
30912
  toAdd = digestClassCounts(toAdd, 1);
@@ -30906,23 +30938,23 @@ function classDirective(name, selector) {
30906
30938
  var values = [];
30907
30939
 
30908
30940
  outer:
30909
- for(var i = 0; i < tokens1.length; i++) {
30941
+ for (var i = 0; i < tokens1.length; i++) {
30910
30942
  var token = tokens1[i];
30911
- for(var j = 0; j < tokens2.length; j++) {
30912
- if(token == tokens2[j]) continue outer;
30943
+ for (var j = 0; j < tokens2.length; j++) {
30944
+ if (token == tokens2[j]) continue outer;
30913
30945
  }
30914
30946
  values.push(token);
30915
30947
  }
30916
30948
  return values;
30917
30949
  }
30918
30950
 
30919
- function arrayClasses (classVal) {
30951
+ function arrayClasses(classVal) {
30920
30952
  if (isArray(classVal)) {
30921
30953
  return classVal;
30922
30954
  } else if (isString(classVal)) {
30923
30955
  return classVal.split(' ');
30924
30956
  } else if (isObject(classVal)) {
30925
- var classes = [], i = 0;
30957
+ var classes = [];
30926
30958
  forEach(classVal, function(v, k) {
30927
30959
  if (v) {
30928
30960
  classes = classes.concat(k.split(' '));
@@ -31681,10 +31713,8 @@ var ngControllerDirective = [function() {
31681
31713
  </example>
31682
31714
  */
31683
31715
  /*
31684
- * A directive that allows creation of custom onclick handlers that are defined as angular
31685
- * expressions and are compiled and executed within the current scope.
31686
- *
31687
- * Events that are handled via these handler are always configured not to propagate further.
31716
+ * A collection of directives that allows creation of custom event handlers that are defined as
31717
+ * angular expressions and are compiled and executed within the current scope.
31688
31718
  */
31689
31719
  var ngEventDirectives = {};
31690
31720
 
@@ -32214,13 +32244,13 @@ var ngIfDirective = ['$animate', function($animate) {
32214
32244
  terminal: true,
32215
32245
  restrict: 'A',
32216
32246
  $$tlb: true,
32217
- link: function ($scope, $element, $attr, ctrl, $transclude) {
32247
+ link: function($scope, $element, $attr, ctrl, $transclude) {
32218
32248
  var block, childScope, previousElements;
32219
32249
  $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
32220
32250
 
32221
32251
  if (value) {
32222
32252
  if (!childScope) {
32223
- $transclude(function (clone, newScope) {
32253
+ $transclude(function(clone, newScope) {
32224
32254
  childScope = newScope;
32225
32255
  clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
32226
32256
  // Note: We only need the first/last node of the cloned nodes.
@@ -32452,15 +32482,15 @@ var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', '$sce
32452
32482
  currentElement;
32453
32483
 
32454
32484
  var cleanupLastIncludeContent = function() {
32455
- if(previousElement) {
32485
+ if (previousElement) {
32456
32486
  previousElement.remove();
32457
32487
  previousElement = null;
32458
32488
  }
32459
- if(currentScope) {
32489
+ if (currentScope) {
32460
32490
  currentScope.$destroy();
32461
32491
  currentScope = null;
32462
32492
  }
32463
- if(currentElement) {
32493
+ if (currentElement) {
32464
32494
  $animate.leave(currentElement).then(function() {
32465
32495
  previousElement = null;
32466
32496
  });
@@ -33143,10 +33173,10 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
33143
33173
  if (trackByExp) {
33144
33174
  trackByExpGetter = $parse(trackByExp);
33145
33175
  } else {
33146
- trackByIdArrayFn = function (key, value) {
33176
+ trackByIdArrayFn = function(key, value) {
33147
33177
  return hashKey(value);
33148
33178
  };
33149
- trackByIdObjFn = function (key) {
33179
+ trackByIdObjFn = function(key) {
33150
33180
  return key;
33151
33181
  };
33152
33182
  }
@@ -33226,7 +33256,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
33226
33256
  nextBlockOrder[index] = block;
33227
33257
  } else if (nextBlockMap[trackById]) {
33228
33258
  // if collision detected. restore lastBlockMap and throw an error
33229
- forEach(nextBlockOrder, function (block) {
33259
+ forEach(nextBlockOrder, function(block) {
33230
33260
  if (block && block.scope) lastBlockMap[block.id] = block;
33231
33261
  });
33232
33262
  throw ngRepeatMinErr('dupes',
@@ -33416,7 +33446,7 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
33416
33446
  </div>
33417
33447
  </file>
33418
33448
  <file name="glyphicons.css">
33419
- @import url(//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css);
33449
+ @import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
33420
33450
  </file>
33421
33451
  <file name="animations.css">
33422
33452
  .animate-show {
@@ -33466,13 +33496,13 @@ var ngShowDirective = ['$animate', function($animate) {
33466
33496
  restrict: 'A',
33467
33497
  multiElement: true,
33468
33498
  link: function(scope, element, attr) {
33469
- scope.$watch(attr.ngShow, function ngShowWatchAction(value){
33499
+ scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
33470
33500
  // we're adding a temporary, animation-specific class for ng-hide since this way
33471
33501
  // we can control when the element is actually displayed on screen without having
33472
33502
  // to have a global/greedy CSS selector that breaks when other animations are run.
33473
33503
  // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
33474
33504
  $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
33475
- tempClasses : NG_HIDE_IN_PROGRESS_CLASS
33505
+ tempClasses: NG_HIDE_IN_PROGRESS_CLASS
33476
33506
  });
33477
33507
  });
33478
33508
  }
@@ -33581,7 +33611,7 @@ var ngShowDirective = ['$animate', function($animate) {
33581
33611
  </div>
33582
33612
  </file>
33583
33613
  <file name="glyphicons.css">
33584
- @import url(//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css);
33614
+ @import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
33585
33615
  </file>
33586
33616
  <file name="animations.css">
33587
33617
  .animate-hide {
@@ -33627,11 +33657,11 @@ var ngHideDirective = ['$animate', function($animate) {
33627
33657
  restrict: 'A',
33628
33658
  multiElement: true,
33629
33659
  link: function(scope, element, attr) {
33630
- scope.$watch(attr.ngHide, function ngHideWatchAction(value){
33660
+ scope.$watch(attr.ngHide, function ngHideWatchAction(value) {
33631
33661
  // The comment inside of the ngShowDirective explains why we add and
33632
33662
  // remove a temporary class for the show/hide animation
33633
33663
  $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
33634
- tempClasses : NG_HIDE_IN_PROGRESS_CLASS
33664
+ tempClasses: NG_HIDE_IN_PROGRESS_CLASS
33635
33665
  });
33636
33666
  });
33637
33667
  }
@@ -34034,34 +34064,37 @@ var ngOptionsMinErr = minErr('ngOptions');
34034
34064
  * elements for the `<select>` element using the array or object obtained by evaluating the
34035
34065
  * `ngOptions` comprehension_expression.
34036
34066
  *
34067
+ * In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
34068
+ * similar result. However, the `ngOptions` provides some benefits such as reducing memory and
34069
+ * increasing speed by not creating a new scope for each repeated instance, as well as providing
34070
+ * more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions should be
34071
+ * used when the `select` model needs to be bound to a non-string value. This is because an option
34072
+ * element can only be bound to string values at present.
34073
+ *
34037
34074
  * When an item in the `<select>` menu is selected, the array element or object property
34038
34075
  * represented by the selected option will be bound to the model identified by the `ngModel`
34039
34076
  * directive.
34040
34077
  *
34041
- * <div class="alert alert-warning">
34042
- * **Note:** `ngModel` compares by reference, not value. This is important when binding to an
34043
- * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
34044
- * </div>
34045
- *
34046
34078
  * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
34047
34079
  * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
34048
34080
  * option. See example below for demonstration.
34049
34081
  *
34050
34082
  * <div class="alert alert-warning">
34051
- * **Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
34052
- * of {@link ng.directive:ngRepeat ngRepeat} when you want the
34053
- * `select` model to be bound to a non-string value. This is because an option element can only
34054
- * be bound to string values at present.
34083
+ * **Note:** `ngModel` compares by reference, not value. This is important when binding to an
34084
+ * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
34055
34085
  * </div>
34056
34086
  *
34057
- * <div class="alert alert-info">
34058
- * **Note:** Using `select as` will bind the result of the `select as` expression to the model, but
34087
+ * ## `select as`
34088
+ *
34089
+ * Using `select as` will bind the result of the `select as` expression to the model, but
34059
34090
  * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
34060
- * or property name (for object data sources) of the value within the collection.
34061
- * </div>
34091
+ * or property name (for object data sources) of the value within the collection. If a `track by` expression
34092
+ * is used, the result of that expression will be set as the value of the `option` and `select` elements.
34093
+ *
34094
+ * ### `select as` with `trackexpr`
34095
+ *
34096
+ * Using `select as` together with `trackexpr` is not recommended. Reasoning:
34062
34097
  *
34063
- * **Note:** Using `select as` together with `trackexpr` is not recommended.
34064
- * Reasoning:
34065
34098
  * - Example: &lt;select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected"&gt;
34066
34099
  * values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}],
34067
34100
  * $scope.selected = {name: 'aSubItem'};
@@ -34272,7 +34305,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34272
34305
  unknownOption = optionTemplate.clone();
34273
34306
 
34274
34307
  // find "null" option
34275
- for(var i = 0, children = element.children(), ii = children.length; i < ii; i++) {
34308
+ for (var i = 0, children = element.children(), ii = children.length; i < ii; i++) {
34276
34309
  if (children[i].value === '') {
34277
34310
  emptyOption = nullOption = children.eq(i);
34278
34311
  break;
@@ -34374,6 +34407,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34374
34407
  valuesFn = $parse(match[7]),
34375
34408
  track = match[8],
34376
34409
  trackFn = track ? $parse(match[8]) : null,
34410
+ trackKeysCache = {},
34377
34411
  // This is an array of array of existing option groups in DOM.
34378
34412
  // We try to reuse these if possible
34379
34413
  // - optionGroupsCache[0] is the options with no option group
@@ -34419,17 +34453,16 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34419
34453
 
34420
34454
  function selectionChanged() {
34421
34455
  scope.$apply(function() {
34422
- var optionGroup,
34423
- collection = valuesFn(scope) || [],
34424
- key, value, optionElement, index, groupIndex, length, groupLength, trackIndex;
34456
+ var collection = valuesFn(scope) || [];
34425
34457
  var viewValue;
34426
34458
  if (multiple) {
34427
34459
  viewValue = [];
34428
34460
  forEach(selectElement.val(), function(selectedKey) {
34461
+ selectedKey = trackFn ? trackKeysCache[selectedKey] : selectedKey;
34429
34462
  viewValue.push(getViewValue(selectedKey, collection[selectedKey]));
34430
34463
  });
34431
34464
  } else {
34432
- var selectedKey = selectElement.val();
34465
+ var selectedKey = trackFn ? trackKeysCache[selectElement.val()] : selectElement.val();
34433
34466
  viewValue = getViewValue(selectedKey, collection[selectedKey]);
34434
34467
  }
34435
34468
  ctrl.$setViewValue(viewValue);
@@ -34551,14 +34584,17 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34551
34584
  anySelected = false,
34552
34585
  lastElement,
34553
34586
  element,
34554
- label;
34587
+ label,
34588
+ optionId;
34589
+
34590
+ trackKeysCache = {};
34555
34591
 
34556
34592
  // We now build up the list of options we need (we merge later)
34557
34593
  for (index = 0; length = keys.length, index < length; index++) {
34558
34594
  key = index;
34559
34595
  if (keyName) {
34560
34596
  key = keys[index];
34561
- if ( key.charAt(0) === '$' ) continue;
34597
+ if (key.charAt(0) === '$') continue;
34562
34598
  }
34563
34599
  value = values[key];
34564
34600
 
@@ -34575,9 +34611,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34575
34611
 
34576
34612
  // doing displayFn(scope, locals) || '' overwrites zero values
34577
34613
  label = isDefined(label) ? label : '';
34614
+ optionId = trackFn ? trackFn(scope, locals) : (keyName ? keys[index] : index);
34615
+ if (trackFn) {
34616
+ trackKeysCache[optionId] = key;
34617
+ }
34618
+
34578
34619
  optionGroup.push({
34579
34620
  // either the index into array or key from object
34580
- id: (keyName ? keys[index] : index),
34621
+ id: optionId,
34581
34622
  label: label,
34582
34623
  selected: selected // determine if we should be selected
34583
34624
  });
@@ -34622,7 +34663,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34622
34663
  }
34623
34664
 
34624
34665
  lastElement = null; // start at the beginning
34625
- for(index = 0, length = optionGroup.length; index < length; index++) {
34666
+ for (index = 0, length = optionGroup.length; index < length; index++) {
34626
34667
  option = optionGroup[index];
34627
34668
  if ((existingOption = existingOptions[index+1])) {
34628
34669
  // reuse elements
@@ -34680,12 +34721,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34680
34721
  }
34681
34722
  // remove any excessive OPTIONs in a group
34682
34723
  index++; // increment since the existingOptions[0] is parent element not OPTION
34683
- while(existingOptions.length > index) {
34724
+ while (existingOptions.length > index) {
34684
34725
  option = existingOptions.pop();
34685
34726
  updateLabelMap(labelMap, option.label, false);
34686
34727
  option.element.remove();
34687
34728
  }
34688
- forEach(labelMap, function (count, label) {
34729
+ forEach(labelMap, function(count, label) {
34689
34730
  if (count > 0) {
34690
34731
  selectCtrl.addOption(label);
34691
34732
  } else if (count < 0) {
@@ -34694,7 +34735,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34694
34735
  });
34695
34736
  }
34696
34737
  // remove any excessive OPTGROUPs from select
34697
- while(optionGroupsCache.length > groupIndex) {
34738
+ while (optionGroupsCache.length > groupIndex) {
34698
34739
  optionGroupsCache.pop()[0].element.remove();
34699
34740
  }
34700
34741
  }
@@ -34720,7 +34761,7 @@ var optionDirective = ['$interpolate', function($interpolate) {
34720
34761
  }
34721
34762
  }
34722
34763
 
34723
- return function (scope, element, attr) {
34764
+ return function(scope, element, attr) {
34724
34765
  var selectCtrlName = '$selectController',
34725
34766
  parent = element.parent(),
34726
34767
  selectCtrl = parent.data(selectCtrlName) ||
@@ -34992,7 +35033,7 @@ function callerFile(offset) {
34992
35033
  *
34993
35034
  * To work around this we instead use our own handler that fires a real event.
34994
35035
  */
34995
- (function(fn){
35036
+ (function(fn) {
34996
35037
  // We need a handle to the original trigger function for input tests.
34997
35038
  var parentTrigger = fn._originalTrigger = fn.trigger;
34998
35039
  fn.trigger = function(type) {
@@ -35022,7 +35063,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35022
35063
  bindSelector = '.ng-binding:visible';
35023
35064
  if (angular.isString(bindExp)) {
35024
35065
  bindExp = bindExp.replace(/\s/g, '');
35025
- match = function (actualExp) {
35066
+ match = function(actualExp) {
35026
35067
  if (actualExp) {
35027
35068
  actualExp = actualExp.replace(/\s/g, '');
35028
35069
  if (actualExp == bindExp) return true;
@@ -35058,7 +35099,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35058
35099
  var element = windowJquery(this),
35059
35100
  bindings;
35060
35101
  if (bindings = element.data('$binding')) {
35061
- for(var expressions = [], binding, j=0, jj=bindings.length; j<jj; j++) {
35102
+ for (var expressions = [], binding, j=0, jj=bindings.length; j<jj; j++) {
35062
35103
  binding = bindings[j];
35063
35104
 
35064
35105
  if (binding.expressions) {
@@ -35068,7 +35109,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35068
35109
  }
35069
35110
  for (var scope, expression, i = 0, ii = expressions.length; i < ii; i++) {
35070
35111
  expression = expressions[i];
35071
- if(match(expression)) {
35112
+ if (match(expression)) {
35072
35113
  scope = scope || element.scope();
35073
35114
  push(scope.$eval(expression));
35074
35115
  }
@@ -35080,12 +35121,6 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35080
35121
  };
35081
35122
 
35082
35123
  (function() {
35083
- /**
35084
- * documentMode is an IE-only property
35085
- * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
35086
- */
35087
- var msie = document.documentMode;
35088
-
35089
35124
  /**
35090
35125
  * Triggers a browser event. Attempts to choose the right event if one is
35091
35126
  * not specified.
@@ -35136,8 +35171,8 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35136
35171
  }
35137
35172
 
35138
35173
  var evnt;
35139
- if(/transitionend/.test(eventType)) {
35140
- if(window.WebKitTransitionEvent) {
35174
+ if (/transitionend/.test(eventType)) {
35175
+ if (window.WebKitTransitionEvent) {
35141
35176
  evnt = new WebKitTransitionEvent(eventType, eventData);
35142
35177
  evnt.initEvent(eventType, false, true);
35143
35178
  }
@@ -35145,14 +35180,14 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35145
35180
  try {
35146
35181
  evnt = new TransitionEvent(eventType, eventData);
35147
35182
  }
35148
- catch(e) {
35183
+ catch (e) {
35149
35184
  evnt = document.createEvent('TransitionEvent');
35150
35185
  evnt.initTransitionEvent(eventType, null, null, null, eventData.elapsedTime || 0);
35151
35186
  }
35152
35187
  }
35153
35188
  }
35154
- else if(/animationend/.test(eventType)) {
35155
- if(window.WebKitAnimationEvent) {
35189
+ else if (/animationend/.test(eventType)) {
35190
+ if (window.WebKitAnimationEvent) {
35156
35191
  evnt = new WebKitAnimationEvent(eventType, eventData);
35157
35192
  evnt.initEvent(eventType, false, true);
35158
35193
  }
@@ -35160,7 +35195,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35160
35195
  try {
35161
35196
  evnt = new AnimationEvent(eventType, eventData);
35162
35197
  }
35163
- catch(e) {
35198
+ catch (e) {
35164
35199
  evnt = document.createEvent('AnimationEvent');
35165
35200
  evnt.initAnimationEvent(eventType, null, null, null, eventData.elapsedTime || 0);
35166
35201
  }
@@ -35179,7 +35214,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35179
35214
  * read */
35180
35215
  evnt.$manualTimeStamp = eventData.timeStamp;
35181
35216
 
35182
- if(!evnt) return;
35217
+ if (!evnt) return;
35183
35218
 
35184
35219
  var originalPreventDefault = evnt.preventDefault,
35185
35220
  appWindow = element.ownerDocument.defaultView,
@@ -35316,7 +35351,7 @@ angular.scenario.Application.prototype.executeAction = function(action) {
35316
35351
  return $injector;
35317
35352
  };
35318
35353
 
35319
- $injector.invoke(function($browser){
35354
+ $injector.invoke(function($browser) {
35320
35355
  $browser.notifyWhenNoOutstandingRequests(function() {
35321
35356
  action.call(self, $window, $element);
35322
35357
  });
@@ -35506,7 +35541,7 @@ angular.scenario.Future.prototype.execute = function(doneFn) {
35506
35541
  if (result) {
35507
35542
  try {
35508
35543
  result = self.parser(result);
35509
- } catch(e) {
35544
+ } catch (e) {
35510
35545
  error = e;
35511
35546
  }
35512
35547
  }
@@ -36137,7 +36172,7 @@ angular.scenario.SpecRunner.prototype.addFutureAction = function(name, behavior,
36137
36172
  });
36138
36173
  var result = $document.find(selector);
36139
36174
  if (selector.match(NG)) {
36140
- angular.forEach(['[ng-','[data-ng-','[x-ng-'], function(value, index){
36175
+ angular.forEach(['[ng-','[data-ng-','[x-ng-'], function(value, index) {
36141
36176
  result = result.add(selector.replace(NG, value), $document);
36142
36177
  });
36143
36178
  }
@@ -36153,7 +36188,7 @@ angular.scenario.SpecRunner.prototype.addFutureAction = function(name, behavior,
36153
36188
 
36154
36189
  try {
36155
36190
  behavior.call(self, $window, $document, done);
36156
- } catch(e) {
36191
+ } catch (e) {
36157
36192
  if (e.type && e.type === 'selector') {
36158
36193
  done(e.message);
36159
36194
  } else {
@@ -36468,7 +36503,7 @@ angular.scenario.dsl('select', function() {
36468
36503
  if (option.length) {
36469
36504
  select.val(value);
36470
36505
  } else {
36471
- option = select.find('option').filter(function(){
36506
+ option = select.find('option').filter(function() {
36472
36507
  return _jQuery(this).text() === value;
36473
36508
  });
36474
36509
  if (!option.length) {