{"version":3,"sources":["webpack://aspAndWebpack/./node_modules/angular-animate/index.js","webpack://aspAndWebpack/./node_modules/angular-animate/angular-animate.js"],"names":["module","exports","window","angular","TRANSITION_PROP","TRANSITIONEND_EVENT","ANIMATION_PROP","ANIMATIONEND_EVENT","undefined","ontransitionend","onwebkittransitionend","onanimationend","onwebkitanimationend","ANIMATION_DELAY_PROP","ANIMATION_DURATION_PROP","TRANSITION_DELAY_PROP","TRANSITION_DURATION_PROP","ngMinErr","$$minErr","assertArg","arg","name","reason","mergeClasses","a","b","isArray","join","pendClasses","classes","fix","isPrefix","className","isString","length","split","forEach","klass","i","stripCommentsFromElement","element","jqLite","nodeType","extractElementNode","elm","applyAnimationClassesFactory","$$jqLite","options","addClass","$$addClass","removeClass","$$removeClass","prepareAnimationOptions","$$prepared","domOperation","noop","$$domOperationFired","applyAnimationStyles","applyAnimationFromStyles","applyAnimationToStyles","from","css","to","mergeAnimationDetails","oldAnimation","newAnimation","target","newOptions","toAdd","toRemove","existing","flags","splitClassesToLookup","value","key","obj","val","prop","allow","resolveElementClasses","attr","preparationClasses","concatWithSpace","realDomOperation","extend","getDomNode","blockKeyframeAnimations","node","applyBlock","applyInlineStyle","styleTuple","style","helpers","duration","$$AnimateChildrenDirective","$interpolate","link","scope","attrs","ngAnimateChildren","setData","data","$observe","DETECT_CSS_PROPERTIES","transitionDuration","transitionDelay","transitionProperty","animationDuration","animationDelay","animationIterationCount","DETECT_STAGGER_CSS_PROPERTIES","getCssDelayStyle","delay","isKeyframeAnimation","computeCssStyles","$window","properties","styles","Object","create","detectedStyles","getComputedStyle","formalStyleName","actualStyleName","maxValue","values","c","charAt","substring","parseFloat","Math","max","truthyTimingValue","getCssTransitionDurationStyle","applyOnlyDuration","registerRestorableStyles","backup","isDefined","getPropertyValue","copy","isElement","isFunction","isObject","isUndefined","$AnimateCssProvider","$animateProvider","this","$get","$$AnimateRunner","$timeout","$$animateCache","$$forceReflow","$sniffer","$$rAFScheduler","$$animateQueue","applyAnimationClasses","rafWaitQueue","waitUntilQuiet","callback","push","flush","pageWidth","computeTimings","cacheKey","allowNoDuration","timings","get","hasDuration","put","computeCachedCssStyles","aD","tD","maxDelay","maxDuration","initialOptions","restoreStyles","parentNode","enabled","closeAndReturnNoopAnimator","animationClosed","animationPaused","animationCompleted","runner","runnerHost","maxDelayTime","maxDurationTime","startTime","temporaryStyles","packageStyles","events","animations","transitions","method","event","isStructural","structural","structuralClassName","addRemoveClassName","applyClassesEarly","trim","hasToStyles","keys","keyframeStyle","stagger","containsCachedAnimationWithoutDuration","staggerVal","staggerCacheKey","count","staggerClassName","computeCachedCssStaggerStyles","$$skipPreparationClasses","transitionStyle","durationStyle","itemIndex","staggerIndex","isFirst","skipBlocking","fullClassName","relativeDelay","hasTransitions","hasAnimations","hasTransitionAll","applyTransitionDuration","applyAnimationDuration","applyTransitionDelay","applyAnimationDelay","recalculateTimingStyles","delayStyle","activeClasses","blockTransition","blockKeyframeAnimation","cleanupStyles","applyBlocking","$$willAnimate","end","endFn","start","cancel","cancelFn","resume","pause","close","rejected","entry","setProperty","removeProperty","onDone","off","onAnimationProgress","animationTimerData","timer","removeData","complete","stopPropagation","ev","originalEvent","timeStamp","$manualTimeStamp","Date","now","elapsedTime","toFixed","playPause","playAnimation","index","arr","indexOf","splice","maxStagger","triggerAnimationStart","floor","getAttribute","easing","easeProp","easeVal","timerTime","endTime","animationsData","setupFallbackTimer","currentTimerData","expectedEndTime","onAnimationExpired","on","$$AnimateCssDriverProvider","$$animationProvider","drivers","$animateCss","$rootScope","$rootElement","$document","bodyNode","body","rootNode","rootBodyElement","contains","animationDetails","anchors","fromAnimation","prepareRegularAnimation","toAnimation","anchorAnimations","anchor","animator","outAnchor","inAnchor","clone","cloneNode","startingClasses","filterCssClasses","getClassVal","append","animatorIn","animatorOut","calculateAnchorStyles","prepareOutAnimation","prepareInAnimation","startingAnimator","currentAnimation","done","coords","getBoundingClientRect","scrollTop","scrollLeft","endingClasses","getUniqueValues","NG_IN_ANCHOR_CLASS_NAME","NG_OUT_ANCHOR_CLASS_NAME","remove","prepareAnchoredAnimation","animationRunners","animation","all","status","prepareFromToAnchorAnimation","replace","filter","$$AnimateJsProvider","$injector","arguments","before","after","afterFn","beforeFn","classesToAdd","classesToRemove","lookupAnimations","toUpperCase","substr","packageAnimations","closeActiveAnimations","chain","fn","applyOptions","setHost","endAnimations","onComplete","success","cancelled","executeAnimationFn","args","apply","groupEventedAnimations","fnName","operations","ani","endProgressCb","resolved","onAnimationComplete","result","concat","runners","animateFn","reject","matches","flagMap","animationFactory","$$registeredAnimations","$$AnimateJsDriverProvider","$$animateJs","prepareAnimation","endFnFactory","$$AnimateQueueProvider","rules","skip","getEventData","hasMatchingClasses","newClassString","currentClassString","currentClassMap","classString","map","makeTruthyCssClassMap","some","isAllowed","ruleType","previousAnimation","hasAnimationClasses","and","state","nA","nR","cA","cR","$$rAF","$$Map","$$animation","$templateRequest","$$isDocumentHidden","activeAnimationsLookup","disabledElementsLookup","animationsEnabled","removeFromDisabledElementsLookup","evt","delete","deregisterWatch","$watch","totalPendingRequests","isEmpty","$$postDigest","callbackRegistry","customFilter","classNameFilter","returnTrue","isAnimatableByFilter","isAnimatableClassName","test","normalizeAnimationDetails","Node","prototype","compareDocumentPosition","filterFromRegistry","list","matchContainer","matchCallback","containerNode","cleanupEventListeners","phase","$animate","container","entries","eventType","pin","parentElement","originalElement","runInNextPostDigestOrNow","postDigestCalled","documentHidden","skipAnimations","existingAnimation","hasExistingAnimation","animateChildren","bodyNodeDetected","nodeName","rootNodeDetected","parentAnimationDetected","elementDisabled","parentHost","details","parentNodeDisabled","areAnimationsAllowed","notifyProgress","children","querySelectorAll","child","parseInt","closeChildAnimations","applyGeneratedPreparationClasses","isValidAnimation","clearElementAnimationState","counter","markElementAnimationState","animationCancelled","parent","realRunner","callbacks","targetParentNode","targetNode","call","findCallbacks","progress","clearGeneratedClasses","queueAnimation","bool","argCount","hasElement","has","set","removeAttribute","setAttribute","oldValue","newValue","$$AnimationProvider","getRunner","animationQueue","tempClasses","setRunner","beforeStart","prepareClassName","handleDestroyedElement","groupedAnimations","preparedAnimations","refLookup","enterOrMove","anchorNodes","items","hasAttribute","getAnchorNodes","direction","animationID","usedIndicesLookup","anchorGroups","lookupKey","toString","group","cssClassesIntersection","indexKey","groupAnimations","toBeSortedAnimations","animationEntry","extraClasses","domNode","startAnimationFn","closeFn","operation","driverName","driver","factory","invokeFirstDriver","animationRunner","newRunner","update","updateAnimationRunners","finalAnimations","tree","lookup","processNode","queue","remainingLevelEntries","nextLevelEntries","row","childEntry","flatten","processed","parentEntry","elementNode","sortAnimations","innerArray","j","aa","removeRunner","info","angularVersion","directive","restrict","transclude","terminal","priority","$element","ctrl","$transclude","previousElement","previousScope","$watchCollection","ngAnimateSwap","leave","$destroy","childScope","enter","scheduler","tasks","nextTick","shift","provider","KEY","parentCounter","cache","parts","isValid","total"],"mappings":"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","file":"npm.angular-animate.599e75afb77c31efb7a3.js","sourcesContent":["require('./angular-animate');\nmodule.exports = 'ngAnimate';\n","/**\n * @license AngularJS v1.8.3\n * (c) 2010-2020 Google LLC. http://angularjs.org\n * License: MIT\n */\n(function(window, angular) {'use strict';\n\nvar ELEMENT_NODE = 1;\nvar COMMENT_NODE = 8;\n\nvar ADD_CLASS_SUFFIX = '-add';\nvar REMOVE_CLASS_SUFFIX = '-remove';\nvar EVENT_CLASS_PREFIX = 'ng-';\nvar ACTIVE_CLASS_SUFFIX = '-active';\nvar PREPARE_CLASS_SUFFIX = '-prepare';\n\nvar NG_ANIMATE_CLASSNAME = 'ng-animate';\nvar NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';\n\n// Detect proper transitionend/animationend event names.\nvar CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;\n\n// If unprefixed events are not supported but webkit-prefixed are, use the latter.\n// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.\n// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`\n// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.\n// Register both events in case `window.onanimationend` is not supported because of that,\n// do the same for `transitionend` as Safari is likely to exhibit similar behavior.\n// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit\n// therefore there is no reason to test anymore for other vendor prefixes:\n// http://caniuse.com/#search=transition\nif ((window.ontransitionend === undefined) && (window.onwebkittransitionend !== undefined)) {\n CSS_PREFIX = '-webkit-';\n TRANSITION_PROP = 'WebkitTransition';\n TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';\n} else {\n TRANSITION_PROP = 'transition';\n TRANSITIONEND_EVENT = 'transitionend';\n}\n\nif ((window.onanimationend === undefined) && (window.onwebkitanimationend !== undefined)) {\n CSS_PREFIX = '-webkit-';\n ANIMATION_PROP = 'WebkitAnimation';\n ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';\n} else {\n ANIMATION_PROP = 'animation';\n ANIMATIONEND_EVENT = 'animationend';\n}\n\nvar DURATION_KEY = 'Duration';\nvar PROPERTY_KEY = 'Property';\nvar DELAY_KEY = 'Delay';\nvar TIMING_KEY = 'TimingFunction';\nvar ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';\nvar ANIMATION_PLAYSTATE_KEY = 'PlayState';\nvar SAFE_FAST_FORWARD_DURATION_VALUE = 9999;\n\nvar ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;\nvar ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;\nvar TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;\nvar TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;\n\nvar ngMinErr = angular.$$minErr('ng');\nfunction assertArg(arg, name, reason) {\n if (!arg) {\n throw ngMinErr('areq', 'Argument \\'{0}\\' is {1}', (name || '?'), (reason || 'required'));\n }\n return arg;\n}\n\nfunction mergeClasses(a,b) {\n if (!a && !b) return '';\n if (!a) return b;\n if (!b) return a;\n if (isArray(a)) a = a.join(' ');\n if (isArray(b)) b = b.join(' ');\n return a + ' ' + b;\n}\n\nfunction packageStyles(options) {\n var styles = {};\n if (options && (options.to || options.from)) {\n styles.to = options.to;\n styles.from = options.from;\n }\n return styles;\n}\n\nfunction pendClasses(classes, fix, isPrefix) {\n var className = '';\n classes = isArray(classes)\n ? classes\n : classes && isString(classes) && classes.length\n ? classes.split(/\\s+/)\n : [];\n forEach(classes, function(klass, i) {\n if (klass && klass.length > 0) {\n className += (i > 0) ? ' ' : '';\n className += isPrefix ? fix + klass\n : klass + fix;\n }\n });\n return className;\n}\n\nfunction removeFromArray(arr, val) {\n var index = arr.indexOf(val);\n if (val >= 0) {\n arr.splice(index, 1);\n }\n}\n\nfunction stripCommentsFromElement(element) {\n if (element instanceof jqLite) {\n switch (element.length) {\n case 0:\n return element;\n\n case 1:\n // there is no point of stripping anything if the element\n // is the only element within the jqLite wrapper.\n // (it's important that we retain the element instance.)\n if (element[0].nodeType === ELEMENT_NODE) {\n return element;\n }\n break;\n\n default:\n return jqLite(extractElementNode(element));\n }\n }\n\n if (element.nodeType === ELEMENT_NODE) {\n return jqLite(element);\n }\n}\n\nfunction extractElementNode(element) {\n if (!element[0]) return element;\n for (var i = 0; i < element.length; i++) {\n var elm = element[i];\n if (elm.nodeType === ELEMENT_NODE) {\n return elm;\n }\n }\n}\n\nfunction $$addClass($$jqLite, element, className) {\n forEach(element, function(elm) {\n $$jqLite.addClass(elm, className);\n });\n}\n\nfunction $$removeClass($$jqLite, element, className) {\n forEach(element, function(elm) {\n $$jqLite.removeClass(elm, className);\n });\n}\n\nfunction applyAnimationClassesFactory($$jqLite) {\n return function(element, options) {\n if (options.addClass) {\n $$addClass($$jqLite, element, options.addClass);\n options.addClass = null;\n }\n if (options.removeClass) {\n $$removeClass($$jqLite, element, options.removeClass);\n options.removeClass = null;\n }\n };\n}\n\nfunction prepareAnimationOptions(options) {\n options = options || {};\n if (!options.$$prepared) {\n var domOperation = options.domOperation || noop;\n options.domOperation = function() {\n options.$$domOperationFired = true;\n domOperation();\n domOperation = noop;\n };\n options.$$prepared = true;\n }\n return options;\n}\n\nfunction applyAnimationStyles(element, options) {\n applyAnimationFromStyles(element, options);\n applyAnimationToStyles(element, options);\n}\n\nfunction applyAnimationFromStyles(element, options) {\n if (options.from) {\n element.css(options.from);\n options.from = null;\n }\n}\n\nfunction applyAnimationToStyles(element, options) {\n if (options.to) {\n element.css(options.to);\n options.to = null;\n }\n}\n\nfunction mergeAnimationDetails(element, oldAnimation, newAnimation) {\n var target = oldAnimation.options || {};\n var newOptions = newAnimation.options || {};\n\n var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || '');\n var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');\n var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);\n\n if (newOptions.preparationClasses) {\n target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses);\n delete newOptions.preparationClasses;\n }\n\n // noop is basically when there is no callback; otherwise something has been set\n var realDomOperation = target.domOperation !== noop ? target.domOperation : null;\n\n extend(target, newOptions);\n\n // TODO(matsko or sreeramu): proper fix is to maintain all animation callback in array and call at last,but now only leave has the callback so no issue with this.\n if (realDomOperation) {\n target.domOperation = realDomOperation;\n }\n\n if (classes.addClass) {\n target.addClass = classes.addClass;\n } else {\n target.addClass = null;\n }\n\n if (classes.removeClass) {\n target.removeClass = classes.removeClass;\n } else {\n target.removeClass = null;\n }\n\n oldAnimation.addClass = target.addClass;\n oldAnimation.removeClass = target.removeClass;\n\n return target;\n}\n\nfunction resolveElementClasses(existing, toAdd, toRemove) {\n var ADD_CLASS = 1;\n var REMOVE_CLASS = -1;\n\n var flags = {};\n existing = splitClassesToLookup(existing);\n\n toAdd = splitClassesToLookup(toAdd);\n forEach(toAdd, function(value, key) {\n flags[key] = ADD_CLASS;\n });\n\n toRemove = splitClassesToLookup(toRemove);\n forEach(toRemove, function(value, key) {\n flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS;\n });\n\n var classes = {\n addClass: '',\n removeClass: ''\n };\n\n forEach(flags, function(val, klass) {\n var prop, allow;\n if (val === ADD_CLASS) {\n prop = 'addClass';\n allow = !existing[klass] || existing[klass + REMOVE_CLASS_SUFFIX];\n } else if (val === REMOVE_CLASS) {\n prop = 'removeClass';\n allow = existing[klass] || existing[klass + ADD_CLASS_SUFFIX];\n }\n if (allow) {\n if (classes[prop].length) {\n classes[prop] += ' ';\n }\n classes[prop] += klass;\n }\n });\n\n function splitClassesToLookup(classes) {\n if (isString(classes)) {\n classes = classes.split(' ');\n }\n\n var obj = {};\n forEach(classes, function(klass) {\n // sometimes the split leaves empty string values\n // incase extra spaces were applied to the options\n if (klass.length) {\n obj[klass] = true;\n }\n });\n return obj;\n }\n\n return classes;\n}\n\nfunction getDomNode(element) {\n return (element instanceof jqLite) ? element[0] : element;\n}\n\nfunction applyGeneratedPreparationClasses($$jqLite, element, event, options) {\n var classes = '';\n if (event) {\n classes = pendClasses(event, EVENT_CLASS_PREFIX, true);\n }\n if (options.addClass) {\n classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX));\n }\n if (options.removeClass) {\n classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX));\n }\n if (classes.length) {\n options.preparationClasses = classes;\n element.addClass(classes);\n }\n}\n\nfunction clearGeneratedClasses(element, options) {\n if (options.preparationClasses) {\n element.removeClass(options.preparationClasses);\n options.preparationClasses = null;\n }\n if (options.activeClasses) {\n element.removeClass(options.activeClasses);\n options.activeClasses = null;\n }\n}\n\nfunction blockKeyframeAnimations(node, applyBlock) {\n var value = applyBlock ? 'paused' : '';\n var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;\n applyInlineStyle(node, [key, value]);\n return [key, value];\n}\n\nfunction applyInlineStyle(node, styleTuple) {\n var prop = styleTuple[0];\n var value = styleTuple[1];\n node.style[prop] = value;\n}\n\nfunction concatWithSpace(a,b) {\n if (!a) return b;\n if (!b) return a;\n return a + ' ' + b;\n}\n\nvar helpers = {\n blockTransitions: function(node, duration) {\n // we use a negative delay value since it performs blocking\n // yet it doesn't kill any existing transitions running on the\n // same element which makes this safe for class-based animations\n var value = duration ? '-' + duration + 's' : '';\n applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);\n return [TRANSITION_DELAY_PROP, value];\n }\n};\n\nvar $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {\n var queue, cancelFn;\n\n function scheduler(tasks) {\n // we make a copy since RAFScheduler mutates the state\n // of the passed in array variable and this would be difficult\n // to track down on the outside code\n queue = queue.concat(tasks);\n nextTick();\n }\n\n queue = scheduler.queue = [];\n\n /* waitUntilQuiet does two things:\n * 1. It will run the FINAL `fn` value only when an uncanceled RAF has passed through\n * 2. It will delay the next wave of tasks from running until the quiet `fn` has run.\n *\n * The motivation here is that animation code can request more time from the scheduler\n * before the next wave runs. This allows for certain DOM properties such as classes to\n * be resolved in time for the next animation to run.\n */\n scheduler.waitUntilQuiet = function(fn) {\n if (cancelFn) cancelFn();\n\n cancelFn = $$rAF(function() {\n cancelFn = null;\n fn();\n nextTick();\n });\n };\n\n return scheduler;\n\n function nextTick() {\n if (!queue.length) return;\n\n var items = queue.shift();\n for (var i = 0; i < items.length; i++) {\n items[i]();\n }\n\n if (!cancelFn) {\n $$rAF(function() {\n if (!cancelFn) nextTick();\n });\n }\n }\n}];\n\n/**\n * @ngdoc directive\n * @name ngAnimateChildren\n * @restrict AE\n * @element ANY\n *\n * @description\n *\n * ngAnimateChildren allows you to specify that children of this element should animate even if any\n * of the children's parents are currently animating. By default, when an element has an active `enter`, `leave`, or `move`\n * (structural) animation, child elements that also have an active structural animation are not animated.\n *\n * Note that even if `ngAnimateChildren` is set, no child animations will run when the parent element is removed from the DOM (`leave` animation).\n *\n *\n * @param {string} ngAnimateChildren If the value is empty, `true` or `on`,\n * then child animations are allowed. If the value is `false`, child animations are not allowed.\n *\n * @example\n * \n \n
\n \n \n
\n
\n
\n List of items:\n
Item {{item}}
\n
\n
\n
\n
\n \n\n .container.ng-enter,\n .container.ng-leave {\n transition: all ease 1.5s;\n }\n\n .container.ng-enter,\n .container.ng-leave-active {\n opacity: 0;\n }\n\n .container.ng-leave,\n .container.ng-enter-active {\n opacity: 1;\n }\n\n .item {\n background: firebrick;\n color: #FFF;\n margin-bottom: 10px;\n }\n\n .item.ng-enter,\n .item.ng-leave {\n transition: transform 1.5s ease;\n }\n\n .item.ng-enter {\n transform: translateX(50px);\n }\n\n .item.ng-enter-active {\n transform: translateX(0);\n }\n \n \n angular.module('ngAnimateChildren', ['ngAnimate'])\n .controller('MainController', function MainController() {\n this.animateChildren = false;\n this.enterElement = false;\n });\n \n
\n */\nvar $$AnimateChildrenDirective = ['$interpolate', function($interpolate) {\n return {\n link: function(scope, element, attrs) {\n var val = attrs.ngAnimateChildren;\n if (isString(val) && val.length === 0) { //empty attribute\n element.data(NG_ANIMATE_CHILDREN_DATA, true);\n } else {\n // Interpolate and set the value, so that it is available to\n // animations that run right after compilation\n setData($interpolate(val)(scope));\n attrs.$observe('ngAnimateChildren', setData);\n }\n\n function setData(value) {\n value = value === 'on' || value === 'true';\n element.data(NG_ANIMATE_CHILDREN_DATA, value);\n }\n }\n };\n}];\n\n/* exported $AnimateCssProvider */\n\nvar ANIMATE_TIMER_KEY = '$$animateCss';\n\n/**\n * @ngdoc service\n * @name $animateCss\n * @kind object\n *\n * @description\n * The `$animateCss` service is a useful utility to trigger customized CSS-based transitions/keyframes\n * from a JavaScript-based animation or directly from a directive. The purpose of `$animateCss` is NOT\n * to side-step how `$animate` and ngAnimate work, but the goal is to allow pre-existing animations or\n * directives to create more complex animations that can be purely driven using CSS code.\n *\n * Note that only browsers that support CSS transitions and/or keyframe animations are capable of\n * rendering animations triggered via `$animateCss` (bad news for IE9 and lower).\n *\n * ## General Use\n * Once again, `$animateCss` is designed to be used inside of a registered JavaScript animation that\n * is powered by ngAnimate. It is possible to use `$animateCss` directly inside of a directive, however,\n * any automatic control over cancelling animations and/or preventing animations from being run on\n * child elements will not be handled by AngularJS. For this to work as expected, please use `$animate` to\n * trigger the animation and then setup a JavaScript animation that injects `$animateCss` to trigger\n * the CSS animation.\n *\n * The example below shows how we can create a folding animation on an element using `ng-if`:\n *\n * ```html\n * \n *
\n * This element will go BOOM\n *
\n * \n * ```\n *\n * Now we create the **JavaScript animation** that will trigger the CSS transition:\n *\n * ```js\n * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) {\n * return {\n * enter: function(element, doneFn) {\n * var height = element[0].offsetHeight;\n * return $animateCss(element, {\n * from: { height:'0px' },\n * to: { height:height + 'px' },\n * duration: 1 // one second\n * });\n * }\n * }\n * }]);\n * ```\n *\n * ## More Advanced Uses\n *\n * `$animateCss` is the underlying code that ngAnimate uses to power **CSS-based animations** behind the scenes. Therefore CSS hooks\n * like `.ng-EVENT`, `.ng-EVENT-active`, `.ng-EVENT-stagger` are all features that can be triggered using `$animateCss` via JavaScript code.\n *\n * This also means that just about any combination of adding classes, removing classes, setting styles, dynamically setting a keyframe animation,\n * applying a hardcoded duration or delay value, changing the animation easing or applying a stagger animation are all options that work with\n * `$animateCss`. The service itself is smart enough to figure out the combination of options and examine the element styling properties in order\n * to provide a working animation that will run in CSS.\n *\n * The example below showcases a more advanced version of the `.fold-animation` from the example above:\n *\n * ```js\n * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) {\n * return {\n * enter: function(element, doneFn) {\n * var height = element[0].offsetHeight;\n * return $animateCss(element, {\n * addClass: 'red large-text pulse-twice',\n * easing: 'ease-out',\n * from: { height:'0px' },\n * to: { height:height + 'px' },\n * duration: 1 // one second\n * });\n * }\n * }\n * }]);\n * ```\n *\n * Since we're adding/removing CSS classes then the CSS transition will also pick those up:\n *\n * ```css\n * /* since a hardcoded duration value of 1 was provided in the JavaScript animation code,\n * the CSS classes below will be transitioned despite them being defined as regular CSS classes */\n * .red { background:red; }\n * .large-text { font-size:20px; }\n *\n * /* we can also use a keyframe animation and $animateCss will make it work alongside the transition */\n * .pulse-twice {\n * animation: 0.5s pulse linear 2;\n * -webkit-animation: 0.5s pulse linear 2;\n * }\n *\n * @keyframes pulse {\n * from { transform: scale(0.5); }\n * to { transform: scale(1.5); }\n * }\n *\n * @-webkit-keyframes pulse {\n * from { -webkit-transform: scale(0.5); }\n * to { -webkit-transform: scale(1.5); }\n * }\n * ```\n *\n * Given this complex combination of CSS classes, styles and options, `$animateCss` will figure everything out and make the animation happen.\n *\n * ## How the Options are handled\n *\n * `$animateCss` is very versatile and intelligent when it comes to figuring out what configurations to apply to the element to ensure the animation\n * works with the options provided. Say for example we were adding a class that contained a keyframe value and we wanted to also animate some inline\n * styles using the `from` and `to` properties.\n *\n * ```js\n * var animator = $animateCss(element, {\n * from: { background:'red' },\n * to: { background:'blue' }\n * });\n * animator.start();\n * ```\n *\n * ```css\n * .rotating-animation {\n * animation:0.5s rotate linear;\n * -webkit-animation:0.5s rotate linear;\n * }\n *\n * @keyframes rotate {\n * from { transform: rotate(0deg); }\n * to { transform: rotate(360deg); }\n * }\n *\n * @-webkit-keyframes rotate {\n * from { -webkit-transform: rotate(0deg); }\n * to { -webkit-transform: rotate(360deg); }\n * }\n * ```\n *\n * The missing pieces here are that we do not have a transition set (within the CSS code nor within the `$animateCss` options) and the duration of the animation is\n * going to be detected from what the keyframe styles on the CSS class are. In this event, `$animateCss` will automatically create an inline transition\n * style matching the duration detected from the keyframe style (which is present in the CSS class that is being added) and then prepare both the transition\n * and keyframe animations to run in parallel on the element. Then when the animation is underway the provided `from` and `to` CSS styles will be applied\n * and spread across the transition and keyframe animation.\n *\n * ## What is returned\n *\n * `$animateCss` works in two stages: a preparation phase and an animation phase. Therefore when `$animateCss` is first called it will NOT actually\n * start the animation. All that is going on here is that the element is being prepared for the animation (which means that the generated CSS classes are\n * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties:\n *\n * ```js\n * var animator = $animateCss(element, { ... });\n * ```\n *\n * Now what do the contents of our `animator` variable look like:\n *\n * ```js\n * {\n * // starts the animation\n * start: Function,\n *\n * // ends (aborts) the animation\n * end: Function\n * }\n * ```\n *\n * To actually start the animation we need to run `animation.start()` which will then return a promise that we can hook into to detect when the animation ends.\n * If we choose not to run the animation then we MUST run `animation.end()` to perform a cleanup on the element (since some CSS classes and styles may have been\n * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties\n * and that changing them will not reconfigure the parameters of the animation.\n *\n * ### runner.done() vs runner.then()\n * It is documented that `animation.start()` will return a promise object and this is true, however, there is also an additional method available on the\n * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**.\n * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()`\n * unless you really need a digest to kick off afterwards.\n *\n * Keep in mind that, to make this easier, ngAnimate has tweaked the JS animations API to recognize when a runner instance is returned from $animateCss\n * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code).\n * Check the {@link ngAnimate.$animateCss#usage animation code above} to see how this works.\n *\n * @param {DOMElement} element the element that will be animated\n * @param {object} options the animation-related options that will be applied during the animation\n *\n * * `event` - The DOM event (e.g. enter, leave, move). When used, a generated CSS class of `ng-EVENT` and `ng-EVENT-active` will be applied\n * to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.)\n * * `structural` - Indicates that the `ng-` prefix will be added to the event class. Setting to `false` or omitting will turn `ng-EVENT` and\n * `ng-EVENT-active` in `EVENT` and `EVENT-active`. Unused if `event` is omitted.\n * * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both).\n * * `transitionStyle` - The raw CSS transition style that will be used (e.g. `1s linear all`).\n * * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).\n * * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation.\n * * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition.\n * * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation.\n * * `removeClass` - A space separated list of CSS classes that will be removed from the element and spread across the animation.\n * * `duration` - A number value representing the total duration of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `0`\n * is provided then the animation will be skipped entirely.\n * * `delay` - A number value representing the total delay of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `true` is\n * used then whatever delay value is detected from the CSS classes will be mirrored on the elements styles (e.g. by setting delay true then the style value\n * of the element will be `transition-delay: DETECTED_VALUE`). Using `true` is useful when you want the CSS classes and inline styles to all share the same\n * CSS delay value.\n * * `stagger` - A numeric time value representing the delay between successively animated elements\n * ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.})\n * * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a\n * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)\n * * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occurring on the classes being added and removed.)\n * * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once\n * the animation is closed. This is useful for when the styles are used purely for the sake of\n * the animation and do not have a lasting visual effect on the element (e.g. a collapse and open animation).\n * By default this value is set to `false`.\n *\n * @return {object} an object with start and end methods and details about the animation.\n *\n * * `start` - The method to start the animation. This will return a `Promise` when called.\n * * `end` - This method will cancel the animation and remove all applied CSS classes and styles.\n */\nvar ONE_SECOND = 1000;\n\nvar ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;\nvar CLOSING_TIME_BUFFER = 1.5;\n\nvar DETECT_CSS_PROPERTIES = {\n transitionDuration: TRANSITION_DURATION_PROP,\n transitionDelay: TRANSITION_DELAY_PROP,\n transitionProperty: TRANSITION_PROP + PROPERTY_KEY,\n animationDuration: ANIMATION_DURATION_PROP,\n animationDelay: ANIMATION_DELAY_PROP,\n animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY\n};\n\nvar DETECT_STAGGER_CSS_PROPERTIES = {\n transitionDuration: TRANSITION_DURATION_PROP,\n transitionDelay: TRANSITION_DELAY_PROP,\n animationDuration: ANIMATION_DURATION_PROP,\n animationDelay: ANIMATION_DELAY_PROP\n};\n\nfunction getCssKeyframeDurationStyle(duration) {\n return [ANIMATION_DURATION_PROP, duration + 's'];\n}\n\nfunction getCssDelayStyle(delay, isKeyframeAnimation) {\n var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;\n return [prop, delay + 's'];\n}\n\nfunction computeCssStyles($window, element, properties) {\n var styles = Object.create(null);\n var detectedStyles = $window.getComputedStyle(element) || {};\n forEach(properties, function(formalStyleName, actualStyleName) {\n var val = detectedStyles[formalStyleName];\n if (val) {\n var c = val.charAt(0);\n\n // only numerical-based values have a negative sign or digit as the first value\n if (c === '-' || c === '+' || c >= 0) {\n val = parseMaxTime(val);\n }\n\n // by setting this to null in the event that the delay is not set or is set directly as 0\n // then we can still allow for negative values to be used later on and not mistake this\n // value for being greater than any other negative value.\n if (val === 0) {\n val = null;\n }\n styles[actualStyleName] = val;\n }\n });\n\n return styles;\n}\n\nfunction parseMaxTime(str) {\n var maxValue = 0;\n var values = str.split(/\\s*,\\s*/);\n forEach(values, function(value) {\n // it's always safe to consider only second values and omit `ms` values since\n // getComputedStyle will always handle the conversion for us\n if (value.charAt(value.length - 1) === 's') {\n value = value.substring(0, value.length - 1);\n }\n value = parseFloat(value) || 0;\n maxValue = maxValue ? Math.max(value, maxValue) : value;\n });\n return maxValue;\n}\n\nfunction truthyTimingValue(val) {\n return val === 0 || val != null;\n}\n\nfunction getCssTransitionDurationStyle(duration, applyOnlyDuration) {\n var style = TRANSITION_PROP;\n var value = duration + 's';\n if (applyOnlyDuration) {\n style += DURATION_KEY;\n } else {\n value += ' linear all';\n }\n return [style, value];\n}\n\n// we do not reassign an already present style value since\n// if we detect the style property value again we may be\n// detecting styles that were added via the `from` styles.\n// We make use of `isDefined` here since an empty string\n// or null value (which is what getPropertyValue will return\n// for a non-existing style) will still be marked as a valid\n// value for the style (a falsy value implies that the style\n// is to be removed at the end of the animation). If we had a simple\n// \"OR\" statement then it would not be enough to catch that.\nfunction registerRestorableStyles(backup, node, properties) {\n forEach(properties, function(prop) {\n backup[prop] = isDefined(backup[prop])\n ? backup[prop]\n : node.style.getPropertyValue(prop);\n });\n}\n\nvar $AnimateCssProvider = ['$animateProvider', /** @this */ function($animateProvider) {\n\n this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout', '$$animateCache',\n '$$forceReflow', '$sniffer', '$$rAFScheduler', '$$animateQueue',\n function($window, $$jqLite, $$AnimateRunner, $timeout, $$animateCache,\n $$forceReflow, $sniffer, $$rAFScheduler, $$animateQueue) {\n\n var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);\n\n function computeCachedCssStyles(node, className, cacheKey, allowNoDuration, properties) {\n var timings = $$animateCache.get(cacheKey);\n\n if (!timings) {\n timings = computeCssStyles($window, node, properties);\n if (timings.animationIterationCount === 'infinite') {\n timings.animationIterationCount = 1;\n }\n }\n\n // if a css animation has no duration we\n // should mark that so that repeated addClass/removeClass calls are skipped\n var hasDuration = allowNoDuration || (timings.transitionDuration > 0 || timings.animationDuration > 0);\n\n // we keep putting this in multiple times even though the value and the cacheKey are the same\n // because we're keeping an internal tally of how many duplicate animations are detected.\n $$animateCache.put(cacheKey, timings, hasDuration);\n\n return timings;\n }\n\n function computeCachedCssStaggerStyles(node, className, cacheKey, properties) {\n var stagger;\n var staggerCacheKey = 'stagger-' + cacheKey;\n\n // if we have one or more existing matches of matching elements\n // containing the same parent + CSS styles (which is how cacheKey works)\n // then staggering is possible\n if ($$animateCache.count(cacheKey) > 0) {\n stagger = $$animateCache.get(staggerCacheKey);\n\n if (!stagger) {\n var staggerClassName = pendClasses(className, '-stagger');\n\n $$jqLite.addClass(node, staggerClassName);\n\n stagger = computeCssStyles($window, node, properties);\n\n // force the conversion of a null value to zero incase not set\n stagger.animationDuration = Math.max(stagger.animationDuration, 0);\n stagger.transitionDuration = Math.max(stagger.transitionDuration, 0);\n\n $$jqLite.removeClass(node, staggerClassName);\n\n $$animateCache.put(staggerCacheKey, stagger, true);\n }\n }\n\n return stagger || {};\n }\n\n var rafWaitQueue = [];\n function waitUntilQuiet(callback) {\n rafWaitQueue.push(callback);\n $$rAFScheduler.waitUntilQuiet(function() {\n $$animateCache.flush();\n\n // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.\n // PLEASE EXAMINE THE `$$forceReflow` service to understand why.\n var pageWidth = $$forceReflow();\n\n // we use a for loop to ensure that if the queue is changed\n // during this looping then it will consider new requests\n for (var i = 0; i < rafWaitQueue.length; i++) {\n rafWaitQueue[i](pageWidth);\n }\n rafWaitQueue.length = 0;\n });\n }\n\n function computeTimings(node, className, cacheKey, allowNoDuration) {\n var timings = computeCachedCssStyles(node, className, cacheKey, allowNoDuration, DETECT_CSS_PROPERTIES);\n var aD = timings.animationDelay;\n var tD = timings.transitionDelay;\n timings.maxDelay = aD && tD\n ? Math.max(aD, tD)\n : (aD || tD);\n timings.maxDuration = Math.max(\n timings.animationDuration * timings.animationIterationCount,\n timings.transitionDuration);\n\n return timings;\n }\n\n return function init(element, initialOptions) {\n // all of the animation functions should create\n // a copy of the options data, however, if a\n // parent service has already created a copy then\n // we should stick to using that\n var options = initialOptions || {};\n if (!options.$$prepared) {\n options = prepareAnimationOptions(copy(options));\n }\n\n var restoreStyles = {};\n var node = getDomNode(element);\n if (!node\n || !node.parentNode\n || !$$animateQueue.enabled()) {\n return closeAndReturnNoopAnimator();\n }\n\n var temporaryStyles = [];\n var classes = element.attr('class');\n var styles = packageStyles(options);\n var animationClosed;\n var animationPaused;\n var animationCompleted;\n var runner;\n var runnerHost;\n var maxDelay;\n var maxDelayTime;\n var maxDuration;\n var maxDurationTime;\n var startTime;\n var events = [];\n\n if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) {\n return closeAndReturnNoopAnimator();\n }\n\n var method = options.event && isArray(options.event)\n ? options.event.join(' ')\n : options.event;\n\n var isStructural = method && options.structural;\n var structuralClassName = '';\n var addRemoveClassName = '';\n\n if (isStructural) {\n structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true);\n } else if (method) {\n structuralClassName = method;\n }\n\n if (options.addClass) {\n addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX);\n }\n\n if (options.removeClass) {\n if (addRemoveClassName.length) {\n addRemoveClassName += ' ';\n }\n addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX);\n }\n\n // there may be a situation where a structural animation is combined together\n // with CSS classes that need to resolve before the animation is computed.\n // However this means that there is no explicit CSS code to block the animation\n // from happening (by setting 0s none in the class name). If this is the case\n // we need to apply the classes before the first rAF so we know to continue if\n // there actually is a detected transition or keyframe animation\n if (options.applyClassesEarly && addRemoveClassName.length) {\n applyAnimationClasses(element, options);\n }\n\n var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim();\n var fullClassName = classes + ' ' + preparationClasses;\n var hasToStyles = styles.to && Object.keys(styles.to).length > 0;\n var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;\n\n // there is no way we can trigger an animation if no styles and\n // no classes are being applied which would then trigger a transition,\n // unless there a is raw keyframe value that is applied to the element.\n if (!containsKeyframeAnimation\n && !hasToStyles\n && !preparationClasses) {\n return closeAndReturnNoopAnimator();\n }\n\n var stagger, cacheKey = $$animateCache.cacheKey(node, method, options.addClass, options.removeClass);\n if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) {\n preparationClasses = null;\n return closeAndReturnNoopAnimator();\n }\n\n if (options.stagger > 0) {\n var staggerVal = parseFloat(options.stagger);\n stagger = {\n transitionDelay: staggerVal,\n animationDelay: staggerVal,\n transitionDuration: 0,\n animationDuration: 0\n };\n } else {\n stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);\n }\n\n if (!options.$$skipPreparationClasses) {\n $$jqLite.addClass(element, preparationClasses);\n }\n\n var applyOnlyDuration;\n\n if (options.transitionStyle) {\n var transitionStyle = [TRANSITION_PROP, options.transitionStyle];\n applyInlineStyle(node, transitionStyle);\n temporaryStyles.push(transitionStyle);\n }\n\n if (options.duration >= 0) {\n applyOnlyDuration = node.style[TRANSITION_PROP].length > 0;\n var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration);\n\n // we set the duration so that it will be picked up by getComputedStyle later\n applyInlineStyle(node, durationStyle);\n temporaryStyles.push(durationStyle);\n }\n\n if (options.keyframeStyle) {\n var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle];\n applyInlineStyle(node, keyframeStyle);\n temporaryStyles.push(keyframeStyle);\n }\n\n var itemIndex = stagger\n ? options.staggerIndex >= 0\n ? options.staggerIndex\n : $$animateCache.count(cacheKey)\n : 0;\n\n var isFirst = itemIndex === 0;\n\n // this is a pre-emptive way of forcing the setup classes to be added and applied INSTANTLY\n // without causing any combination of transitions to kick in. By adding a negative delay value\n // it forces the setup class' transition to end immediately. We later then remove the negative\n // transition delay to allow for the transition to naturally do it's thing. The beauty here is\n // that if there is no transition defined then nothing will happen and this will also allow\n // other transitions to be stacked on top of each other without any chopping them out.\n if (isFirst && !options.skipBlocking) {\n helpers.blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);\n }\n\n var timings = computeTimings(node, fullClassName, cacheKey, !isStructural);\n var relativeDelay = timings.maxDelay;\n maxDelay = Math.max(relativeDelay, 0);\n maxDuration = timings.maxDuration;\n\n var flags = {};\n flags.hasTransitions = timings.transitionDuration > 0;\n flags.hasAnimations = timings.animationDuration > 0;\n flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty === 'all';\n flags.applyTransitionDuration = hasToStyles && (\n (flags.hasTransitions && !flags.hasTransitionAll)\n || (flags.hasAnimations && !flags.hasTransitions));\n flags.applyAnimationDuration = options.duration && flags.hasAnimations;\n flags.applyTransitionDelay = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions);\n flags.applyAnimationDelay = truthyTimingValue(options.delay) && flags.hasAnimations;\n flags.recalculateTimingStyles = addRemoveClassName.length > 0;\n\n if (flags.applyTransitionDuration || flags.applyAnimationDuration) {\n maxDuration = options.duration ? parseFloat(options.duration) : maxDuration;\n\n if (flags.applyTransitionDuration) {\n flags.hasTransitions = true;\n timings.transitionDuration = maxDuration;\n applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0;\n temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration));\n }\n\n if (flags.applyAnimationDuration) {\n flags.hasAnimations = true;\n timings.animationDuration = maxDuration;\n temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration));\n }\n }\n\n if (maxDuration === 0 && !flags.recalculateTimingStyles) {\n return closeAndReturnNoopAnimator();\n }\n\n var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);\n\n if (options.delay != null) {\n var delayStyle;\n if (typeof options.delay !== 'boolean') {\n delayStyle = parseFloat(options.delay);\n // number in options.delay means we have to recalculate the delay for the closing timeout\n maxDelay = Math.max(delayStyle, 0);\n }\n\n if (flags.applyTransitionDelay) {\n temporaryStyles.push(getCssDelayStyle(delayStyle));\n }\n\n if (flags.applyAnimationDelay) {\n temporaryStyles.push(getCssDelayStyle(delayStyle, true));\n }\n }\n\n // we need to recalculate the delay value since we used a pre-emptive negative\n // delay value and the delay value is required for the final event checking. This\n // property will ensure that this will happen after the RAF phase has passed.\n if (options.duration == null && timings.transitionDuration > 0) {\n flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst;\n }\n\n maxDelayTime = maxDelay * ONE_SECOND;\n maxDurationTime = maxDuration * ONE_SECOND;\n if (!options.skipBlocking) {\n flags.blockTransition = timings.transitionDuration > 0;\n flags.blockKeyframeAnimation = timings.animationDuration > 0 &&\n stagger.animationDelay > 0 &&\n stagger.animationDuration === 0;\n }\n\n if (options.from) {\n if (options.cleanupStyles) {\n registerRestorableStyles(restoreStyles, node, Object.keys(options.from));\n }\n applyAnimationFromStyles(element, options);\n }\n\n if (flags.blockTransition || flags.blockKeyframeAnimation) {\n applyBlocking(maxDuration);\n } else if (!options.skipBlocking) {\n helpers.blockTransitions(node, false);\n }\n\n // TODO(matsko): for 1.5 change this code to have an animator object for better debugging\n return {\n $$willAnimate: true,\n end: endFn,\n start: function() {\n if (animationClosed) return;\n\n runnerHost = {\n end: endFn,\n cancel: cancelFn,\n resume: null, //this will be set during the start() phase\n pause: null\n };\n\n runner = new $$AnimateRunner(runnerHost);\n\n waitUntilQuiet(start);\n\n // we don't have access to pause/resume the animation\n // since it hasn't run yet. AnimateRunner will therefore\n // set noop functions for resume and pause and they will\n // later be overridden once the animation is triggered\n return runner;\n }\n };\n\n function endFn() {\n close();\n }\n\n function cancelFn() {\n close(true);\n }\n\n function close(rejected) {\n // if the promise has been called already then we shouldn't close\n // the animation again\n if (animationClosed || (animationCompleted && animationPaused)) return;\n animationClosed = true;\n animationPaused = false;\n\n if (preparationClasses && !options.$$skipPreparationClasses) {\n $$jqLite.removeClass(element, preparationClasses);\n }\n\n if (activeClasses) {\n $$jqLite.removeClass(element, activeClasses);\n }\n\n blockKeyframeAnimations(node, false);\n helpers.blockTransitions(node, false);\n\n forEach(temporaryStyles, function(entry) {\n // There is only one way to remove inline style properties entirely from elements.\n // By using `removeProperty` this works, but we need to convert camel-cased CSS\n // styles down to hyphenated values.\n node.style[entry[0]] = '';\n });\n\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n\n if (Object.keys(restoreStyles).length) {\n forEach(restoreStyles, function(value, prop) {\n if (value) {\n node.style.setProperty(prop, value);\n } else {\n node.style.removeProperty(prop);\n }\n });\n }\n\n // the reason why we have this option is to allow a synchronous closing callback\n // that is fired as SOON as the animation ends (when the CSS is removed) or if\n // the animation never takes off at all. A good example is a leave animation since\n // the element must be removed just after the animation is over or else the element\n // will appear on screen for one animation frame causing an overbearing flicker.\n if (options.onDone) {\n options.onDone();\n }\n\n if (events && events.length) {\n // Remove the transitionend / animationend listener(s)\n element.off(events.join(' '), onAnimationProgress);\n }\n\n //Cancel the fallback closing timeout and remove the timer data\n var animationTimerData = element.data(ANIMATE_TIMER_KEY);\n if (animationTimerData) {\n $timeout.cancel(animationTimerData[0].timer);\n element.removeData(ANIMATE_TIMER_KEY);\n }\n\n // if the preparation function fails then the promise is not setup\n if (runner) {\n runner.complete(!rejected);\n }\n }\n\n function applyBlocking(duration) {\n if (flags.blockTransition) {\n helpers.blockTransitions(node, duration);\n }\n\n if (flags.blockKeyframeAnimation) {\n blockKeyframeAnimations(node, !!duration);\n }\n }\n\n function closeAndReturnNoopAnimator() {\n runner = new $$AnimateRunner({\n end: endFn,\n cancel: cancelFn\n });\n\n // should flush the cache animation\n waitUntilQuiet(noop);\n close();\n\n return {\n $$willAnimate: false,\n start: function() {\n return runner;\n },\n end: endFn\n };\n }\n\n function onAnimationProgress(event) {\n event.stopPropagation();\n var ev = event.originalEvent || event;\n\n if (ev.target !== node) {\n // Since TransitionEvent / AnimationEvent bubble up,\n // we have to ignore events by finished child animations\n return;\n }\n\n // we now always use `Date.now()` due to the recent changes with\n // event.timeStamp in Firefox, Webkit and Chrome (see #13494 for more info)\n var timeStamp = ev.$manualTimeStamp || Date.now();\n\n /* Firefox (or possibly just Gecko) likes to not round values up\n * when a ms measurement is used for the animation */\n var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));\n\n /* $manualTimeStamp is a mocked timeStamp value which is set\n * within browserTrigger(). This is only here so that tests can\n * mock animations properly. Real events fallback to event.timeStamp,\n * or, if they don't, then a timeStamp is automatically created for them.\n * We're checking to see if the timeStamp surpasses the expected delay,\n * but we're using elapsedTime instead of the timeStamp on the 2nd\n * pre-condition since animationPauseds sometimes close off early */\n if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {\n // we set this flag to ensure that if the transition is paused then, when resumed,\n // the animation will automatically close itself since transitions cannot be paused.\n animationCompleted = true;\n close();\n }\n }\n\n function start() {\n if (animationClosed) return;\n if (!node.parentNode) {\n close();\n return;\n }\n\n // even though we only pause keyframe animations here the pause flag\n // will still happen when transitions are used. Only the transition will\n // not be paused since that is not possible. If the animation ends when\n // paused then it will not complete until unpaused or cancelled.\n var playPause = function(playAnimation) {\n if (!animationCompleted) {\n animationPaused = !playAnimation;\n if (timings.animationDuration) {\n var value = blockKeyframeAnimations(node, animationPaused);\n if (animationPaused) {\n temporaryStyles.push(value);\n } else {\n removeFromArray(temporaryStyles, value);\n }\n }\n } else if (animationPaused && playAnimation) {\n animationPaused = false;\n close();\n }\n };\n\n // checking the stagger duration prevents an accidentally cascade of the CSS delay style\n // being inherited from the parent. If the transition duration is zero then we can safely\n // rely that the delay value is an intentional stagger delay style.\n var maxStagger = itemIndex > 0\n && ((timings.transitionDuration && stagger.transitionDuration === 0) ||\n (timings.animationDuration && stagger.animationDuration === 0))\n && Math.max(stagger.animationDelay, stagger.transitionDelay);\n if (maxStagger) {\n $timeout(triggerAnimationStart,\n Math.floor(maxStagger * itemIndex * ONE_SECOND),\n false);\n } else {\n triggerAnimationStart();\n }\n\n // this will decorate the existing promise runner with pause/resume methods\n runnerHost.resume = function() {\n playPause(true);\n };\n\n runnerHost.pause = function() {\n playPause(false);\n };\n\n function triggerAnimationStart() {\n // just incase a stagger animation kicks in when the animation\n // itself was cancelled entirely\n if (animationClosed) return;\n\n applyBlocking(false);\n\n forEach(temporaryStyles, function(entry) {\n var key = entry[0];\n var value = entry[1];\n node.style[key] = value;\n });\n\n applyAnimationClasses(element, options);\n $$jqLite.addClass(element, activeClasses);\n\n if (flags.recalculateTimingStyles) {\n fullClassName = node.getAttribute('class') + ' ' + preparationClasses;\n cacheKey = $$animateCache.cacheKey(node, method, options.addClass, options.removeClass);\n\n timings = computeTimings(node, fullClassName, cacheKey, false);\n relativeDelay = timings.maxDelay;\n maxDelay = Math.max(relativeDelay, 0);\n maxDuration = timings.maxDuration;\n\n if (maxDuration === 0) {\n close();\n return;\n }\n\n flags.hasTransitions = timings.transitionDuration > 0;\n flags.hasAnimations = timings.animationDuration > 0;\n }\n\n if (flags.applyAnimationDelay) {\n relativeDelay = typeof options.delay !== 'boolean' && truthyTimingValue(options.delay)\n ? parseFloat(options.delay)\n : relativeDelay;\n\n maxDelay = Math.max(relativeDelay, 0);\n timings.animationDelay = relativeDelay;\n delayStyle = getCssDelayStyle(relativeDelay, true);\n temporaryStyles.push(delayStyle);\n node.style[delayStyle[0]] = delayStyle[1];\n }\n\n maxDelayTime = maxDelay * ONE_SECOND;\n maxDurationTime = maxDuration * ONE_SECOND;\n\n if (options.easing) {\n var easeProp, easeVal = options.easing;\n if (flags.hasTransitions) {\n easeProp = TRANSITION_PROP + TIMING_KEY;\n temporaryStyles.push([easeProp, easeVal]);\n node.style[easeProp] = easeVal;\n }\n if (flags.hasAnimations) {\n easeProp = ANIMATION_PROP + TIMING_KEY;\n temporaryStyles.push([easeProp, easeVal]);\n node.style[easeProp] = easeVal;\n }\n }\n\n if (timings.transitionDuration) {\n events.push(TRANSITIONEND_EVENT);\n }\n\n if (timings.animationDuration) {\n events.push(ANIMATIONEND_EVENT);\n }\n\n startTime = Date.now();\n var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime;\n var endTime = startTime + timerTime;\n\n var animationsData = element.data(ANIMATE_TIMER_KEY) || [];\n var setupFallbackTimer = true;\n if (animationsData.length) {\n var currentTimerData = animationsData[0];\n setupFallbackTimer = endTime > currentTimerData.expectedEndTime;\n if (setupFallbackTimer) {\n $timeout.cancel(currentTimerData.timer);\n } else {\n animationsData.push(close);\n }\n }\n\n if (setupFallbackTimer) {\n var timer = $timeout(onAnimationExpired, timerTime, false);\n animationsData[0] = {\n timer: timer,\n expectedEndTime: endTime\n };\n animationsData.push(close);\n element.data(ANIMATE_TIMER_KEY, animationsData);\n }\n\n if (events.length) {\n element.on(events.join(' '), onAnimationProgress);\n }\n\n if (options.to) {\n if (options.cleanupStyles) {\n registerRestorableStyles(restoreStyles, node, Object.keys(options.to));\n }\n applyAnimationToStyles(element, options);\n }\n }\n\n function onAnimationExpired() {\n var animationsData = element.data(ANIMATE_TIMER_KEY);\n\n // this will be false in the event that the element was\n // removed from the DOM (via a leave animation or something\n // similar)\n if (animationsData) {\n for (var i = 1; i < animationsData.length; i++) {\n animationsData[i]();\n }\n element.removeData(ANIMATE_TIMER_KEY);\n }\n }\n }\n };\n }];\n}];\n\nvar $$AnimateCssDriverProvider = ['$$animationProvider', /** @this */ function($$animationProvider) {\n $$animationProvider.drivers.push('$$animateCssDriver');\n\n var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim';\n var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor';\n\n var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out';\n var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in';\n\n function isDocumentFragment(node) {\n return node.parentNode && node.parentNode.nodeType === 11;\n }\n\n this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document',\n function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $sniffer, $$jqLite, $document) {\n\n // only browsers that support these properties can render animations\n if (!$sniffer.animations && !$sniffer.transitions) return noop;\n\n var bodyNode = $document[0].body;\n var rootNode = getDomNode($rootElement);\n\n var rootBodyElement = jqLite(\n // this is to avoid using something that exists outside of the body\n // we also special case the doc fragment case because our unit test code\n // appends the $rootElement to the body after the app has been bootstrapped\n isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode\n );\n\n return function initDriverFn(animationDetails) {\n return animationDetails.from && animationDetails.to\n ? prepareFromToAnchorAnimation(animationDetails.from,\n animationDetails.to,\n animationDetails.classes,\n animationDetails.anchors)\n : prepareRegularAnimation(animationDetails);\n };\n\n function filterCssClasses(classes) {\n //remove all the `ng-` stuff\n return classes.replace(/\\bng-\\S+\\b/g, '');\n }\n\n function getUniqueValues(a, b) {\n if (isString(a)) a = a.split(' ');\n if (isString(b)) b = b.split(' ');\n return a.filter(function(val) {\n return b.indexOf(val) === -1;\n }).join(' ');\n }\n\n function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {\n var clone = jqLite(getDomNode(outAnchor).cloneNode(true));\n var startingClasses = filterCssClasses(getClassVal(clone));\n\n outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);\n inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);\n\n clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME);\n\n rootBodyElement.append(clone);\n\n var animatorIn, animatorOut = prepareOutAnimation();\n\n // the user may not end up using the `out` animation and\n // only making use of the `in` animation or vice-versa.\n // In either case we should allow this and not assume the\n // animation is over unless both animations are not used.\n if (!animatorOut) {\n animatorIn = prepareInAnimation();\n if (!animatorIn) {\n return end();\n }\n }\n\n var startingAnimator = animatorOut || animatorIn;\n\n return {\n start: function() {\n var runner;\n\n var currentAnimation = startingAnimator.start();\n currentAnimation.done(function() {\n currentAnimation = null;\n if (!animatorIn) {\n animatorIn = prepareInAnimation();\n if (animatorIn) {\n currentAnimation = animatorIn.start();\n currentAnimation.done(function() {\n currentAnimation = null;\n end();\n runner.complete();\n });\n return currentAnimation;\n }\n }\n // in the event that there is no `in` animation\n end();\n runner.complete();\n });\n\n runner = new $$AnimateRunner({\n end: endFn,\n cancel: endFn\n });\n\n return runner;\n\n function endFn() {\n if (currentAnimation) {\n currentAnimation.end();\n }\n }\n }\n };\n\n function calculateAnchorStyles(anchor) {\n var styles = {};\n\n var coords = getDomNode(anchor).getBoundingClientRect();\n\n // we iterate directly since safari messes up and doesn't return\n // all the keys for the coords object when iterated\n forEach(['width','height','top','left'], function(key) {\n var value = coords[key];\n switch (key) {\n case 'top':\n value += bodyNode.scrollTop;\n break;\n case 'left':\n value += bodyNode.scrollLeft;\n break;\n }\n styles[key] = Math.floor(value) + 'px';\n });\n return styles;\n }\n\n function prepareOutAnimation() {\n var animator = $animateCss(clone, {\n addClass: NG_OUT_ANCHOR_CLASS_NAME,\n delay: true,\n from: calculateAnchorStyles(outAnchor)\n });\n\n // read the comment within `prepareRegularAnimation` to understand\n // why this check is necessary\n return animator.$$willAnimate ? animator : null;\n }\n\n function getClassVal(element) {\n return element.attr('class') || '';\n }\n\n function prepareInAnimation() {\n var endingClasses = filterCssClasses(getClassVal(inAnchor));\n var toAdd = getUniqueValues(endingClasses, startingClasses);\n var toRemove = getUniqueValues(startingClasses, endingClasses);\n\n var animator = $animateCss(clone, {\n to: calculateAnchorStyles(inAnchor),\n addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd,\n removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove,\n delay: true\n });\n\n // read the comment within `prepareRegularAnimation` to understand\n // why this check is necessary\n return animator.$$willAnimate ? animator : null;\n }\n\n function end() {\n clone.remove();\n outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);\n inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);\n }\n }\n\n function prepareFromToAnchorAnimation(from, to, classes, anchors) {\n var fromAnimation = prepareRegularAnimation(from, noop);\n var toAnimation = prepareRegularAnimation(to, noop);\n\n var anchorAnimations = [];\n forEach(anchors, function(anchor) {\n var outElement = anchor['out'];\n var inElement = anchor['in'];\n var animator = prepareAnchoredAnimation(classes, outElement, inElement);\n if (animator) {\n anchorAnimations.push(animator);\n }\n });\n\n // no point in doing anything when there are no elements to animate\n if (!fromAnimation && !toAnimation && anchorAnimations.length === 0) return;\n\n return {\n start: function() {\n var animationRunners = [];\n\n if (fromAnimation) {\n animationRunners.push(fromAnimation.start());\n }\n\n if (toAnimation) {\n animationRunners.push(toAnimation.start());\n }\n\n forEach(anchorAnimations, function(animation) {\n animationRunners.push(animation.start());\n });\n\n var runner = new $$AnimateRunner({\n end: endFn,\n cancel: endFn // CSS-driven animations cannot be cancelled, only ended\n });\n\n $$AnimateRunner.all(animationRunners, function(status) {\n runner.complete(status);\n });\n\n return runner;\n\n function endFn() {\n forEach(animationRunners, function(runner) {\n runner.end();\n });\n }\n }\n };\n }\n\n function prepareRegularAnimation(animationDetails) {\n var element = animationDetails.element;\n var options = animationDetails.options || {};\n\n if (animationDetails.structural) {\n options.event = animationDetails.event;\n options.structural = true;\n options.applyClassesEarly = true;\n\n // we special case the leave animation since we want to ensure that\n // the element is removed as soon as the animation is over. Otherwise\n // a flicker might appear or the element may not be removed at all\n if (animationDetails.event === 'leave') {\n options.onDone = options.domOperation;\n }\n }\n\n // We assign the preparationClasses as the actual animation event since\n // the internals of $animateCss will just suffix the event token values\n // with `-active` to trigger the animation.\n if (options.preparationClasses) {\n options.event = concatWithSpace(options.event, options.preparationClasses);\n }\n\n var animator = $animateCss(element, options);\n\n // the driver lookup code inside of $$animation attempts to spawn a\n // driver one by one until a driver returns a.$$willAnimate animator object.\n // $animateCss will always return an object, however, it will pass in\n // a flag as a hint as to whether an animation was detected or not\n return animator.$$willAnimate ? animator : null;\n }\n }];\n}];\n\n// TODO(matsko): use caching here to speed things up for detection\n// TODO(matsko): add documentation\n// by the time...\n\nvar $$AnimateJsProvider = ['$animateProvider', /** @this */ function($animateProvider) {\n this.$get = ['$injector', '$$AnimateRunner', '$$jqLite',\n function($injector, $$AnimateRunner, $$jqLite) {\n\n var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);\n // $animateJs(element, 'enter');\n return function(element, event, classes, options) {\n var animationClosed = false;\n\n // the `classes` argument is optional and if it is not used\n // then the classes will be resolved from the element's className\n // property as well as options.addClass/options.removeClass.\n if (arguments.length === 3 && isObject(classes)) {\n options = classes;\n classes = null;\n }\n\n options = prepareAnimationOptions(options);\n if (!classes) {\n classes = element.attr('class') || '';\n if (options.addClass) {\n classes += ' ' + options.addClass;\n }\n if (options.removeClass) {\n classes += ' ' + options.removeClass;\n }\n }\n\n var classesToAdd = options.addClass;\n var classesToRemove = options.removeClass;\n\n // the lookupAnimations function returns a series of animation objects that are\n // matched up with one or more of the CSS classes. These animation objects are\n // defined via the module.animation factory function. If nothing is detected then\n // we don't return anything which then makes $animation query the next driver.\n var animations = lookupAnimations(classes);\n var before, after;\n if (animations.length) {\n var afterFn, beforeFn;\n if (event === 'leave') {\n beforeFn = 'leave';\n afterFn = 'afterLeave'; // TODO(matsko): get rid of this\n } else {\n beforeFn = 'before' + event.charAt(0).toUpperCase() + event.substr(1);\n afterFn = event;\n }\n\n if (event !== 'enter' && event !== 'move') {\n before = packageAnimations(element, event, options, animations, beforeFn);\n }\n after = packageAnimations(element, event, options, animations, afterFn);\n }\n\n // no matching animations\n if (!before && !after) return;\n\n function applyOptions() {\n options.domOperation();\n applyAnimationClasses(element, options);\n }\n\n function close() {\n animationClosed = true;\n applyOptions();\n applyAnimationStyles(element, options);\n }\n\n var runner;\n\n return {\n $$willAnimate: true,\n end: function() {\n if (runner) {\n runner.end();\n } else {\n close();\n runner = new $$AnimateRunner();\n runner.complete(true);\n }\n return runner;\n },\n start: function() {\n if (runner) {\n return runner;\n }\n\n runner = new $$AnimateRunner();\n var closeActiveAnimations;\n var chain = [];\n\n if (before) {\n chain.push(function(fn) {\n closeActiveAnimations = before(fn);\n });\n }\n\n if (chain.length) {\n chain.push(function(fn) {\n applyOptions();\n fn(true);\n });\n } else {\n applyOptions();\n }\n\n if (after) {\n chain.push(function(fn) {\n closeActiveAnimations = after(fn);\n });\n }\n\n runner.setHost({\n end: function() {\n endAnimations();\n },\n cancel: function() {\n endAnimations(true);\n }\n });\n\n $$AnimateRunner.chain(chain, onComplete);\n return runner;\n\n function onComplete(success) {\n close(success);\n runner.complete(success);\n }\n\n function endAnimations(cancelled) {\n if (!animationClosed) {\n (closeActiveAnimations || noop)(cancelled);\n onComplete(cancelled);\n }\n }\n }\n };\n\n function executeAnimationFn(fn, element, event, options, onDone) {\n var args;\n switch (event) {\n case 'animate':\n args = [element, options.from, options.to, onDone];\n break;\n\n case 'setClass':\n args = [element, classesToAdd, classesToRemove, onDone];\n break;\n\n case 'addClass':\n args = [element, classesToAdd, onDone];\n break;\n\n case 'removeClass':\n args = [element, classesToRemove, onDone];\n break;\n\n default:\n args = [element, onDone];\n break;\n }\n\n args.push(options);\n\n var value = fn.apply(fn, args);\n if (value) {\n if (isFunction(value.start)) {\n value = value.start();\n }\n\n if (value instanceof $$AnimateRunner) {\n value.done(onDone);\n } else if (isFunction(value)) {\n // optional onEnd / onCancel callback\n return value;\n }\n }\n\n return noop;\n }\n\n function groupEventedAnimations(element, event, options, animations, fnName) {\n var operations = [];\n forEach(animations, function(ani) {\n var animation = ani[fnName];\n if (!animation) return;\n\n // note that all of these animations will run in parallel\n operations.push(function() {\n var runner;\n var endProgressCb;\n\n var resolved = false;\n var onAnimationComplete = function(rejected) {\n if (!resolved) {\n resolved = true;\n (endProgressCb || noop)(rejected);\n runner.complete(!rejected);\n }\n };\n\n runner = new $$AnimateRunner({\n end: function() {\n onAnimationComplete();\n },\n cancel: function() {\n onAnimationComplete(true);\n }\n });\n\n endProgressCb = executeAnimationFn(animation, element, event, options, function(result) {\n var cancelled = result === false;\n onAnimationComplete(cancelled);\n });\n\n return runner;\n });\n });\n\n return operations;\n }\n\n function packageAnimations(element, event, options, animations, fnName) {\n var operations = groupEventedAnimations(element, event, options, animations, fnName);\n if (operations.length === 0) {\n var a, b;\n if (fnName === 'beforeSetClass') {\n a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass');\n b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass');\n } else if (fnName === 'setClass') {\n a = groupEventedAnimations(element, 'removeClass', options, animations, 'removeClass');\n b = groupEventedAnimations(element, 'addClass', options, animations, 'addClass');\n }\n\n if (a) {\n operations = operations.concat(a);\n }\n if (b) {\n operations = operations.concat(b);\n }\n }\n\n if (operations.length === 0) return;\n\n // TODO(matsko): add documentation\n return function startAnimation(callback) {\n var runners = [];\n if (operations.length) {\n forEach(operations, function(animateFn) {\n runners.push(animateFn());\n });\n }\n\n if (runners.length) {\n $$AnimateRunner.all(runners, callback);\n } else {\n callback();\n }\n\n return function endFn(reject) {\n forEach(runners, function(runner) {\n if (reject) {\n runner.cancel();\n } else {\n runner.end();\n }\n });\n };\n };\n }\n };\n\n function lookupAnimations(classes) {\n classes = isArray(classes) ? classes : classes.split(' ');\n var matches = [], flagMap = {};\n for (var i = 0; i < classes.length; i++) {\n var klass = classes[i],\n animationFactory = $animateProvider.$$registeredAnimations[klass];\n if (animationFactory && !flagMap[klass]) {\n matches.push($injector.get(animationFactory));\n flagMap[klass] = true;\n }\n }\n return matches;\n }\n }];\n}];\n\nvar $$AnimateJsDriverProvider = ['$$animationProvider', /** @this */ function($$animationProvider) {\n $$animationProvider.drivers.push('$$animateJsDriver');\n this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) {\n return function initDriverFn(animationDetails) {\n if (animationDetails.from && animationDetails.to) {\n var fromAnimation = prepareAnimation(animationDetails.from);\n var toAnimation = prepareAnimation(animationDetails.to);\n if (!fromAnimation && !toAnimation) return;\n\n return {\n start: function() {\n var animationRunners = [];\n\n if (fromAnimation) {\n animationRunners.push(fromAnimation.start());\n }\n\n if (toAnimation) {\n animationRunners.push(toAnimation.start());\n }\n\n $$AnimateRunner.all(animationRunners, done);\n\n var runner = new $$AnimateRunner({\n end: endFnFactory(),\n cancel: endFnFactory()\n });\n\n return runner;\n\n function endFnFactory() {\n return function() {\n forEach(animationRunners, function(runner) {\n // at this point we cannot cancel animations for groups just yet. 1.5+\n runner.end();\n });\n };\n }\n\n function done(status) {\n runner.complete(status);\n }\n }\n };\n } else {\n return prepareAnimation(animationDetails);\n }\n };\n\n function prepareAnimation(animationDetails) {\n // TODO(matsko): make sure to check for grouped animations and delegate down to normal animations\n var element = animationDetails.element;\n var event = animationDetails.event;\n var options = animationDetails.options;\n var classes = animationDetails.classes;\n return $$animateJs(element, event, classes, options);\n }\n }];\n}];\n\nvar NG_ANIMATE_ATTR_NAME = 'data-ng-animate';\nvar NG_ANIMATE_PIN_DATA = '$ngAnimatePin';\nvar $$AnimateQueueProvider = ['$animateProvider', /** @this */ function($animateProvider) {\n var PRE_DIGEST_STATE = 1;\n var RUNNING_STATE = 2;\n var ONE_SPACE = ' ';\n\n var rules = this.rules = {\n skip: [],\n cancel: [],\n join: []\n };\n\n function getEventData(options) {\n return {\n addClass: options.addClass,\n removeClass: options.removeClass,\n from: options.from,\n to: options.to\n };\n }\n\n function makeTruthyCssClassMap(classString) {\n if (!classString) {\n return null;\n }\n\n var keys = classString.split(ONE_SPACE);\n var map = Object.create(null);\n\n forEach(keys, function(key) {\n map[key] = true;\n });\n return map;\n }\n\n function hasMatchingClasses(newClassString, currentClassString) {\n if (newClassString && currentClassString) {\n var currentClassMap = makeTruthyCssClassMap(currentClassString);\n return newClassString.split(ONE_SPACE).some(function(className) {\n return currentClassMap[className];\n });\n }\n }\n\n function isAllowed(ruleType, currentAnimation, previousAnimation) {\n return rules[ruleType].some(function(fn) {\n return fn(currentAnimation, previousAnimation);\n });\n }\n\n function hasAnimationClasses(animation, and) {\n var a = (animation.addClass || '').length > 0;\n var b = (animation.removeClass || '').length > 0;\n return and ? a && b : a || b;\n }\n\n rules.join.push(function(newAnimation, currentAnimation) {\n // if the new animation is class-based then we can just tack that on\n return !newAnimation.structural && hasAnimationClasses(newAnimation);\n });\n\n rules.skip.push(function(newAnimation, currentAnimation) {\n // there is no need to animate anything if no classes are being added and\n // there is no structural animation that will be triggered\n return !newAnimation.structural && !hasAnimationClasses(newAnimation);\n });\n\n rules.skip.push(function(newAnimation, currentAnimation) {\n // why should we trigger a new structural animation if the element will\n // be removed from the DOM anyway?\n return currentAnimation.event === 'leave' && newAnimation.structural;\n });\n\n rules.skip.push(function(newAnimation, currentAnimation) {\n // if there is an ongoing current animation then don't even bother running the class-based animation\n return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural;\n });\n\n rules.cancel.push(function(newAnimation, currentAnimation) {\n // there can never be two structural animations running at the same time\n return currentAnimation.structural && newAnimation.structural;\n });\n\n rules.cancel.push(function(newAnimation, currentAnimation) {\n // if the previous animation is already running, but the new animation will\n // be triggered, but the new animation is structural\n return currentAnimation.state === RUNNING_STATE && newAnimation.structural;\n });\n\n rules.cancel.push(function(newAnimation, currentAnimation) {\n // cancel the animation if classes added / removed in both animation cancel each other out,\n // but only if the current animation isn't structural\n\n if (currentAnimation.structural) return false;\n\n var nA = newAnimation.addClass;\n var nR = newAnimation.removeClass;\n var cA = currentAnimation.addClass;\n var cR = currentAnimation.removeClass;\n\n // early detection to save the global CPU shortage :)\n if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) {\n return false;\n }\n\n return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA);\n });\n\n this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$Map',\n '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow',\n '$$isDocumentHidden',\n function($$rAF, $rootScope, $rootElement, $document, $$Map,\n $$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow,\n $$isDocumentHidden) {\n\n var activeAnimationsLookup = new $$Map();\n var disabledElementsLookup = new $$Map();\n var animationsEnabled = null;\n\n function removeFromDisabledElementsLookup(evt) {\n disabledElementsLookup.delete(evt.target);\n }\n\n function postDigestTaskFactory() {\n var postDigestCalled = false;\n return function(fn) {\n // we only issue a call to postDigest before\n // it has first passed. This prevents any callbacks\n // from not firing once the animation has completed\n // since it will be out of the digest cycle.\n if (postDigestCalled) {\n fn();\n } else {\n $rootScope.$$postDigest(function() {\n postDigestCalled = true;\n fn();\n });\n }\n };\n }\n\n // Wait until all directive and route-related templates are downloaded and\n // compiled. The $templateRequest.totalPendingRequests variable keeps track of\n // all of the remote templates being currently downloaded. If there are no\n // templates currently downloading then the watcher will still fire anyway.\n var deregisterWatch = $rootScope.$watch(\n function() { return $templateRequest.totalPendingRequests === 0; },\n function(isEmpty) {\n if (!isEmpty) return;\n deregisterWatch();\n\n // Now that all templates have been downloaded, $animate will wait until\n // the post digest queue is empty before enabling animations. By having two\n // calls to $postDigest calls we can ensure that the flag is enabled at the\n // very end of the post digest queue. Since all of the animations in $animate\n // use $postDigest, it's important that the code below executes at the end.\n // This basically means that the page is fully downloaded and compiled before\n // any animations are triggered.\n $rootScope.$$postDigest(function() {\n $rootScope.$$postDigest(function() {\n // we check for null directly in the event that the application already called\n // .enabled() with whatever arguments that it provided it with\n if (animationsEnabled === null) {\n animationsEnabled = true;\n }\n });\n });\n }\n );\n\n var callbackRegistry = Object.create(null);\n\n // remember that the `customFilter`/`classNameFilter` are set during the\n // provider/config stage therefore we can optimize here and setup helper functions\n var customFilter = $animateProvider.customFilter();\n var classNameFilter = $animateProvider.classNameFilter();\n var returnTrue = function() { return true; };\n\n var isAnimatableByFilter = customFilter || returnTrue;\n var isAnimatableClassName = !classNameFilter ? returnTrue : function(node, options) {\n var className = [node.getAttribute('class'), options.addClass, options.removeClass].join(' ');\n return classNameFilter.test(className);\n };\n\n var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);\n\n function normalizeAnimationDetails(element, animation) {\n return mergeAnimationDetails(element, animation, {});\n }\n\n // IE9-11 has no method \"contains\" in SVG element and in Node.prototype. Bug #10259.\n var contains = window.Node.prototype.contains || /** @this */ function(arg) {\n // eslint-disable-next-line no-bitwise\n return this === arg || !!(this.compareDocumentPosition(arg) & 16);\n };\n\n function findCallbacks(targetParentNode, targetNode, event) {\n var matches = [];\n var entries = callbackRegistry[event];\n if (entries) {\n forEach(entries, function(entry) {\n if (contains.call(entry.node, targetNode)) {\n matches.push(entry.callback);\n } else if (event === 'leave' && contains.call(entry.node, targetParentNode)) {\n matches.push(entry.callback);\n }\n });\n }\n\n return matches;\n }\n\n function filterFromRegistry(list, matchContainer, matchCallback) {\n var containerNode = extractElementNode(matchContainer);\n return list.filter(function(entry) {\n var isMatch = entry.node === containerNode &&\n (!matchCallback || entry.callback === matchCallback);\n return !isMatch;\n });\n }\n\n function cleanupEventListeners(phase, node) {\n if (phase === 'close' && !node.parentNode) {\n // If the element is not attached to a parentNode, it has been removed by\n // the domOperation, and we can safely remove the event callbacks\n $animate.off(node);\n }\n }\n\n var $animate = {\n on: function(event, container, callback) {\n var node = extractElementNode(container);\n callbackRegistry[event] = callbackRegistry[event] || [];\n callbackRegistry[event].push({\n node: node,\n callback: callback\n });\n\n // Remove the callback when the element is removed from the DOM\n jqLite(container).on('$destroy', function() {\n var animationDetails = activeAnimationsLookup.get(node);\n\n if (!animationDetails) {\n // If there's an animation ongoing, the callback calling code will remove\n // the event listeners. If we'd remove here, the callbacks would be removed\n // before the animation ends\n $animate.off(event, container, callback);\n }\n });\n },\n\n off: function(event, container, callback) {\n if (arguments.length === 1 && !isString(arguments[0])) {\n container = arguments[0];\n for (var eventType in callbackRegistry) {\n callbackRegistry[eventType] = filterFromRegistry(callbackRegistry[eventType], container);\n }\n\n return;\n }\n\n var entries = callbackRegistry[event];\n if (!entries) return;\n\n callbackRegistry[event] = arguments.length === 1\n ? null\n : filterFromRegistry(entries, container, callback);\n },\n\n pin: function(element, parentElement) {\n assertArg(isElement(element), 'element', 'not an element');\n assertArg(isElement(parentElement), 'parentElement', 'not an element');\n element.data(NG_ANIMATE_PIN_DATA, parentElement);\n },\n\n push: function(element, event, options, domOperation) {\n options = options || {};\n options.domOperation = domOperation;\n return queueAnimation(element, event, options);\n },\n\n // this method has four signatures:\n // () - global getter\n // (bool) - global setter\n // (element) - element getter\n // (element, bool) - element setter\n enabled: function(element, bool) {\n var argCount = arguments.length;\n\n if (argCount === 0) {\n // () - Global getter\n bool = !!animationsEnabled;\n } else {\n var hasElement = isElement(element);\n\n if (!hasElement) {\n // (bool) - Global setter\n bool = animationsEnabled = !!element;\n } else {\n var node = getDomNode(element);\n\n if (argCount === 1) {\n // (element) - Element getter\n bool = !disabledElementsLookup.get(node);\n } else {\n // (element, bool) - Element setter\n if (!disabledElementsLookup.has(node)) {\n // The element is added to the map for the first time.\n // Create a listener to remove it on `$destroy` (to avoid memory leak).\n jqLite(element).on('$destroy', removeFromDisabledElementsLookup);\n }\n disabledElementsLookup.set(node, !bool);\n }\n }\n }\n\n return bool;\n }\n };\n\n return $animate;\n\n function queueAnimation(originalElement, event, initialOptions) {\n // we always make a copy of the options since\n // there should never be any side effects on\n // the input data when running `$animateCss`.\n var options = copy(initialOptions);\n\n var element = stripCommentsFromElement(originalElement);\n var node = getDomNode(element);\n var parentNode = node && node.parentNode;\n\n options = prepareAnimationOptions(options);\n\n // we create a fake runner with a working promise.\n // These methods will become available after the digest has passed\n var runner = new $$AnimateRunner();\n\n // this is used to trigger callbacks in postDigest mode\n var runInNextPostDigestOrNow = postDigestTaskFactory();\n\n if (isArray(options.addClass)) {\n options.addClass = options.addClass.join(' ');\n }\n\n if (options.addClass && !isString(options.addClass)) {\n options.addClass = null;\n }\n\n if (isArray(options.removeClass)) {\n options.removeClass = options.removeClass.join(' ');\n }\n\n if (options.removeClass && !isString(options.removeClass)) {\n options.removeClass = null;\n }\n\n if (options.from && !isObject(options.from)) {\n options.from = null;\n }\n\n if (options.to && !isObject(options.to)) {\n options.to = null;\n }\n\n // If animations are hard-disabled for the whole application there is no need to continue.\n // There are also situations where a directive issues an animation for a jqLite wrapper that\n // contains only comment nodes. In this case, there is no way we can perform an animation.\n if (!animationsEnabled ||\n !node ||\n !isAnimatableByFilter(node, event, initialOptions) ||\n !isAnimatableClassName(node, options)) {\n close();\n return runner;\n }\n\n var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;\n\n var documentHidden = $$isDocumentHidden();\n\n // This is a hard disable of all animations the element itself, therefore there is no need to\n // continue further past this point if not enabled\n // Animations are also disabled if the document is currently hidden (page is not visible\n // to the user), because browsers slow down or do not flush calls to requestAnimationFrame\n var skipAnimations = documentHidden || disabledElementsLookup.get(node);\n var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};\n var hasExistingAnimation = !!existingAnimation.state;\n\n // there is no point in traversing the same collection of parent ancestors if a followup\n // animation will be run on the same element that already did all that checking work\n if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state !== PRE_DIGEST_STATE)) {\n skipAnimations = !areAnimationsAllowed(node, parentNode, event);\n }\n\n if (skipAnimations) {\n // Callbacks should fire even if the document is hidden (regression fix for issue #14120)\n if (documentHidden) notifyProgress(runner, event, 'start', getEventData(options));\n close();\n if (documentHidden) notifyProgress(runner, event, 'close', getEventData(options));\n return runner;\n }\n\n if (isStructural) {\n closeChildAnimations(node);\n }\n\n var newAnimation = {\n structural: isStructural,\n element: element,\n event: event,\n addClass: options.addClass,\n removeClass: options.removeClass,\n close: close,\n options: options,\n runner: runner\n };\n\n if (hasExistingAnimation) {\n var skipAnimationFlag = isAllowed('skip', newAnimation, existingAnimation);\n if (skipAnimationFlag) {\n if (existingAnimation.state === RUNNING_STATE) {\n close();\n return runner;\n } else {\n mergeAnimationDetails(element, existingAnimation, newAnimation);\n return existingAnimation.runner;\n }\n }\n var cancelAnimationFlag = isAllowed('cancel', newAnimation, existingAnimation);\n if (cancelAnimationFlag) {\n if (existingAnimation.state === RUNNING_STATE) {\n // this will end the animation right away and it is safe\n // to do so since the animation is already running and the\n // runner callback code will run in async\n existingAnimation.runner.end();\n } else if (existingAnimation.structural) {\n // this means that the animation is queued into a digest, but\n // hasn't started yet. Therefore it is safe to run the close\n // method which will call the runner methods in async.\n existingAnimation.close();\n } else {\n // this will merge the new animation options into existing animation options\n mergeAnimationDetails(element, existingAnimation, newAnimation);\n\n return existingAnimation.runner;\n }\n } else {\n // a joined animation means that this animation will take over the existing one\n // so an example would involve a leave animation taking over an enter. Then when\n // the postDigest kicks in the enter will be ignored.\n var joinAnimationFlag = isAllowed('join', newAnimation, existingAnimation);\n if (joinAnimationFlag) {\n if (existingAnimation.state === RUNNING_STATE) {\n normalizeAnimationDetails(element, newAnimation);\n } else {\n applyGeneratedPreparationClasses($$jqLite, element, isStructural ? event : null, options);\n\n event = newAnimation.event = existingAnimation.event;\n options = mergeAnimationDetails(element, existingAnimation, newAnimation);\n\n //we return the same runner since only the option values of this animation will\n //be fed into the `existingAnimation`.\n return existingAnimation.runner;\n }\n }\n }\n } else {\n // normalization in this case means that it removes redundant CSS classes that\n // already exist (addClass) or do not exist (removeClass) on the element\n normalizeAnimationDetails(element, newAnimation);\n }\n\n // when the options are merged and cleaned up we may end up not having to do\n // an animation at all, therefore we should check this before issuing a post\n // digest callback. Structural animations will always run no matter what.\n var isValidAnimation = newAnimation.structural;\n if (!isValidAnimation) {\n // animate (from/to) can be quickly checked first, otherwise we check if any classes are present\n isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0)\n || hasAnimationClasses(newAnimation);\n }\n\n if (!isValidAnimation) {\n close();\n clearElementAnimationState(node);\n return runner;\n }\n\n // the counter keeps track of cancelled animations\n var counter = (existingAnimation.counter || 0) + 1;\n newAnimation.counter = counter;\n\n markElementAnimationState(node, PRE_DIGEST_STATE, newAnimation);\n\n $rootScope.$$postDigest(function() {\n // It is possible that the DOM nodes inside `originalElement` have been replaced. This can\n // happen if the animated element is a transcluded clone and also has a `templateUrl`\n // directive on it. Therefore, we must recreate `element` in order to interact with the\n // actual DOM nodes.\n // Note: We still need to use the old `node` for certain things, such as looking up in\n // HashMaps where it was used as the key.\n\n element = stripCommentsFromElement(originalElement);\n\n var animationDetails = activeAnimationsLookup.get(node);\n var animationCancelled = !animationDetails;\n animationDetails = animationDetails || {};\n\n // if addClass/removeClass is called before something like enter then the\n // registered parent element may not be present. The code below will ensure\n // that a final value for parent element is obtained\n var parentElement = element.parent() || [];\n\n // animate/structural/class-based animations all have requirements. Otherwise there\n // is no point in performing an animation. The parent node must also be set.\n var isValidAnimation = parentElement.length > 0\n && (animationDetails.event === 'animate'\n || animationDetails.structural\n || hasAnimationClasses(animationDetails));\n\n // this means that the previous animation was cancelled\n // even if the follow-up animation is the same event\n if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) {\n // if another animation did not take over then we need\n // to make sure that the domOperation and options are\n // handled accordingly\n if (animationCancelled) {\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n }\n\n // if the event changed from something like enter to leave then we do\n // it, otherwise if it's the same then the end result will be the same too\n if (animationCancelled || (isStructural && animationDetails.event !== event)) {\n options.domOperation();\n runner.end();\n }\n\n // in the event that the element animation was not cancelled or a follow-up animation\n // isn't allowed to animate from here then we need to clear the state of the element\n // so that any future animations won't read the expired animation data.\n if (!isValidAnimation) {\n clearElementAnimationState(node);\n }\n\n return;\n }\n\n // this combined multiple class to addClass / removeClass into a setClass event\n // so long as a structural event did not take over the animation\n event = !animationDetails.structural && hasAnimationClasses(animationDetails, true)\n ? 'setClass'\n : animationDetails.event;\n\n markElementAnimationState(node, RUNNING_STATE);\n var realRunner = $$animation(element, event, animationDetails.options);\n\n // this will update the runner's flow-control events based on\n // the `realRunner` object.\n runner.setHost(realRunner);\n notifyProgress(runner, event, 'start', getEventData(options));\n\n realRunner.done(function(status) {\n close(!status);\n var animationDetails = activeAnimationsLookup.get(node);\n if (animationDetails && animationDetails.counter === counter) {\n clearElementAnimationState(node);\n }\n notifyProgress(runner, event, 'close', getEventData(options));\n });\n });\n\n return runner;\n\n function notifyProgress(runner, event, phase, data) {\n runInNextPostDigestOrNow(function() {\n var callbacks = findCallbacks(parentNode, node, event);\n if (callbacks.length) {\n // do not optimize this call here to RAF because\n // we don't know how heavy the callback code here will\n // be and if this code is buffered then this can\n // lead to a performance regression.\n $$rAF(function() {\n forEach(callbacks, function(callback) {\n callback(element, phase, data);\n });\n cleanupEventListeners(phase, node);\n });\n } else {\n cleanupEventListeners(phase, node);\n }\n });\n runner.progress(event, phase, data);\n }\n\n function close(reject) {\n clearGeneratedClasses(element, options);\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n options.domOperation();\n runner.complete(!reject);\n }\n }\n\n function closeChildAnimations(node) {\n var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']');\n forEach(children, function(child) {\n var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME), 10);\n var animationDetails = activeAnimationsLookup.get(child);\n if (animationDetails) {\n switch (state) {\n case RUNNING_STATE:\n animationDetails.runner.end();\n /* falls through */\n case PRE_DIGEST_STATE:\n activeAnimationsLookup.delete(child);\n break;\n }\n }\n });\n }\n\n function clearElementAnimationState(node) {\n node.removeAttribute(NG_ANIMATE_ATTR_NAME);\n activeAnimationsLookup.delete(node);\n }\n\n /**\n * This fn returns false if any of the following is true:\n * a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed\n * b) a parent element has an ongoing structural animation, and animateChildren is false\n * c) the element is not a child of the body\n * d) the element is not a child of the $rootElement\n */\n function areAnimationsAllowed(node, parentNode, event) {\n var bodyNode = $document[0].body;\n var rootNode = getDomNode($rootElement);\n\n var bodyNodeDetected = (node === bodyNode) || node.nodeName === 'HTML';\n var rootNodeDetected = (node === rootNode);\n var parentAnimationDetected = false;\n var elementDisabled = disabledElementsLookup.get(node);\n var animateChildren;\n\n var parentHost = jqLite.data(node, NG_ANIMATE_PIN_DATA);\n if (parentHost) {\n parentNode = getDomNode(parentHost);\n }\n\n while (parentNode) {\n if (!rootNodeDetected) {\n // AngularJS doesn't want to attempt to animate elements outside of the application\n // therefore we need to ensure that the rootElement is an ancestor of the current element\n rootNodeDetected = (parentNode === rootNode);\n }\n\n if (parentNode.nodeType !== ELEMENT_NODE) {\n // no point in inspecting the #document element\n break;\n }\n\n var details = activeAnimationsLookup.get(parentNode) || {};\n // either an enter, leave or move animation will commence\n // therefore we can't allow any animations to take place\n // but if a parent animation is class-based then that's ok\n if (!parentAnimationDetected) {\n var parentNodeDisabled = disabledElementsLookup.get(parentNode);\n\n if (parentNodeDisabled === true && elementDisabled !== false) {\n // disable animations if the user hasn't explicitly enabled animations on the\n // current element\n elementDisabled = true;\n // element is disabled via parent element, no need to check anything else\n break;\n } else if (parentNodeDisabled === false) {\n elementDisabled = false;\n }\n parentAnimationDetected = details.structural;\n }\n\n if (isUndefined(animateChildren) || animateChildren === true) {\n var value = jqLite.data(parentNode, NG_ANIMATE_CHILDREN_DATA);\n if (isDefined(value)) {\n animateChildren = value;\n }\n }\n\n // there is no need to continue traversing at this point\n if (parentAnimationDetected && animateChildren === false) break;\n\n if (!bodyNodeDetected) {\n // we also need to ensure that the element is or will be a part of the body element\n // otherwise it is pointless to even issue an animation to be rendered\n bodyNodeDetected = (parentNode === bodyNode);\n }\n\n if (bodyNodeDetected && rootNodeDetected) {\n // If both body and root have been found, any other checks are pointless,\n // as no animation data should live outside the application\n break;\n }\n\n if (!rootNodeDetected) {\n // If `rootNode` is not detected, check if `parentNode` is pinned to another element\n parentHost = jqLite.data(parentNode, NG_ANIMATE_PIN_DATA);\n if (parentHost) {\n // The pin target element becomes the next parent element\n parentNode = getDomNode(parentHost);\n continue;\n }\n }\n\n parentNode = parentNode.parentNode;\n }\n\n var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true;\n return allowAnimation && rootNodeDetected && bodyNodeDetected;\n }\n\n function markElementAnimationState(node, state, details) {\n details = details || {};\n details.state = state;\n\n node.setAttribute(NG_ANIMATE_ATTR_NAME, state);\n\n var oldValue = activeAnimationsLookup.get(node);\n var newValue = oldValue\n ? extend(oldValue, details)\n : details;\n activeAnimationsLookup.set(node, newValue);\n }\n }];\n}];\n\n/** @this */\nvar $$AnimateCacheProvider = function() {\n\n var KEY = '$$ngAnimateParentKey';\n var parentCounter = 0;\n var cache = Object.create(null);\n\n this.$get = [function() {\n return {\n cacheKey: function(node, method, addClass, removeClass) {\n var parentNode = node.parentNode;\n var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter);\n var parts = [parentID, method, node.getAttribute('class')];\n if (addClass) {\n parts.push(addClass);\n }\n if (removeClass) {\n parts.push(removeClass);\n }\n return parts.join(' ');\n },\n\n containsCachedAnimationWithoutDuration: function(key) {\n var entry = cache[key];\n\n // nothing cached, so go ahead and animate\n // otherwise it should be a valid animation\n return (entry && !entry.isValid) || false;\n },\n\n flush: function() {\n cache = Object.create(null);\n },\n\n count: function(key) {\n var entry = cache[key];\n return entry ? entry.total : 0;\n },\n\n get: function(key) {\n var entry = cache[key];\n return entry && entry.value;\n },\n\n put: function(key, value, isValid) {\n if (!cache[key]) {\n cache[key] = { total: 1, value: value, isValid: isValid };\n } else {\n cache[key].total++;\n cache[key].value = value;\n }\n }\n };\n }];\n};\n\n/* exported $$AnimationProvider */\n\nvar $$AnimationProvider = ['$animateProvider', /** @this */ function($animateProvider) {\n var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';\n\n var drivers = this.drivers = [];\n\n var RUNNER_STORAGE_KEY = '$$animationRunner';\n var PREPARE_CLASSES_KEY = '$$animatePrepareClasses';\n\n function setRunner(element, runner) {\n element.data(RUNNER_STORAGE_KEY, runner);\n }\n\n function removeRunner(element) {\n element.removeData(RUNNER_STORAGE_KEY);\n }\n\n function getRunner(element) {\n return element.data(RUNNER_STORAGE_KEY);\n }\n\n this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$Map', '$$rAFScheduler', '$$animateCache',\n function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$Map, $$rAFScheduler, $$animateCache) {\n\n var animationQueue = [];\n var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);\n\n function sortAnimations(animations) {\n var tree = { children: [] };\n var i, lookup = new $$Map();\n\n // this is done first beforehand so that the map\n // is filled with a list of the elements that will be animated\n for (i = 0; i < animations.length; i++) {\n var animation = animations[i];\n lookup.set(animation.domNode, animations[i] = {\n domNode: animation.domNode,\n element: animation.element,\n fn: animation.fn,\n children: []\n });\n }\n\n for (i = 0; i < animations.length; i++) {\n processNode(animations[i]);\n }\n\n return flatten(tree);\n\n function processNode(entry) {\n if (entry.processed) return entry;\n entry.processed = true;\n\n var elementNode = entry.domNode;\n var parentNode = elementNode.parentNode;\n lookup.set(elementNode, entry);\n\n var parentEntry;\n while (parentNode) {\n parentEntry = lookup.get(parentNode);\n if (parentEntry) {\n if (!parentEntry.processed) {\n parentEntry = processNode(parentEntry);\n }\n break;\n }\n parentNode = parentNode.parentNode;\n }\n\n (parentEntry || tree).children.push(entry);\n return entry;\n }\n\n function flatten(tree) {\n var result = [];\n var queue = [];\n var i;\n\n for (i = 0; i < tree.children.length; i++) {\n queue.push(tree.children[i]);\n }\n\n var remainingLevelEntries = queue.length;\n var nextLevelEntries = 0;\n var row = [];\n\n for (i = 0; i < queue.length; i++) {\n var entry = queue[i];\n if (remainingLevelEntries <= 0) {\n remainingLevelEntries = nextLevelEntries;\n nextLevelEntries = 0;\n result.push(row);\n row = [];\n }\n row.push(entry);\n entry.children.forEach(function(childEntry) {\n nextLevelEntries++;\n queue.push(childEntry);\n });\n remainingLevelEntries--;\n }\n\n if (row.length) {\n result.push(row);\n }\n\n return result;\n }\n }\n\n // TODO(matsko): document the signature in a better way\n return function(element, event, options) {\n options = prepareAnimationOptions(options);\n var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;\n\n // there is no animation at the current moment, however\n // these runner methods will get later updated with the\n // methods leading into the driver's end/cancel methods\n // for now they just stop the animation from starting\n var runner = new $$AnimateRunner({\n end: function() { close(); },\n cancel: function() { close(true); }\n });\n\n if (!drivers.length) {\n close();\n return runner;\n }\n\n var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass));\n var tempClasses = options.tempClasses;\n if (tempClasses) {\n classes += ' ' + tempClasses;\n options.tempClasses = null;\n }\n\n if (isStructural) {\n element.data(PREPARE_CLASSES_KEY, 'ng-' + event + PREPARE_CLASS_SUFFIX);\n }\n\n setRunner(element, runner);\n\n animationQueue.push({\n // this data is used by the postDigest code and passed into\n // the driver step function\n element: element,\n classes: classes,\n event: event,\n structural: isStructural,\n options: options,\n beforeStart: beforeStart,\n close: close\n });\n\n element.on('$destroy', handleDestroyedElement);\n\n // we only want there to be one function called within the post digest\n // block. This way we can group animations for all the animations that\n // were apart of the same postDigest flush call.\n if (animationQueue.length > 1) return runner;\n\n $rootScope.$$postDigest(function() {\n var animations = [];\n forEach(animationQueue, function(entry) {\n // the element was destroyed early on which removed the runner\n // form its storage. This means we can't animate this element\n // at all and it already has been closed due to destruction.\n if (getRunner(entry.element)) {\n animations.push(entry);\n } else {\n entry.close();\n }\n });\n\n // now any future animations will be in another postDigest\n animationQueue.length = 0;\n\n var groupedAnimations = groupAnimations(animations);\n var toBeSortedAnimations = [];\n\n forEach(groupedAnimations, function(animationEntry) {\n var element = animationEntry.from ? animationEntry.from.element : animationEntry.element;\n var extraClasses = options.addClass;\n\n extraClasses = (extraClasses ? (extraClasses + ' ') : '') + NG_ANIMATE_CLASSNAME;\n var cacheKey = $$animateCache.cacheKey(element[0], animationEntry.event, extraClasses, options.removeClass);\n\n toBeSortedAnimations.push({\n element: element,\n domNode: getDomNode(element),\n fn: function triggerAnimationStart() {\n var startAnimationFn, closeFn = animationEntry.close;\n\n // in the event that we've cached the animation status for this element\n // and it's in fact an invalid animation (something that has duration = 0)\n // then we should skip all the heavy work from here on\n if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) {\n closeFn();\n return;\n }\n\n // it's important that we apply the `ng-animate` CSS class and the\n // temporary classes before we do any driver invoking since these\n // CSS classes may be required for proper CSS detection.\n animationEntry.beforeStart();\n\n // in the event that the element was removed before the digest runs or\n // during the RAF sequencing then we should not trigger the animation.\n var targetElement = animationEntry.anchors\n ? (animationEntry.from.element || animationEntry.to.element)\n : animationEntry.element;\n\n if (getRunner(targetElement)) {\n var operation = invokeFirstDriver(animationEntry);\n if (operation) {\n startAnimationFn = operation.start;\n }\n }\n\n if (!startAnimationFn) {\n closeFn();\n } else {\n var animationRunner = startAnimationFn();\n animationRunner.done(function(status) {\n closeFn(!status);\n });\n updateAnimationRunners(animationEntry, animationRunner);\n }\n }\n });\n });\n\n // we need to sort each of the animations in order of parent to child\n // relationships. This ensures that the child classes are applied at the\n // right time.\n var finalAnimations = sortAnimations(toBeSortedAnimations);\n for (var i = 0; i < finalAnimations.length; i++) {\n var innerArray = finalAnimations[i];\n for (var j = 0; j < innerArray.length; j++) {\n var entry = innerArray[j];\n var element = entry.element;\n\n // the RAFScheduler code only uses functions\n finalAnimations[i][j] = entry.fn;\n\n // the first row of elements shouldn't have a prepare-class added to them\n // since the elements are at the top of the animation hierarchy and they\n // will be applied without a RAF having to pass...\n if (i === 0) {\n element.removeData(PREPARE_CLASSES_KEY);\n continue;\n }\n\n var prepareClassName = element.data(PREPARE_CLASSES_KEY);\n if (prepareClassName) {\n $$jqLite.addClass(element, prepareClassName);\n }\n }\n }\n\n $$rAFScheduler(finalAnimations);\n });\n\n return runner;\n\n // TODO(matsko): change to reference nodes\n function getAnchorNodes(node) {\n var SELECTOR = '[' + NG_ANIMATE_REF_ATTR + ']';\n var items = node.hasAttribute(NG_ANIMATE_REF_ATTR)\n ? [node]\n : node.querySelectorAll(SELECTOR);\n var anchors = [];\n forEach(items, function(node) {\n var attr = node.getAttribute(NG_ANIMATE_REF_ATTR);\n if (attr && attr.length) {\n anchors.push(node);\n }\n });\n return anchors;\n }\n\n function groupAnimations(animations) {\n var preparedAnimations = [];\n var refLookup = {};\n forEach(animations, function(animation, index) {\n var element = animation.element;\n var node = getDomNode(element);\n var event = animation.event;\n var enterOrMove = ['enter', 'move'].indexOf(event) >= 0;\n var anchorNodes = animation.structural ? getAnchorNodes(node) : [];\n\n if (anchorNodes.length) {\n var direction = enterOrMove ? 'to' : 'from';\n\n forEach(anchorNodes, function(anchor) {\n var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR);\n refLookup[key] = refLookup[key] || {};\n refLookup[key][direction] = {\n animationID: index,\n element: jqLite(anchor)\n };\n });\n } else {\n preparedAnimations.push(animation);\n }\n });\n\n var usedIndicesLookup = {};\n var anchorGroups = {};\n forEach(refLookup, function(operations, key) {\n var from = operations.from;\n var to = operations.to;\n\n if (!from || !to) {\n // only one of these is set therefore we can't have an\n // anchor animation since all three pieces are required\n var index = from ? from.animationID : to.animationID;\n var indexKey = index.toString();\n if (!usedIndicesLookup[indexKey]) {\n usedIndicesLookup[indexKey] = true;\n preparedAnimations.push(animations[index]);\n }\n return;\n }\n\n var fromAnimation = animations[from.animationID];\n var toAnimation = animations[to.animationID];\n var lookupKey = from.animationID.toString();\n if (!anchorGroups[lookupKey]) {\n var group = anchorGroups[lookupKey] = {\n structural: true,\n beforeStart: function() {\n fromAnimation.beforeStart();\n toAnimation.beforeStart();\n },\n close: function() {\n fromAnimation.close();\n toAnimation.close();\n },\n classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes),\n from: fromAnimation,\n to: toAnimation,\n anchors: [] // TODO(matsko): change to reference nodes\n };\n\n // the anchor animations require that the from and to elements both have at least\n // one shared CSS class which effectively marries the two elements together to use\n // the same animation driver and to properly sequence the anchor animation.\n if (group.classes.length) {\n preparedAnimations.push(group);\n } else {\n preparedAnimations.push(fromAnimation);\n preparedAnimations.push(toAnimation);\n }\n }\n\n anchorGroups[lookupKey].anchors.push({\n 'out': from.element, 'in': to.element\n });\n });\n\n return preparedAnimations;\n }\n\n function cssClassesIntersection(a,b) {\n a = a.split(' ');\n b = b.split(' ');\n var matches = [];\n\n for (var i = 0; i < a.length; i++) {\n var aa = a[i];\n if (aa.substring(0,3) === 'ng-') continue;\n\n for (var j = 0; j < b.length; j++) {\n if (aa === b[j]) {\n matches.push(aa);\n break;\n }\n }\n }\n\n return matches.join(' ');\n }\n\n function invokeFirstDriver(animationDetails) {\n // we loop in reverse order since the more general drivers (like CSS and JS)\n // may attempt more elements, but custom drivers are more particular\n for (var i = drivers.length - 1; i >= 0; i--) {\n var driverName = drivers[i];\n var factory = $injector.get(driverName);\n var driver = factory(animationDetails);\n if (driver) {\n return driver;\n }\n }\n }\n\n function beforeStart() {\n tempClasses = (tempClasses ? (tempClasses + ' ') : '') + NG_ANIMATE_CLASSNAME;\n $$jqLite.addClass(element, tempClasses);\n\n var prepareClassName = element.data(PREPARE_CLASSES_KEY);\n if (prepareClassName) {\n $$jqLite.removeClass(element, prepareClassName);\n prepareClassName = null;\n }\n }\n\n function updateAnimationRunners(animation, newRunner) {\n if (animation.from && animation.to) {\n update(animation.from.element);\n update(animation.to.element);\n } else {\n update(animation.element);\n }\n\n function update(element) {\n var runner = getRunner(element);\n if (runner) runner.setHost(newRunner);\n }\n }\n\n function handleDestroyedElement() {\n var runner = getRunner(element);\n if (runner && (event !== 'leave' || !options.$$domOperationFired)) {\n runner.end();\n }\n }\n\n function close(rejected) {\n element.off('$destroy', handleDestroyedElement);\n removeRunner(element);\n\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n options.domOperation();\n\n if (tempClasses) {\n $$jqLite.removeClass(element, tempClasses);\n }\n\n runner.complete(!rejected);\n }\n };\n }];\n}];\n\n/**\n * @ngdoc directive\n * @name ngAnimateSwap\n * @restrict A\n * @scope\n *\n * @description\n *\n * ngAnimateSwap is a animation-oriented directive that allows for the container to\n * be removed and entered in whenever the associated expression changes. A\n * common usecase for this directive is a rotating banner or slider component which\n * contains one image being present at a time. When the active image changes\n * then the old image will perform a `leave` animation and the new element\n * will be inserted via an `enter` animation.\n *\n * @animations\n * | Animation | Occurs |\n * |----------------------------------|--------------------------------------|\n * | {@link ng.$animate#enter enter} | when the new element is inserted to the DOM |\n * | {@link ng.$animate#leave leave} | when the old element is removed from the DOM |\n *\n * @example\n * \n * \n *
\n *
\n * {{ number }}\n *
\n *
\n *
\n * \n * angular.module('ngAnimateSwapExample', ['ngAnimate'])\n * .controller('AppCtrl', ['$scope', '$interval', function($scope, $interval) {\n * $scope.number = 0;\n * $interval(function() {\n * $scope.number++;\n * }, 1000);\n *\n * var colors = ['red','blue','green','yellow','orange'];\n * $scope.colorClass = function(number) {\n * return colors[number % colors.length];\n * };\n * }]);\n * \n * \n * .container {\n * height:250px;\n * width:250px;\n * position:relative;\n * overflow:hidden;\n * border:2px solid black;\n * }\n * .container .cell {\n * font-size:150px;\n * text-align:center;\n * line-height:250px;\n * position:absolute;\n * top:0;\n * left:0;\n * right:0;\n * border-bottom:2px solid black;\n * }\n * .swap-animation.ng-enter, .swap-animation.ng-leave {\n * transition:0.5s linear all;\n * }\n * .swap-animation.ng-enter {\n * top:-250px;\n * }\n * .swap-animation.ng-enter-active {\n * top:0px;\n * }\n * .swap-animation.ng-leave {\n * top:0px;\n * }\n * .swap-animation.ng-leave-active {\n * top:250px;\n * }\n * .red { background:red; }\n * .green { background:green; }\n * .blue { background:blue; }\n * .yellow { background:yellow; }\n * .orange { background:orange; }\n * \n *
\n */\nvar ngAnimateSwapDirective = ['$animate', function($animate) {\n return {\n restrict: 'A',\n transclude: 'element',\n terminal: true,\n priority: 550, // We use 550 here to ensure that the directive is caught before others,\n // but after `ngIf` (at priority 600).\n link: function(scope, $element, attrs, ctrl, $transclude) {\n var previousElement, previousScope;\n scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) {\n if (previousElement) {\n $animate.leave(previousElement);\n }\n if (previousScope) {\n previousScope.$destroy();\n previousScope = null;\n }\n if (value || value === 0) {\n $transclude(function(clone, childScope) {\n previousElement = clone;\n previousScope = childScope;\n $animate.enter(clone, null, $element);\n });\n }\n });\n }\n };\n}];\n\n/**\n * @ngdoc module\n * @name ngAnimate\n * @description\n *\n * The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via\n * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an AngularJS app.\n *\n * ## Usage\n * Simply put, there are two ways to make use of animations when ngAnimate is used: by using **CSS** and **JavaScript**. The former works purely based\n * using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via `module.animation()`. For\n * both CSS and JS animations the sole requirement is to have a matching `CSS class` that exists both in the registered animation and within\n * the HTML element that the animation will be triggered on.\n *\n * ## Directive Support\n * The following directives are \"animation aware\":\n *\n * | Directive | Supported Animations |\n * |-------------------------------------------------------------------------------|---------------------------------------------------------------------------|\n * | {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |\n * | {@link ngAnimate.directive:ngAnimateSwap#animations ngAnimateSwap} | enter and leave |\n * | {@link ng.directive:ngClass#animations ngClass / {{class}​}} | add and remove |\n * | {@link ng.directive:ngClassEven#animations ngClassEven} | add and remove |\n * | {@link ng.directive:ngClassOdd#animations ngClassOdd} | add and remove |\n * | {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |\n * | {@link ng.directive:ngIf#animations ngIf} | enter and leave |\n * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |\n * | {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |\n * | {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |\n * | {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |\n * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |\n * | {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |\n * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |\n * | {@link ngRoute.directive:ngView#animations ngView} | enter and leave |\n *\n * (More information can be found by visiting the documentation associated with each directive.)\n *\n * For a full breakdown of the steps involved during each animation event, refer to the\n * {@link ng.$animate `$animate` API docs}.\n *\n * ## CSS-based Animations\n *\n * CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML\n * and CSS code we can create an animation that will be picked up by AngularJS when an underlying directive performs an operation.\n *\n * The example below shows how an `enter` animation can be made possible on an element using `ng-if`:\n *\n * ```html\n *
\n * Fade me in out\n *
\n * \n * \n * ```\n *\n * Notice the CSS class **fade**? We can now create the CSS transition code that references this class:\n *\n * ```css\n * /* The starting CSS styles for the enter animation */\n * .fade.ng-enter {\n * transition:0.5s linear all;\n * opacity:0;\n * }\n *\n * /* The finishing CSS styles for the enter animation */\n * .fade.ng-enter.ng-enter-active {\n * opacity:1;\n * }\n * ```\n *\n * The key thing to remember here is that, depending on the animation event (which each of the directives above trigger depending on what's going on) two\n * generated CSS classes will be applied to the element; in the example above we have `.ng-enter` and `.ng-enter-active`. For CSS transitions, the transition\n * code **must** be defined within the starting CSS class (in this case `.ng-enter`). The destination class is what the transition will animate towards.\n *\n * If for example we wanted to create animations for `leave` and `move` (ngRepeat triggers move) then we can do so using the same CSS naming conventions:\n *\n * ```css\n * /* now the element will fade out before it is removed from the DOM */\n * .fade.ng-leave {\n * transition:0.5s linear all;\n * opacity:1;\n * }\n * .fade.ng-leave.ng-leave-active {\n * opacity:0;\n * }\n * ```\n *\n * We can also make use of **CSS Keyframes** by referencing the keyframe animation within the starting CSS class:\n *\n * ```css\n * /* there is no need to define anything inside of the destination\n * CSS class since the keyframe will take charge of the animation */\n * .fade.ng-leave {\n * animation: my_fade_animation 0.5s linear;\n * -webkit-animation: my_fade_animation 0.5s linear;\n * }\n *\n * @keyframes my_fade_animation {\n * from { opacity:1; }\n * to { opacity:0; }\n * }\n *\n * @-webkit-keyframes my_fade_animation {\n * from { opacity:1; }\n * to { opacity:0; }\n * }\n * ```\n *\n * Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element.\n *\n * ### CSS Class-based Animations\n *\n * Class-based animations (animations that are triggered via `ngClass`, `ngShow`, `ngHide` and some other directives) have a slightly different\n * naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added\n * and removed.\n *\n * For example if we wanted to do a CSS animation for `ngHide` then we place an animation on the `.ng-hide` CSS class:\n *\n * ```html\n *
\n * Show and hide me\n *
\n * \n *\n * \n * ```\n *\n * All that is going on here with ngShow/ngHide behind the scenes is the `.ng-hide` class is added/removed (when the hidden state is valid). Since\n * ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest.\n *\n * In addition the addition and removal of the CSS class, ngAnimate also provides two helper methods that we can use to further decorate the animation\n * with CSS styles.\n *\n * ```html\n *
\n * Highlight this box\n *
\n * \n *\n * \n * ```\n *\n * We can also make use of CSS keyframes by placing them within the CSS classes.\n *\n *\n * ### CSS Staggering Animations\n * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a\n * curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be\n * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for\n * the animation. The style property expected within the stagger class can either be a **transition-delay** or an\n * **animation-delay** property (or both if your animation contains both transitions and keyframe animations).\n *\n * ```css\n * .my-animation.ng-enter {\n * /* standard transition code */\n * transition: 1s linear all;\n * opacity:0;\n * }\n * .my-animation.ng-enter-stagger {\n * /* this will have a 100ms delay between each successive leave animation */\n * transition-delay: 0.1s;\n *\n * /* As of 1.4.4, this must always be set: it signals ngAnimate\n * to not accidentally inherit a delay property from another CSS class */\n * transition-duration: 0s;\n *\n * /* if you are using animations instead of transitions you should configure as follows:\n * animation-delay: 0.1s;\n * animation-duration: 0s; */\n * }\n * .my-animation.ng-enter.ng-enter-active {\n * /* standard transition styles */\n * opacity:1;\n * }\n * ```\n *\n * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations\n * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this\n * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation\n * will also be reset if one or more animation frames have passed since the multiple calls to `$animate` were fired.\n *\n * The following code will issue the **ng-leave-stagger** event on the element provided:\n *\n * ```js\n * var kids = parent.children();\n *\n * $animate.leave(kids[0]); //stagger index=0\n * $animate.leave(kids[1]); //stagger index=1\n * $animate.leave(kids[2]); //stagger index=2\n * $animate.leave(kids[3]); //stagger index=3\n * $animate.leave(kids[4]); //stagger index=4\n *\n * window.requestAnimationFrame(function() {\n * //stagger has reset itself\n * $animate.leave(kids[5]); //stagger index=0\n * $animate.leave(kids[6]); //stagger index=1\n *\n * $scope.$digest();\n * });\n * ```\n *\n * Stagger animations are currently only supported within CSS-defined animations.\n *\n * ### The `ng-animate` CSS class\n *\n * When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation.\n * This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations).\n *\n * Therefore, animations can be applied to an element using this temporary class directly via CSS.\n *\n * ```css\n * .zipper.ng-animate {\n * transition:0.5s linear all;\n * }\n * .zipper.ng-enter {\n * opacity:0;\n * }\n * .zipper.ng-enter.ng-enter-active {\n * opacity:1;\n * }\n * .zipper.ng-leave {\n * opacity:1;\n * }\n * .zipper.ng-leave.ng-leave-active {\n * opacity:0;\n * }\n * ```\n *\n * (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove\n * the CSS class once an animation has completed.)\n *\n *\n * ### The `ng-[event]-prepare` class\n *\n * This is a special class that can be used to prevent unwanted flickering / flash of content before\n * the actual animation starts. The class is added as soon as an animation is initialized, but removed\n * before the actual animation starts (after waiting for a $digest).\n * It is also only added for *structural* animations (`enter`, `move`, and `leave`).\n *\n * In practice, flickering can appear when nesting elements with structural animations such as `ngIf`\n * into elements that have class-based animations such as `ngClass`.\n *\n * ```html\n *
\n *
\n *
\n *
\n *
\n * ```\n *\n * It is possible that during the `enter` animation, the `.message` div will be briefly visible before it starts animating.\n * In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts:\n *\n * ```css\n * .message.ng-enter-prepare {\n * opacity: 0;\n * }\n * ```\n *\n * ### Animating between value changes\n *\n * Sometimes you need to animate between different expression states, whose values\n * don't necessary need to be known or referenced in CSS styles.\n * Unless possible with another {@link ngAnimate#directive-support \"animation aware\" directive},\n * that specific use case can always be covered with {@link ngAnimate.directive:ngAnimateSwap} as\n * can be seen in {@link ngAnimate.directive:ngAnimateSwap#examples this example}.\n *\n * Note that {@link ngAnimate.directive:ngAnimateSwap} is a *structural directive*, which means it\n * creates a new instance of the element (including any other/child directives it may have) and\n * links it to a new scope every time *swap* happens. In some cases this might not be desirable\n * (e.g. for performance reasons, or when you wish to retain internal state on the original\n * element instance).\n *\n * ## JavaScript-based Animations\n *\n * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared\n * CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the\n * `module.animation()` module function we can register the animation.\n *\n * Let's see an example of a enter/leave animation using `ngRepeat`:\n *\n * ```html\n *
\n * {{ item }}\n *
\n * ```\n *\n * See the **slide** CSS class? Let's use that class to define an animation that we'll structure in our module code by using `module.animation`:\n *\n * ```js\n * myModule.animation('.slide', [function() {\n * return {\n * // make note that other events (like addClass/removeClass)\n * // have different function input parameters\n * enter: function(element, doneFn) {\n * jQuery(element).fadeIn(1000, doneFn);\n *\n * // remember to call doneFn so that AngularJS\n * // knows that the animation has concluded\n * },\n *\n * move: function(element, doneFn) {\n * jQuery(element).fadeIn(1000, doneFn);\n * },\n *\n * leave: function(element, doneFn) {\n * jQuery(element).fadeOut(1000, doneFn);\n * }\n * }\n * }]);\n * ```\n *\n * The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as\n * greensock.js and velocity.js.\n *\n * If our animation code class-based (meaning that something like `ngClass`, `ngHide` and `ngShow` triggers it) then we can still define\n * our animations inside of the same registered animation, however, the function input arguments are a bit different:\n *\n * ```html\n *
\n * this box is moody\n *
\n * \n * \n * \n * ```\n *\n * ```js\n * myModule.animation('.colorful', [function() {\n * return {\n * addClass: function(element, className, doneFn) {\n * // do some cool animation and call the doneFn\n * },\n * removeClass: function(element, className, doneFn) {\n * // do some cool animation and call the doneFn\n * },\n * setClass: function(element, addedClass, removedClass, doneFn) {\n * // do some cool animation and call the doneFn\n * }\n * }\n * }]);\n * ```\n *\n * ## CSS + JS Animations Together\n *\n * AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of AngularJS,\n * defining CSS and JS animations to work off of the same CSS class will not work anymore. Therefore the example below will only result in **JS animations taking\n * charge of the animation**:\n *\n * ```html\n *
\n * Slide in and out\n *
\n * ```\n *\n * ```js\n * myModule.animation('.slide', [function() {\n * return {\n * enter: function(element, doneFn) {\n * jQuery(element).slideIn(1000, doneFn);\n * }\n * }\n * }]);\n * ```\n *\n * ```css\n * .slide.ng-enter {\n * transition:0.5s linear all;\n * transform:translateY(-100px);\n * }\n * .slide.ng-enter.ng-enter-active {\n * transform:translateY(0);\n * }\n * ```\n *\n * Does this mean that CSS and JS animations cannot be used together? Do JS-based animations always have higher priority? We can make up for the\n * lack of CSS animations by using the `$animateCss` service to trigger our own tweaked-out, CSS-based animations directly from\n * our own JS-based animation code:\n *\n * ```js\n * myModule.animation('.slide', ['$animateCss', function($animateCss) {\n * return {\n * enter: function(element) {\n* // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.\n * return $animateCss(element, {\n * event: 'enter',\n * structural: true\n * });\n * }\n * }\n * }]);\n * ```\n *\n * The nice thing here is that we can save bandwidth by sticking to our CSS-based animation code and we don't need to rely on a 3rd-party animation framework.\n *\n * The `$animateCss` service is very powerful since we can feed in all kinds of extra properties that will be evaluated and fed into a CSS transition or\n * keyframe animation. For example if we wanted to animate the height of an element while adding and removing classes then we can do so by providing that\n * data into `$animateCss` directly:\n *\n * ```js\n * myModule.animation('.slide', ['$animateCss', function($animateCss) {\n * return {\n * enter: function(element) {\n * return $animateCss(element, {\n * event: 'enter',\n * structural: true,\n * addClass: 'maroon-setting',\n * from: { height:0 },\n * to: { height: 200 }\n * });\n * }\n * }\n * }]);\n * ```\n *\n * Now we can fill in the rest via our transition CSS code:\n *\n * ```css\n * /* the transition tells ngAnimate to make the animation happen */\n * .slide.ng-enter { transition:0.5s linear all; }\n *\n * /* this extra CSS class will be absorbed into the transition\n * since the $animateCss code is adding the class */\n * .maroon-setting { background:red; }\n * ```\n *\n * And `$animateCss` will figure out the rest. Just make sure to have the `done()` callback fire the `doneFn` function to signal when the animation is over.\n *\n * To learn more about what's possible be sure to visit the {@link ngAnimate.$animateCss $animateCss service}.\n *\n * ## Animation Anchoring (via `ng-animate-ref`)\n *\n * ngAnimate in AngularJS 1.4 comes packed with the ability to cross-animate elements between\n * structural areas of an application (like views) by pairing up elements using an attribute\n * called `ng-animate-ref`.\n *\n * Let's say for example we have two views that are managed by `ng-view` and we want to show\n * that there is a relationship between two components situated in within these views. By using the\n * `ng-animate-ref` attribute we can identify that the two components are paired together and we\n * can then attach an animation, which is triggered when the view changes.\n *\n * Say for example we have the following template code:\n *\n * ```html\n * \n *
\n *
\n *\n * \n * \n * \n * \n *\n * \n * \n * ```\n *\n * Now, when the view changes (once the link is clicked), ngAnimate will examine the\n * HTML contents to see if there is a match reference between any components in the view\n * that is leaving and the view that is entering. It will scan both the view which is being\n * removed (leave) and inserted (enter) to see if there are any paired DOM elements that\n * contain a matching ref value.\n *\n * The two images match since they share the same ref value. ngAnimate will now create a\n * transport element (which is a clone of the first image element) and it will then attempt\n * to animate to the position of the second image element in the next view. For the animation to\n * work a special CSS class called `ng-anchor` will be added to the transported element.\n *\n * We can now attach a transition onto the `.banner.ng-anchor` CSS class and then\n * ngAnimate will handle the entire transition for us as well as the addition and removal of\n * any changes of CSS classes between the elements:\n *\n * ```css\n * .banner.ng-anchor {\n * /* this animation will last for 1 second since there are\n * two phases to the animation (an `in` and an `out` phase) */\n * transition:0.5s linear all;\n * }\n * ```\n *\n * We also **must** include animations for the views that are being entered and removed\n * (otherwise anchoring wouldn't be possible since the new view would be inserted right away).\n *\n * ```css\n * .view-animation.ng-enter, .view-animation.ng-leave {\n * transition:0.5s linear all;\n * position:fixed;\n * left:0;\n * top:0;\n * width:100%;\n * }\n * .view-animation.ng-enter {\n * transform:translateX(100%);\n * }\n * .view-animation.ng-leave,\n * .view-animation.ng-enter.ng-enter-active {\n * transform:translateX(0%);\n * }\n * .view-animation.ng-leave.ng-leave-active {\n * transform:translateX(-100%);\n * }\n * ```\n *\n * Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur:\n * an `out` and an `in` stage. The `out` stage happens first and that is when the element is animated away\n * from its origin. Once that animation is over then the `in` stage occurs which animates the\n * element to its destination. The reason why there are two animations is to give enough time\n * for the enter animation on the new element to be ready.\n *\n * The example above sets up a transition for both the in and out phases, but we can also target the out or\n * in phases directly via `ng-anchor-out` and `ng-anchor-in`.\n *\n * ```css\n * .banner.ng-anchor-out {\n * transition: 0.5s linear all;\n *\n * /* the scale will be applied during the out animation,\n * but will be animated away when the in animation runs */\n * transform: scale(1.2);\n * }\n *\n * .banner.ng-anchor-in {\n * transition: 1s linear all;\n * }\n * ```\n *\n *\n *\n *\n * ### Anchoring Demo\n *\n \n \n Home\n
\n
\n
\n
\n
\n \n angular.module('anchoringExample', ['ngAnimate', 'ngRoute'])\n .config(['$routeProvider', function($routeProvider) {\n $routeProvider.when('/', {\n templateUrl: 'home.html',\n controller: 'HomeController as home'\n });\n $routeProvider.when('/profile/:id', {\n templateUrl: 'profile.html',\n controller: 'ProfileController as profile'\n });\n }])\n .run(['$rootScope', function($rootScope) {\n $rootScope.records = [\n { id: 1, title: 'Miss Beulah Roob' },\n { id: 2, title: 'Trent Morissette' },\n { id: 3, title: 'Miss Ava Pouros' },\n { id: 4, title: 'Rod Pouros' },\n { id: 5, title: 'Abdul Rice' },\n { id: 6, title: 'Laurie Rutherford Sr.' },\n { id: 7, title: 'Nakia McLaughlin' },\n { id: 8, title: 'Jordon Blanda DVM' },\n { id: 9, title: 'Rhoda Hand' },\n { id: 10, title: 'Alexandrea Sauer' }\n ];\n }])\n .controller('HomeController', [function() {\n //empty\n }])\n .controller('ProfileController', ['$rootScope', '$routeParams',\n function ProfileController($rootScope, $routeParams) {\n var index = parseInt($routeParams.id, 10);\n var record = $rootScope.records[index - 1];\n\n this.title = record.title;\n this.id = record.id;\n }]);\n \n \n

Welcome to the home page

\n

Please click on an element

\n \n {{ record.title }}\n \n
\n \n
\n {{ profile.title }}\n
\n
\n \n .record {\n display:block;\n font-size:20px;\n }\n .profile {\n background:black;\n color:white;\n font-size:100px;\n }\n .view-container {\n position:relative;\n }\n .view-container > .view.ng-animate {\n position:absolute;\n top:0;\n left:0;\n width:100%;\n min-height:500px;\n }\n .view.ng-enter, .view.ng-leave,\n .record.ng-anchor {\n transition:0.5s linear all;\n }\n .view.ng-enter {\n transform:translateX(100%);\n }\n .view.ng-enter.ng-enter-active, .view.ng-leave {\n transform:translateX(0%);\n }\n .view.ng-leave.ng-leave-active {\n transform:translateX(-100%);\n }\n .record.ng-anchor-out {\n background:red;\n }\n \n
\n *\n * ### How is the element transported?\n *\n * When an anchor animation occurs, ngAnimate will clone the starting element and position it exactly where the starting\n * element is located on screen via absolute positioning. The cloned element will be placed inside of the root element\n * of the application (where ng-app was defined) and all of the CSS classes of the starting element will be applied. The\n * element will then animate into the `out` and `in` animations and will eventually reach the coordinates and match\n * the dimensions of the destination element. During the entire animation a CSS class of `.ng-animate-shim` will be applied\n * to both the starting and destination elements in order to hide them from being visible (the CSS styling for the class\n * is: `visibility:hidden`). Once the anchor reaches its destination then it will be removed and the destination element\n * will become visible since the shim class will be removed.\n *\n * ### How is the morphing handled?\n *\n * CSS Anchoring relies on transitions and keyframes and the internal code is intelligent enough to figure out\n * what CSS classes differ between the starting element and the destination element. These different CSS classes\n * will be added/removed on the anchor element and a transition will be applied (the transition that is provided\n * in the anchor class). Long story short, ngAnimate will figure out what classes to add and remove which will\n * make the transition of the element as smooth and automatic as possible. Be sure to use simple CSS classes that\n * do not rely on DOM nesting structure so that the anchor element appears the same as the starting element (since\n * the cloned element is placed inside of root element which is likely close to the body element).\n *\n * Note that if the root element is on the `` element then the cloned node will be placed inside of body.\n *\n *\n * ## Using $animate in your directive code\n *\n * So far we've explored how to feed in animations into an AngularJS application, but how do we trigger animations within our own directives in our application?\n * By injecting the `$animate` service into our directive code, we can trigger structural and class-based hooks which can then be consumed by animations. Let's\n * imagine we have a greeting box that shows and hides itself when the data changes\n *\n * ```html\n * Hi there\n * ```\n *\n * ```js\n * ngModule.directive('greetingBox', ['$animate', function($animate) {\n * return function(scope, element, attrs) {\n * attrs.$observe('active', function(value) {\n * value ? $animate.addClass(element, 'on') : $animate.removeClass(element, 'on');\n * });\n * });\n * }]);\n * ```\n *\n * Now the `on` CSS class is added and removed on the greeting box component. Now if we add a CSS class on top of the greeting box element\n * in our HTML code then we can trigger a CSS or JS animation to happen.\n *\n * ```css\n * /* normally we would create a CSS class to reference on the element */\n * greeting-box.on { transition:0.5s linear all; background:green; color:white; }\n * ```\n *\n * The `$animate` service contains a variety of other methods like `enter`, `leave`, `animate` and `setClass`. To learn more about what's\n * possible be sure to visit the {@link ng.$animate $animate service API page}.\n *\n *\n * ## Callbacks and Promises\n *\n * When `$animate` is called it returns a promise that can be used to capture when the animation has ended. Therefore if we were to trigger\n * an animation (within our directive code) then we can continue performing directive and scope related activities after the animation has\n * ended by chaining onto the returned promise that animation method returns.\n *\n * ```js\n * // somewhere within the depths of the directive\n * $animate.enter(element, parent).then(function() {\n * //the animation has completed\n * });\n * ```\n *\n * (Note that earlier versions of AngularJS prior to v1.4 required the promise code to be wrapped using `$scope.$apply(...)`. This is not the case\n * anymore.)\n *\n * In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering\n * an event listener using the `$animate` service. Let's say for example that an animation was triggered on our view\n * routing controller to hook into that:\n *\n * ```js\n * ngModule.controller('HomePageController', ['$animate', function($animate) {\n * $animate.on('enter', ngViewElement, function(element) {\n * // the animation for this route has completed\n * }]);\n * }])\n * ```\n *\n * (Note that you will need to trigger a digest within the callback to get AngularJS to notice any scope-related changes.)\n */\n\nvar copy;\nvar extend;\nvar forEach;\nvar isArray;\nvar isDefined;\nvar isElement;\nvar isFunction;\nvar isObject;\nvar isString;\nvar isUndefined;\nvar jqLite;\nvar noop;\n\n/**\n * @ngdoc service\n * @name $animate\n * @kind object\n *\n * @description\n * The ngAnimate `$animate` service documentation is the same for the core `$animate` service.\n *\n * Click here {@link ng.$animate to learn more about animations with `$animate`}.\n */\nangular.module('ngAnimate', [], function initAngularHelpers() {\n // Access helpers from AngularJS core.\n // Do it inside a `config` block to ensure `window.angular` is available.\n noop = angular.noop;\n copy = angular.copy;\n extend = angular.extend;\n jqLite = angular.element;\n forEach = angular.forEach;\n isArray = angular.isArray;\n isString = angular.isString;\n isObject = angular.isObject;\n isUndefined = angular.isUndefined;\n isDefined = angular.isDefined;\n isFunction = angular.isFunction;\n isElement = angular.isElement;\n})\n .info({ angularVersion: '1.8.3' })\n .directive('ngAnimateSwap', ngAnimateSwapDirective)\n\n .directive('ngAnimateChildren', $$AnimateChildrenDirective)\n .factory('$$rAFScheduler', $$rAFSchedulerFactory)\n\n .provider('$$animateQueue', $$AnimateQueueProvider)\n .provider('$$animateCache', $$AnimateCacheProvider)\n .provider('$$animation', $$AnimationProvider)\n\n .provider('$animateCss', $AnimateCssProvider)\n .provider('$$animateCssDriver', $$AnimateCssDriverProvider)\n\n .provider('$$animateJs', $$AnimateJsProvider)\n .provider('$$animateJsDriver', $$AnimateJsDriverProvider);\n\n\n})(window, window.angular);\n"],"sourceRoot":""}