diff --git a/containers/xos/local_certs.crt b/containers/xos/local_certs.crt
index e69de29..8b13789 100644
--- a/containers/xos/local_certs.crt
+++ b/containers/xos/local_certs.crt
@@ -0,0 +1 @@
+
diff --git a/views/ngXosViews/ceilometerDashboard/mock/config.json b/views/ngXosViews/ceilometerDashboard/mock/config.json
new file mode 100644
index 0000000..3d64838
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/config.json
@@ -0,0 +1,19 @@
+{
+  "endpoints": [
+    {
+      "url": "xos-slice-service-mapping",
+      "base": "api/tenant/monitoring/dashboard/",
+      "methods": ["GET"]
+    },
+    {
+      "url": "meters",
+      "base": "api/tenant/monitoring/dashboard/",
+      "methods": ["GET"]
+    },
+    {
+      "url": "metersamples",
+      "base": "api/tenant/monitoring/dashboard/",
+      "methods": ["GET"]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/mock/data/meters.json b/views/ngXosViews/ceilometerDashboard/mock/data/meters.json
new file mode 100644
index 0000000..9a6451b
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/data/meters.json
@@ -0,0 +1,26 @@
+[
+  {
+    "service":"service-a",
+    "slice":"slice-a-1",
+    "name":"broadview.bst.egress-uc-queue",
+    "resource_name":"resource-1",
+    "resource_id":"resource-1",
+    "tenant": "id-a-1"
+  },
+  {
+    "service":"service-a",
+    "slice":"slice-a-1",
+    "name":"broadview.pt.packet-trace-lag-resolution",
+    "resource_name":"resource-1",
+    "resource_id":"resource-1",
+    "tenant": "id-a-1"
+  },
+  {
+    "service":"service-a",
+    "slice":"slice-a-1",
+    "name":"broadview.pt.packet-trace-ecmp-resolution",
+    "resource_name":"resource-1",
+    "resource_id":"resource-1",
+    "tenant": "id-a-1"
+  }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/mock/data/metersamples.json b/views/ngXosViews/ceilometerDashboard/mock/data/metersamples.json
new file mode 100644
index 0000000..4cb99eb
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/data/metersamples.json
@@ -0,0 +1,120 @@
+[
+   {
+       "slice": "slice-a-1",
+       "user_id": null,
+       "resource_id": "resource-1",
+       "timestamp": "2016-09-19T14:53:55",
+       "meter": "broadview.bst.egress-uc-queue",
+       "volume": 1111.0,
+       "source": "openstack",
+       "resource_name": "resource-1",
+       "recorded_at": "2016-09-19T21:53:56.879000",
+       "project_id": "default_admin_tenant",
+       "type": "gauge",
+       "id": "8fe9a026-7eb3-11e6-9a9b-3417ebe580ce",
+       "unit": "bv-agent",
+       "limit": 10
+   },
+   {
+       "slice": "slice-a-1",
+       "user_id": null,
+       "resource_id": "resource-1",
+       "timestamp": "2016-09-19T14:54:55",
+       "meter": "broadview.bst.egress-uc-queue",
+       "volume": 1345.0,
+       "source": "openstack",
+       "resource_name": "resource-1",
+       "recorded_at": "2016-09-19T21:53:56.879000",
+       "project_id": "default_admin_tenant",
+       "type": "gauge",
+       "id": "8fe9a026-7eb3-11e6-9a9b-3417ebe580ce",
+       "unit": "bv-agent",
+       "limit": 10
+   },
+   {
+       "slice": "slice-a-1",
+       "user_id": null,
+       "resource_id": "resource-1",
+       "timestamp": "2016-09-19T14:55:55",
+       "meter": "broadview.bst.egress-uc-queue",
+       "volume": 945.0,
+       "source": "openstack",
+       "resource_name": "resource-1",
+       "recorded_at": "2016-09-19T21:53:56.879000",
+       "project_id": "default_admin_tenant",
+       "type": "gauge",
+       "id": "8fe9a026-7eb3-11e6-9a9b-3417ebe580ce",
+       "unit": "bv-agent",
+       "limit": 10
+    },
+
+
+
+
+
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/1"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/1"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/2"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/3"
+      }
+    },
+    {
+      "slice": "slice-a-1",
+      "resource_id": "resource-1",
+      "resource_name": "resource-1",
+      "timestamp": "2016-09-19T14:54:05",
+      "meter": "broadview.pt.packet-trace-lag-resolution",
+      "limit": 30,
+      "metadata": {
+          "event_type": "broadview.pt.packet-trace-lag-resolution",
+          "lag-members": "['0/1', '0/2', '0/3', '0/4']",
+          "dst-lag-member": "0/4"
+      }
+    }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/mock/data/xos-slice-service-mapping.json b/views/ngXosViews/ceilometerDashboard/mock/data/xos-slice-service-mapping.json
new file mode 100644
index 0000000..5e6ae23
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/mock/data/xos-slice-service-mapping.json
@@ -0,0 +1,11 @@
+[
+   {
+      "service":"service-a",
+      "slices":[
+         {
+            "project_id":"id-a-1",
+            "slice":"slice-a-1"
+         }
+      ]
+   }
+]
\ No newline at end of file
diff --git a/views/ngXosViews/ceilometerDashboard/package.json b/views/ngXosViews/ceilometerDashboard/package.json
index 1f85623..a2fc0da 100644
--- a/views/ngXosViews/ceilometerDashboard/package.json
+++ b/views/ngXosViews/ceilometerDashboard/package.json
@@ -10,7 +10,8 @@
     "build": "gulp",
     "test": "karma start",
     "test:ci": "karma start --single-run",
-    "lint": "eslint src/js/"
+    "lint": "eslint src/js/",
+    "mock": "easy-mocker -d mock/data -c mock/config.json"
   },
   "keywords": [
     "XOS",
@@ -27,7 +28,7 @@
     "css-mqpacker": "^4.0.0",
     "csswring": "^4.2.1",
     "del": "^2.0.2",
-    "easy-mocker": "^1.2.0",
+    "easy-mocker": "^1.3.1",
     "eslint": "^1.8.0",
     "eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
     "gulp": "^3.9.0",
diff --git a/views/ngXosViews/ceilometerDashboard/src/index.html b/views/ngXosViews/ceilometerDashboard/src/index.html
index 40bc603..6360fea 100644
--- a/views/ngXosViews/ceilometerDashboard/src/index.html
+++ b/views/ngXosViews/ceilometerDashboard/src/index.html
@@ -18,6 +18,8 @@
 <!-- bower:js -->
 <script src="vendor/jquery/dist/jquery.js"></script>
 <script src="vendor/angular/angular.js"></script>
+<script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
+<script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
 <script src="vendor/angular-mocks/angular-mocks.js"></script>
 <script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
 <script src="vendor/angular-cookies/angular-cookies.js"></script>
@@ -28,12 +30,11 @@
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
 <script src="vendor/d3/d3.js"></script>
-<script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
-<script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower --><!-- endjs -->
 
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/stats.directive.js"></script>
 <script src="/.tmp/samples.directive.js"></script>
diff --git a/views/ngXosViews/ceilometerDashboard/src/js/rest.js b/views/ngXosViews/ceilometerDashboard/src/js/rest.js
index 11c22c0..bcd582b 100644
--- a/views/ngXosViews/ceilometerDashboard/src/js/rest.js
+++ b/views/ngXosViews/ceilometerDashboard/src/js/rest.js
@@ -41,10 +41,10 @@
         return deferred.promise;
       };
 
-      this.getSamples = (name, tenant) => {
+      this.getSamples = (name, limit = 10) => {
         let deferred = $q.defer();
 
-        $http.get(`/api/tenant/monitoring/dashboard/metersamples/`, {params: {meter: name, tenant: tenant}})
+        $http.get(`/api/tenant/monitoring/dashboard/metersamples/`, {params: {meter: name, limit: limit}})
           .then((res) => {
             deferred.resolve(res.data)
           })
diff --git a/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js b/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js
index 9f2dcea..3938714 100644
--- a/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js
+++ b/views/ngXosViews/ceilometerDashboard/src/js/samples.directive.js
@@ -10,7 +10,7 @@
   'use strict';
 
   angular.module('xos.ceilometerDashboard')
-  .directive('ceilometerSamples', function(_, $stateParams){
+  .directive('ceilometerSamples', function(_, $stateParams, $interval){
     return {
       restrict: 'E',
       scope: {},
@@ -39,10 +39,30 @@
 
         this.chartType = 'line';
 
+        // TODO
+        // check for name, if
+        // - broadview.pt.packet-trace-lag-resolution
+        // - broadview.pt.packet-trace-ecmp-resolution
+        // draw a pie
+        
+        const pieStats = [
+          'broadview.pt.packet-trace-lag-resolution',
+          'broadview.pt.packet-trace-ecmp-resolution'
+        ];
+        let isApie = false;
+
+        let refreshInterval = 60 * 1000;
+
         if($stateParams.name && $stateParams.tenant){
           this.name = $stateParams.name;
-          this.tenant = $stateParams.tenant;
           // TODO rename tenant in resource_id
+          this.tenant = $stateParams.tenant;
+
+          if(pieStats.indexOf(this.name) > -1){
+            isApie = true;
+            this.chartType = 'pie';
+            refreshInterval = 10 * 1000;
+          }
         }
         else{
           throw new Error('Missing Name and Tenant Params!');
@@ -118,42 +138,92 @@
             }, []);
         }
 
+        /**
+        * Format data series in pie chart val
+        */
+       
+        this.formatPieChartData = (samples) => {
+
+          this.chart['labels'] = samples[0].metadata['lag-members'].replace(/\[|\]|'| /g, '').split(',');
+          this.chart.options = {
+            legend: {
+              display: true
+            }
+          };
+          samples = _.groupBy(samples, i => i.metadata['dst-lag-member']);
+          
+          // TODO show percentage in pie
+          Chart.defaults.global.tooltipTemplate = '<%if (label){%><%=label%>: <%}%><%= value %>%';
+
+          let data = _.reduce(this.chart.labels, (data, item) => {
+            let length = samples[item] ? samples[item].length : 0;
+            data.push(length);
+            return data;
+          }, []);
+
+          let total = _.reduce(data, (d, t) => d + t);
+
+          let percent = _.map(data, d => Math.round((d / total) * 100));
+
+          console.log(total);
+
+          this.chart['data'] = percent;
+        };
+
 
         /**
          * Load the samples and format data
          */
 
+        this.loader = true;
         this.showSamples = () => {
-          this.loader = true;
           // Ceilometer.getSamples(this.name, this.tenant) //fetch one
-          Ceilometer.getSamples(this.name) //fetch all
-            .then(res => {
+          let p;
+          if (isApie){
+            p = Ceilometer.getSamples(this.name, 30) //fetch all
+          }
+          else{
+            p = Ceilometer.getSamples(this.name) //fetch all
+          }
 
-              // rename things in UI
-              res.map(m => {
-                m.resource_name = m.resource_name.replace('mysite_onos_vbng', 'ONOS_FABRIC');
-                m.resource_name = m.resource_name.replace('mysite_onos_volt', 'ONOS_CORD');
-                m.resource_name = m.resource_name.replace('mysite_vbng', 'mysite_vRouter');
-                return m;
-              });
-              // end rename things in UI
+          p.then(res => {
 
-              // setup data for visualization
-              this.samplesList = _.groupBy(res, 'resource_id');
-              this.sampleLabels = this.formatSamplesLabels(res);
-
-              // add current meter to chart
-              this.addMeterToChart(this.tenant);
-
-            })
-            .catch(err => {
-              this.error = err.data.detail;
-            })
-            .finally(() => {
-              this.loader = false;
+            // rename things in UI
+            res.map(m => {
+              m.resource_name = m.resource_name.replace('mysite_onos_vbng', 'ONOS_FABRIC');
+              m.resource_name = m.resource_name.replace('mysite_onos_volt', 'ONOS_CORD');
+              m.resource_name = m.resource_name.replace('mysite_vbng', 'mysite_vRouter');
+              return m;
             });
+            // end rename things in UI
+
+            // if I have to draw a pie skip the rest
+            if(isApie){
+
+              // TODO format data as pie
+              this.formatPieChartData(res);
+              return;
+            }
+
+            // setup data for visualization
+            this.samplesList = _.groupBy(res, 'resource_id');
+            this.sampleLabels = this.formatSamplesLabels(res);
+
+            // add current meter to chart
+            this.addMeterToChart(this.tenant);
+
+          })
+          .catch(err => {
+            this.error = err.data.detail;
+          })
+          .finally(() => {
+            this.loader = false;
+          });
         };
 
+        $interval(() => {
+          this.showSamples();
+        }, refreshInterval)
         this.showSamples();
       }
     }
diff --git a/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html b/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
index b279123..8df2a29 100644
--- a/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
+++ b/views/ngXosViews/ceilometerDashboard/src/templates/ceilometer-samples.tpl.html
@@ -16,7 +16,7 @@
   </div>
 </div>
 <section ng-if="!vm.loader && !vm.error">
-  <div class="row">
+  <div class="row" ng-if="vm.chartType !== 'pie'">
     <form class="form-inline col-xs-8" ng-submit="vm.addMeterToChart(vm.addMeterValue)">
       <select ng-model="vm.addMeterValue" class="form-control" ng-options="resource.id as resource.name for resource in vm.sampleLabels"></select>
       <button class="btn btn-success"> 
@@ -36,8 +36,25 @@
       <canvas ng-if="vm.chartType === 'bar'" id="bar" class="chart chart-bar" chart-data="vm.chart.data"
         chart-labels="vm.chart.labels" chart-legend="false" chart-series="vm.chart.series">
       </canvas>
-      <!-- <pre>{{vm.chartMeters | json}}</pre> -->
     </div>
+    <!-- PIE CHART -->
+    <div class="col-xs-8" ng-if="vm.chartType === 'pie'">
+      <canvas id="pie" class="chart chart-pie"
+        chart-data="vm.chart.data" chart-labels="vm.chart.labels" chart-options="vm.chart.options">
+      </canvas> 
+    </div>
+    <div class="col-xs-4" ng-if="vm.chartType === 'pie'">
+      <div class="row" ng-repeat="item in vm.chart.labels">
+        <div class="col-xs-12">
+          <span 
+            class="btn btn-chart"
+            ng-style="{'background-color': vm.chartColors[$index]}">
+            {{item}}: {{vm.chart.data[$index]}}%
+          </span>
+        </div>
+      </div>
+    </div>
+    <!-- END PIE CHART -->
   </div>
   <div class="row" ng-if="!vm.loader">
     <div class="col-xs-12">
diff --git a/views/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us b/views/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
deleted file mode 100644
index 8e990a2..0000000
--- a/views/ngXosViews/ceilometerDashboard/teone@clnode015.clemson.cloudlab.us
+++ /dev/null
@@ -1,20 +0,0 @@
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<meta name="viewport" content="width=device-width, initial-scale=1, max-scale=1">
-<!-- browserSync -->
-
-<!-- inject:css -->
-<link rel="stylesheet" href="/css/ceilometerDashboard.css">
-<link rel="stylesheet" href="/css/dev.css">
-<!-- endinject -->
-<link rel="stylesheet" href="css/ceilometerDashboard.css">
-<div id="xosCeilometerDashboard">
-  <div ui-view ng-class="stateName"></div>
-</div>
-
-
-<script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
-<script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
-<!-- inject:js -->
-<script src="/../../static/js/vendor/xosCeilometerDashboardVendor.js"></script>
-<script src="/../../static/js/xosCeilometerDashboard.js"></script>
-<!-- endinject -->
diff --git a/xos/core/xoslib/static/js/xosCeilometerDashboard.js b/xos/core/xoslib/static/js/xosCeilometerDashboard.js
index a296156..ddf2c6a 100644
--- a/xos/core/xoslib/static/js/xosCeilometerDashboard.js
+++ b/xos/core/xoslib/static/js/xosCeilometerDashboard.js
@@ -1 +1 @@
-"use strict";angular.module("xos.ceilometerDashboard",["ngResource","ngCookies","ui.router","xos.helpers","ngAnimate","chart.js","ui.bootstrap.accordion"]).config(["$stateProvider","$urlRouterProvider",function(e,t){e.state("ceilometerDashboard",{url:"/",template:"<ceilometer-dashboard></ceilometer-dashboard>"}).state("samples",{url:"/:name/:tenant/samples",template:"<ceilometer-samples></ceilometer-samples>"}),t.otherwise("/")}]).config(["$httpProvider",function(e){e.interceptors.push("NoHyperlinks")}]).run(["$rootScope",function(e){e.stateName="ceilometerDashboard",e.$on("$stateChangeStart",function(t,n){e.stateName=n.name})}]),angular.module("xos.ceilometerDashboard").run(["$templateCache",function(e){e.put("templates/accordion-group.html",'<div class="panel {{panelClass || \'panel-default\'}}">\n  <div class="panel-heading" ng-keypress="toggleOpen($event)">\n    <h5>\n      <a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span ng-class="{\'text-muted\': isDisabled}">{{heading}}</span></a>\n    </h5>\n  </div>\n  <div class="panel-collapse collapse" uib-collapse="!isOpen">\n	  <div class="panel-body" ng-transclude></div>\n  </div>\n</div>\n'),e.put("templates/accordion.html",'<div class="panel-group" ng-transclude></div>'),e.put("templates/ceilometer-dashboard.tpl.html",'<div class="row">\n  <div class="col-sm-10">\n    <h3>XOS Monitoring Statistics</h3>\n  </div>\n  <div class="col-xs-2 text-right">\n    <a href="" class="btn btn-default" \n      ng-show="vm.selectedSlice && !vm.showStats"\n      ng-click="vm.showStats = true">\n      <i class="glyphicon glyphicon-transfer"></i>\n    </a>\n    <a href="" class="btn btn-default" \n      ng-show="vm.selectedSlice && vm.showStats"\n      ng-click="vm.showStats = false">\n      <i class="glyphicon glyphicon-transfer"></i>\n    </a>\n  </div>\n</div>\n\n<div class="row" ng-show="vm.loader">\n  <div class="col-xs-12">\n    <div class="loader">Loading</div>\n  </div>\n</div>\n\n<section ng-hide="vm.loader" ng-class="{animate: !vm.loader}">\n  <div class="row">\n    <div class="col-sm-3 service-list">\n        <h4>XOS Service: </h4>\n        <uib-accordion close-others="true" template-url="templates/accordion.html">\n          <uib-accordion-group\n            ng-repeat="service in vm.services | orderBy:\'-service\'"\n            template-url="templates/accordion-group.html"\n            is-open="vm.accordion.open[service.service]"\n            heading="{{service.service}}">\n            <h5>Slices:</h5>\n            <a ng-repeat="slice in service.slices" \n              ng-class="{active: slice.slice === vm.selectedSlice}"\n              ng-click="vm.loadSliceMeter(slice, service.service)"\n              href="#" class="list-group-item" >\n              {{slice.slice}} <i class="glyphicon glyphicon-chevron-right pull-right"></i>\n            </a>\n          </uib-accordion-group>\n        </uib-accordion>\n    </div>\n    <section class="side-container col-sm-9">\n      <div class="row">\n        <!-- STATS -->\n        <article ng-hide="!vm.showStats" class="stats animate-slide-left">\n          <div class="col-xs-12">\n            <div class="list-group">\n              <div class="list-group-item">\n                <h4>Stats</h4>\n              </div>\n              <div class="list-group-item">\n                <ceilometer-stats ng-if="vm.selectedSlice" name="vm.selectedSlice" tenant="vm.selectedTenant"></ceilometer-stats>\n              </div>\n            </div>\n          </div>\n        </article>\n        <!-- METERS -->\n        <article ng-hide="vm.showStats" class="meters animate-slide-left">\n          <div class="alert alert-danger" ng-show="vm.ceilometerError">\n            {{vm.ceilometerError}}\n          </div>\n          <div class="col-sm-4 animate-slide-left" ng-hide="!vm.selectedSlice">\n            <div class="list-group">\n              <div class="list-group-item">\n                <h4>Resources</h4>\n              </div>\n              <a href="#" \n                ng-click="vm.selectMeters(meters, resource)" \n                class="list-group-item" \n                ng-repeat="(resource, meters) in vm.selectedResources" \n                ng-class="{active: resource === vm.selectedResource}">\n                {{resource}} <i class="glyphicon glyphicon-chevron-right pull-right"></i>\n              </a>\n            </div>\n          </div>\n          <div class="col-sm-8 animate-slide-left" ng-hide="!vm.selectedMeters">\n            <div class="list-group">\n              <div class="list-group-item">\n                <h4>Meters</h4>\n              </div>\n              <div class="list-group-item">\n                <div class="row">\n                  <div class="col-xs-6">\n                    <label>Name:</label>\n                  </div>\n                  <div class="col-xs-3">\n                    <label>Unit:</label>\n                  </div>\n                  <div class="col-xs-3"></div>\n                </div>\n                <div class="row" ng-repeat="meter in vm.selectedMeters" style="margin-bottom: 10px;">\n                  <div class="col-xs-6">\n                    {{meter.name}}\n                  </div>\n                  <div class="col-xs-3">\n                    {{meter.unit}}\n                  </div>\n                  <div class="col-xs-3">\n                    <!-- tenant: meter.resource_id -->\n                    <a ui-sref="samples({name: meter.name, tenant: meter.resource_id})" class="btn btn-primary">\n                      <i class="glyphicon glyphicon-search"></i>\n                    </a>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </article>\n      </div>\n    </section>\n  </div>\n</section>\n<section ng-if="!vm.loader && vm.error">\n  <div class="alert alert-danger">\n    {{vm.error}}\n  </div>\n</section>\n'),e.put("templates/ceilometer-samples.tpl.html",'<!-- <pre>{{ vm | json}}</pre> -->\n\n<div class="row">\n  <div class="col-xs-10">\n    <h1>{{vm.name | uppercase}}</h1>\n  </div>\n  <div class="col-xs-2">\n    <a ui-sref="ceilometerDashboard" class="btn btn-primary pull-right">\n      <i class="glyphicon glyphicon-arrow-left"></i> Back to list\n    </a>\n  </div>\n</div>\n<div class="row" ng-show="vm.loader">\n  <div class="col-xs-12">\n    <div class="loader">Loading</div>\n  </div>\n</div>\n<section ng-if="!vm.loader && !vm.error">\n  <div class="row">\n    <form class="form-inline col-xs-8" ng-submit="vm.addMeterToChart(vm.addMeterValue)">\n      <select ng-model="vm.addMeterValue" class="form-control" ng-options="resource.id as resource.name for resource in vm.sampleLabels"></select>\n      <button class="btn btn-success"> \n        <i class="glyphicon glyphicon-plus"></i> Add\n      </button>\n    </form>\n    <div class="col-xs-4 text-right">\n      <a ng-click="vm.chartType = \'line\'" class="btn" ng-class="{\'btn-default\': vm.chartType != \'bar\', \'btn-primary\': vm.chartType == \'line\'}">Lines</a>\n      <a ng-click="vm.chartType = \'bar\'" class="btn" ng-class="{\'btn-default\': vm.chartType != \'line\', \'btn-primary\': vm.chartType == \'bar\'}">Bars</a>\n    </div>\n  </div>\n  <div class="row" ng-if="!vm.loader">\n    <div class="col-xs-12">\n      <canvas ng-if="vm.chartType === \'line\'" id="line" class="chart chart-line" chart-data="vm.chart.data" chart-options="{datasetFill: false}"\n        chart-labels="vm.chart.labels" chart-legend="false" chart-series="vm.chart.series">\n      </canvas>\n      <canvas ng-if="vm.chartType === \'bar\'" id="bar" class="chart chart-bar" chart-data="vm.chart.data"\n        chart-labels="vm.chart.labels" chart-legend="false" chart-series="vm.chart.series">\n      </canvas>\n      <!-- <pre>{{vm.chartMeters | json}}</pre> -->\n    </div>\n  </div>\n  <div class="row" ng-if="!vm.loader">\n    <div class="col-xs-12">\n      <a ng-click="vm.removeFromChart(meter)" class="btn btn-chart" ng-style="{\'background-color\': vm.chartColors[$index]}" ng-repeat="meter in vm.chartMeters">\n        {{meter.resource_name || meter.resource_id}}\n      </a>\n    </div>\n  </div>\n</section>\n<section ng-if="!vm.loader && vm.error">\n  <div class="alert alert-danger">\n    {{vm.error}}\n  </div>\n</section>'),e.put("templates/ceilometer-stats.tpl.html",'<div ng-show="vm.loader" class="loader">Loading</div>\n\n<section ng-if="!vm.loader && !vm.error">\n\n  <div class="alert alert-danger" ng-if="vm.stats.length == 0">\n    No result\n  </div>  \n\n  <table class="table" ng-if="vm.stats.length > 0">\n    <tr>\n      <th>\n        <a ng-click="(order == \'category\') ? order = \'-category\' : order = \'category\'">Type:</a>\n      </th>\n      <th>\n        <a ng-click="(order == \'resource_name\') ? order = \'-resource_name\' : order = \'resource_name\'">Resource:</a>\n      </th>\n      <th>\n        <a ng-click="(order == \'meter\') ? order = \'-meter\' : order = \'meter\'">Meter:</a>\n      </th>\n      <th>\n        Unit:\n      </th>\n      <th>\n        Value:\n      </th>\n    </tr>\n    <!-- <tr>\n      <td>\n        <input type="text" ng-model="query.category">\n      </td>\n      <td>\n        <input type="text" ng-model="query.resource_name">\n      </td>\n      <td>\n        <input type="text" ng-model="query.meter">\n      </td>\n      <td>\n        <input type="text" ng-model="query.unit">\n      </td>\n      <td>\n        <input type="text" ng-model="query.value">\n      </td>\n    </tr> -->\n    <tr ng-repeat="item in vm.stats | orderBy:order">\n      <td>{{item.category}}</td>\n      <td>{{item.resource_name}}</td>\n      <td>{{item.meter}}</td>\n      <td>{{item.unit}}</td>\n      <td>{{item.value}}</td>\n    </tr>\n  </table>\n</section>\n\n<section ng-if="!vm.loader && vm.error">\n  <div class="alert alert-danger">\n    {{vm.error}}\n  </div>\n</section>\n'),e.put("templates/users-list.tpl.html",'<xos-table config="vm.tableConfig" data="vm.users"></xos-table>')}]),function(){angular.module("xos.ceilometerDashboard").directive("ceilometerStats",function(){return{restrict:"E",scope:{name:"=name",tenant:"=tenant"},bindToController:!0,controllerAs:"vm",templateUrl:"templates/ceilometer-stats.tpl.html",controller:["$scope","Ceilometer",function(e,t){var n=this;this.getStats=function(e){n.loader=!0,t.getStats({tenant:e}).then(function(e){e.map(function(e){return e.resource_name=e.resource_name.replace("mysite_onos_vbng","ONOS_FABRIC"),e.resource_name=e.resource_name.replace("mysite_onos_volt","ONOS_CORD"),e.resource_name=e.resource_name.replace("mysite_vbng","mysite_vRouter"),e}),n.stats=e})["catch"](function(e){n.error=e.data})["finally"](function(){n.loader=!1})},e.$watch(function(){return n.name},function(e){e&&n.getStats(n.tenant)})}]}})}(),function(){angular.module("xos.ceilometerDashboard").directive("ceilometerSamples",["_","$stateParams",function(e,t){return{restrict:"E",scope:{},bindToController:!0,controllerAs:"vm",templateUrl:"templates/ceilometer-samples.tpl.html",controller:["Ceilometer",function(n){var s=this;if(this.chartColors=["#286090","#F7464A","#46BFBD","#FDB45C","#97BBCD","#4D5360","#8c4f9f"],this.chart={series:[],labels:[],data:[]},Chart.defaults.global.colours=this.chartColors,this.chartType="line",!t.name||!t.tenant)throw new Error("Missing Name and Tenant Params!");this.name=t.name,this.tenant=t.tenant,this.getLabels=function(e){return e.reduce(function(e,t){var n=new Date(t.timestamp);return e.push(n.getHours()+":"+((n.getMinutes()<10?"0":"")+n.getMinutes())+":"+n.getSeconds()),e},[])},this.getData=function(e){return e.reduce(function(e,t){return e.push(t.volume),e},[])},this.chartMeters=[],this.addMeterToChart=function(t){s.chart.labels=s.getLabels(e.sortBy(s.samplesList[t],"timestamp")),s.chart.series.push(t),s.chart.data.push(s.getData(e.sortBy(s.samplesList[t],"timestamp"))),s.chartMeters.push(s.samplesList[t][0]),e.remove(s.sampleLabels,{id:t})},this.removeFromChart=function(t){s.chart.data.splice(s.chart.series.indexOf(t.resource_id),1),s.chart.series.splice(s.chart.series.indexOf(t.resource_id),1),s.chartMeters.splice(e.findIndex(s.chartMeters,{resource_id:t.resource_id}),1),s.sampleLabels.push({id:t.resource_id,name:t.resource_name||t.resource_id})},this.formatSamplesLabels=function(t){return e.uniq(t,"resource_id").reduce(function(e,t){return e.push({id:t.resource_id,name:t.resource_name||t.resource_id}),e},[])},this.showSamples=function(){s.loader=!0,n.getSamples(s.name).then(function(t){t.map(function(e){return e.resource_name=e.resource_name.replace("mysite_onos_vbng","ONOS_FABRIC"),e.resource_name=e.resource_name.replace("mysite_onos_volt","ONOS_CORD"),e.resource_name=e.resource_name.replace("mysite_vbng","mysite_vRouter"),e}),s.samplesList=e.groupBy(t,"resource_id"),s.sampleLabels=s.formatSamplesLabels(t),s.addMeterToChart(s.tenant)})["catch"](function(e){s.error=e.data.detail})["finally"](function(){s.loader=!1})},this.showSamples()}]}}])}(),function(){angular.module("xos.ceilometerDashboard").service("Ceilometer",["$http","$q",function(e,t){this.getMappings=function(){var n=t.defer();return e.get("/api/tenant/monitoring/dashboard/xos-slice-service-mapping/").then(function(e){n.resolve(e.data)})["catch"](function(e){n.reject(e)}),n.promise},this.getMeters=function(n){var s=t.defer();return e.get("/api/tenant/monitoring/dashboard/meters/",{cache:!0,params:n}).then(function(e){s.resolve(e.data)})["catch"](function(e){s.reject(e)}),s.promise},this.getSamples=function(n,s){var r=t.defer();return e.get("/api/tenant/monitoring/dashboard/metersamples/",{params:{meter:n,tenant:s}}).then(function(e){r.resolve(e.data)})["catch"](function(e){r.reject(e)}),r.promise},this.getStats=function(n){var s=t.defer();return e.get("/api/tenant/monitoring/dashboard/meterstatistics/",{cache:!0,params:n}).then(function(e){s.resolve(e.data)})["catch"](function(e){s.reject(e)}),s.promise},this.selectedService=null,this.selectedSlice=null,this.selectedResource=null}])}(),function(){angular.module("xos.ceilometerDashboard").directive("ceilometerDashboard",["_",function(e){return{restrict:"E",scope:{},bindToController:!0,controllerAs:"vm",templateUrl:"templates/ceilometer-dashboard.tpl.html",controller:["Ceilometer",function(t){var n=this;this.showStats=!1,this.accordion={open:{}},this.openPanels=function(){t.selectedService&&(n.accordion.open[t.selectedService]=!0,t.selectedSlice&&(n.loadSliceMeter(t.selectedSlice,t.selectedService),n.selectedSlice=t.selectedSlice,t.selectedResource&&(n.selectedResource=t.selectedResource)))},this.loadMappings=function(){n.loader=!0,t.getMappings().then(function(e){e.map(function(e){return"service_ONOS_vBNG"===e.service&&(e.service="ONOS_FABRIC"),"service_ONOS_vOLT"===e.service&&(e.service="ONOS_CORD"),e.slices.map(function(e){"mysite_onos_volt"===e.slice&&(e.slice="ONOS_CORD"),"mysite_onos_vbng"===e.slice&&(e.slice="ONOS_FABRIC"),"mysite_vbng"===e.slice&&(e.slice="mysite_vRouter")}),e}),n.services=e,n.openPanels()})["catch"](function(e){n.error=e.data&&e.data.detail?e.data.detail:"An Error occurred. Please try again later."})["finally"](function(){n.loader=!1})},this.loadMappings(),this.loadSliceMeter=function(s,r){t.selectedSlice=null,t.selectedService=null,t.selectedResources=null,n.loader=!0,n.error=null,n.ceilometerError=null,t.getMeters({tenant:s.project_id}).then(function(a){n.selectedSlice=s.slice,n.selectedTenant=s.project_id,t.selectedSlice=s,t.selectedService=r,a.map(function(e){return e.resource_name=e.resource_name.replace("mysite_onos_vbng","ONOS_FABRIC"),e.resource_name=e.resource_name.replace("mysite_onos_volt","ONOS_CORD"),e.resource_name=e.resource_name.replace("mysite_vbng","mysite_vRouter"),e}),n.selectedResources=e.groupBy(a,"resource_name"),t.selectedResource&&(n.selectedMeters=n.selectedResources[t.selectedResource])})["catch"](function(e){return 503===e.status?n.ceilometerError=e.data.detail.specific_error:void(n.ceilometerError=e.data&&e.data.detail&&e.data.detail.specific_error?e.data.detail.specific_error:"An Error occurred. Please try again later.")})["finally"](function(){n.loader=!1})},this.selectedMeters=null,this.selectMeters=function(e,s){n.selectedMeters=e,t.selectedResource=s,n.selectedResource=s}}]}}])}(),angular.module("xos.ceilometerDashboard").run(["$location",function(e){e.path("/")}]);
+"use strict";angular.module("xos.ceilometerDashboard",["ngResource","ngCookies","ui.router","xos.helpers","ngAnimate","chart.js","ui.bootstrap.accordion"]).config(["$stateProvider","$urlRouterProvider",function(e,t){e.state("ceilometerDashboard",{url:"/",template:"<ceilometer-dashboard></ceilometer-dashboard>"}).state("samples",{url:"/:name/:tenant/samples",template:"<ceilometer-samples></ceilometer-samples>"}),t.otherwise("/")}]).config(["$httpProvider",function(e){e.interceptors.push("NoHyperlinks")}]).run(["$rootScope",function(e){e.stateName="ceilometerDashboard",e.$on("$stateChangeStart",function(t,n){e.stateName=n.name})}]),angular.module("xos.ceilometerDashboard").run(["$templateCache",function(e){e.put("templates/accordion-group.html",'<div class="panel {{panelClass || \'panel-default\'}}">\n  <div class="panel-heading" ng-keypress="toggleOpen($event)">\n    <h5>\n      <a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span ng-class="{\'text-muted\': isDisabled}">{{heading}}</span></a>\n    </h5>\n  </div>\n  <div class="panel-collapse collapse" uib-collapse="!isOpen">\n	  <div class="panel-body" ng-transclude></div>\n  </div>\n</div>\n'),e.put("templates/accordion.html",'<div class="panel-group" ng-transclude></div>'),e.put("templates/ceilometer-dashboard.tpl.html",'<div class="row">\n  <div class="col-sm-10">\n    <h3>XOS Monitoring Statistics</h3>\n  </div>\n  <div class="col-xs-2 text-right">\n    <a href="" class="btn btn-default" \n      ng-show="vm.selectedSlice && !vm.showStats"\n      ng-click="vm.showStats = true">\n      <i class="glyphicon glyphicon-transfer"></i>\n    </a>\n    <a href="" class="btn btn-default" \n      ng-show="vm.selectedSlice && vm.showStats"\n      ng-click="vm.showStats = false">\n      <i class="glyphicon glyphicon-transfer"></i>\n    </a>\n  </div>\n</div>\n\n<div class="row" ng-show="vm.loader">\n  <div class="col-xs-12">\n    <div class="loader">Loading</div>\n  </div>\n</div>\n\n<section ng-hide="vm.loader" ng-class="{animate: !vm.loader}">\n  <div class="row">\n    <div class="col-sm-3 service-list">\n        <h4>XOS Service: </h4>\n        <uib-accordion close-others="true" template-url="templates/accordion.html">\n          <uib-accordion-group\n            ng-repeat="service in vm.services | orderBy:\'-service\'"\n            template-url="templates/accordion-group.html"\n            is-open="vm.accordion.open[service.service]"\n            heading="{{service.service}}">\n            <h5>Slices:</h5>\n            <a ng-repeat="slice in service.slices" \n              ng-class="{active: slice.slice === vm.selectedSlice}"\n              ng-click="vm.loadSliceMeter(slice, service.service)"\n              href="#" class="list-group-item" >\n              {{slice.slice}} <i class="glyphicon glyphicon-chevron-right pull-right"></i>\n            </a>\n          </uib-accordion-group>\n        </uib-accordion>\n    </div>\n    <section class="side-container col-sm-9">\n      <div class="row">\n        <!-- STATS -->\n        <article ng-hide="!vm.showStats" class="stats animate-slide-left">\n          <div class="col-xs-12">\n            <div class="list-group">\n              <div class="list-group-item">\n                <h4>Stats</h4>\n              </div>\n              <div class="list-group-item">\n                <ceilometer-stats ng-if="vm.selectedSlice" name="vm.selectedSlice" tenant="vm.selectedTenant"></ceilometer-stats>\n              </div>\n            </div>\n          </div>\n        </article>\n        <!-- METERS -->\n        <article ng-hide="vm.showStats" class="meters animate-slide-left">\n          <div class="alert alert-danger" ng-show="vm.ceilometerError">\n            {{vm.ceilometerError}}\n          </div>\n          <div class="col-sm-4 animate-slide-left" ng-hide="!vm.selectedSlice">\n            <div class="list-group">\n              <div class="list-group-item">\n                <h4>Resources</h4>\n              </div>\n              <a href="#" \n                ng-click="vm.selectMeters(meters, resource)" \n                class="list-group-item" \n                ng-repeat="(resource, meters) in vm.selectedResources" \n                ng-class="{active: resource === vm.selectedResource}">\n                {{resource}} <i class="glyphicon glyphicon-chevron-right pull-right"></i>\n              </a>\n            </div>\n          </div>\n          <div class="col-sm-8 animate-slide-left" ng-hide="!vm.selectedMeters">\n            <div class="list-group">\n              <div class="list-group-item">\n                <h4>Meters</h4>\n              </div>\n              <div class="list-group-item">\n                <div class="row">\n                  <div class="col-xs-6">\n                    <label>Name:</label>\n                  </div>\n                  <div class="col-xs-3">\n                    <label>Unit:</label>\n                  </div>\n                  <div class="col-xs-3"></div>\n                </div>\n                <div class="row" ng-repeat="meter in vm.selectedMeters" style="margin-bottom: 10px;">\n                  <div class="col-xs-6">\n                    {{meter.name}}\n                  </div>\n                  <div class="col-xs-3">\n                    {{meter.unit}}\n                  </div>\n                  <div class="col-xs-3">\n                    <!-- tenant: meter.resource_id -->\n                    <a ui-sref="samples({name: meter.name, tenant: meter.resource_id})" class="btn btn-primary">\n                      <i class="glyphicon glyphicon-search"></i>\n                    </a>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </article>\n      </div>\n    </section>\n  </div>\n</section>\n<section ng-if="!vm.loader && vm.error">\n  <div class="alert alert-danger">\n    {{vm.error}}\n  </div>\n</section>\n'),e.put("templates/ceilometer-samples.tpl.html",'<!-- <pre>{{ vm | json}}</pre> -->\n\n<div class="row">\n  <div class="col-xs-10">\n    <h1>{{vm.name | uppercase}}</h1>\n  </div>\n  <div class="col-xs-2">\n    <a ui-sref="ceilometerDashboard" class="btn btn-primary pull-right">\n      <i class="glyphicon glyphicon-arrow-left"></i> Back to list\n    </a>\n  </div>\n</div>\n<div class="row" ng-show="vm.loader">\n  <div class="col-xs-12">\n    <div class="loader">Loading</div>\n  </div>\n</div>\n<section ng-if="!vm.loader && !vm.error">\n  <div class="row" ng-if="vm.chartType !== \'pie\'">\n    <form class="form-inline col-xs-8" ng-submit="vm.addMeterToChart(vm.addMeterValue)">\n      <select ng-model="vm.addMeterValue" class="form-control" ng-options="resource.id as resource.name for resource in vm.sampleLabels"></select>\n      <button class="btn btn-success"> \n        <i class="glyphicon glyphicon-plus"></i> Add\n      </button>\n    </form>\n    <div class="col-xs-4 text-right">\n      <a ng-click="vm.chartType = \'line\'" class="btn" ng-class="{\'btn-default\': vm.chartType != \'bar\', \'btn-primary\': vm.chartType == \'line\'}">Lines</a>\n      <a ng-click="vm.chartType = \'bar\'" class="btn" ng-class="{\'btn-default\': vm.chartType != \'line\', \'btn-primary\': vm.chartType == \'bar\'}">Bars</a>\n    </div>\n  </div>\n  <div class="row" ng-if="!vm.loader">\n    <div class="col-xs-12">\n      <canvas ng-if="vm.chartType === \'line\'" id="line" class="chart chart-line" chart-data="vm.chart.data" chart-options="{datasetFill: false}"\n        chart-labels="vm.chart.labels" chart-legend="false" chart-series="vm.chart.series">\n      </canvas>\n      <canvas ng-if="vm.chartType === \'bar\'" id="bar" class="chart chart-bar" chart-data="vm.chart.data"\n        chart-labels="vm.chart.labels" chart-legend="false" chart-series="vm.chart.series">\n      </canvas>\n    </div>\n    <!-- PIE CHART -->\n    <div class="col-xs-8" ng-if="vm.chartType === \'pie\'">\n      <canvas id="pie" class="chart chart-pie"\n        chart-data="vm.chart.data" chart-labels="vm.chart.labels" chart-options="vm.chart.options">\n      </canvas> \n    </div>\n    <div class="col-xs-4" ng-if="vm.chartType === \'pie\'">\n      <div class="row" ng-repeat="item in vm.chart.labels">\n        <div class="col-xs-12">\n          <span \n            class="btn btn-chart"\n            ng-style="{\'background-color\': vm.chartColors[$index]}">\n            {{item}}: {{vm.chart.data[$index]}}%\n          </span>\n        </div>\n      </div>\n    </div>\n    <!-- END PIE CHART -->\n  </div>\n  <div class="row" ng-if="!vm.loader">\n    <div class="col-xs-12">\n      <a ng-click="vm.removeFromChart(meter)" class="btn btn-chart" ng-style="{\'background-color\': vm.chartColors[$index]}" ng-repeat="meter in vm.chartMeters">\n        {{meter.resource_name || meter.resource_id}}\n      </a>\n    </div>\n  </div>\n</section>\n<section ng-if="!vm.loader && vm.error">\n  <div class="alert alert-danger">\n    {{vm.error}}\n  </div>\n</section>'),e.put("templates/ceilometer-stats.tpl.html",'<div ng-show="vm.loader" class="loader">Loading</div>\n\n<section ng-if="!vm.loader && !vm.error">\n\n  <div class="alert alert-danger" ng-if="vm.stats.length == 0">\n    No result\n  </div>  \n\n  <table class="table" ng-if="vm.stats.length > 0">\n    <tr>\n      <th>\n        <a ng-click="(order == \'category\') ? order = \'-category\' : order = \'category\'">Type:</a>\n      </th>\n      <th>\n        <a ng-click="(order == \'resource_name\') ? order = \'-resource_name\' : order = \'resource_name\'">Resource:</a>\n      </th>\n      <th>\n        <a ng-click="(order == \'meter\') ? order = \'-meter\' : order = \'meter\'">Meter:</a>\n      </th>\n      <th>\n        Unit:\n      </th>\n      <th>\n        Value:\n      </th>\n    </tr>\n    <!-- <tr>\n      <td>\n        <input type="text" ng-model="query.category">\n      </td>\n      <td>\n        <input type="text" ng-model="query.resource_name">\n      </td>\n      <td>\n        <input type="text" ng-model="query.meter">\n      </td>\n      <td>\n        <input type="text" ng-model="query.unit">\n      </td>\n      <td>\n        <input type="text" ng-model="query.value">\n      </td>\n    </tr> -->\n    <tr ng-repeat="item in vm.stats | orderBy:order">\n      <td>{{item.category}}</td>\n      <td>{{item.resource_name}}</td>\n      <td>{{item.meter}}</td>\n      <td>{{item.unit}}</td>\n      <td>{{item.value}}</td>\n    </tr>\n  </table>\n</section>\n\n<section ng-if="!vm.loader && vm.error">\n  <div class="alert alert-danger">\n    {{vm.error}}\n  </div>\n</section>\n'),e.put("templates/users-list.tpl.html",'<xos-table config="vm.tableConfig" data="vm.users"></xos-table>')}]),function(){angular.module("xos.ceilometerDashboard").directive("ceilometerStats",function(){return{restrict:"E",scope:{name:"=name",tenant:"=tenant"},bindToController:!0,controllerAs:"vm",templateUrl:"templates/ceilometer-stats.tpl.html",controller:["$scope","Ceilometer",function(e,t){var n=this;this.getStats=function(e){n.loader=!0,t.getStats({tenant:e}).then(function(e){e.map(function(e){return e.resource_name=e.resource_name.replace("mysite_onos_vbng","ONOS_FABRIC"),e.resource_name=e.resource_name.replace("mysite_onos_volt","ONOS_CORD"),e.resource_name=e.resource_name.replace("mysite_vbng","mysite_vRouter"),e}),n.stats=e})["catch"](function(e){n.error=e.data})["finally"](function(){n.loader=!1})},e.$watch(function(){return n.name},function(e){e&&n.getStats(n.tenant)})}]}})}(),function(){angular.module("xos.ceilometerDashboard").directive("ceilometerSamples",["_","$stateParams","$interval",function(e,t,n){return{restrict:"E",scope:{},bindToController:!0,controllerAs:"vm",templateUrl:"templates/ceilometer-samples.tpl.html",controller:["Ceilometer",function(r){var s=this;this.chartColors=["#286090","#F7464A","#46BFBD","#FDB45C","#97BBCD","#4D5360","#8c4f9f"],this.chart={series:[],labels:[],data:[]},Chart.defaults.global.colours=this.chartColors,this.chartType="line";var a=["broadview.pt.packet-trace-lag-resolution","broadview.pt.packet-trace-ecmp-resolution"],i=!1,c=6e4;if(!t.name||!t.tenant)throw new Error("Missing Name and Tenant Params!");this.name=t.name,this.tenant=t.tenant,a.indexOf(this.name)>-1&&(i=!0,this.chartType="pie",c=1e4),this.getLabels=function(e){return e.reduce(function(e,t){var n=new Date(t.timestamp);return e.push(n.getHours()+":"+((n.getMinutes()<10?"0":"")+n.getMinutes())+":"+n.getSeconds()),e},[])},this.getData=function(e){return e.reduce(function(e,t){return e.push(t.volume),e},[])},this.chartMeters=[],this.addMeterToChart=function(t){s.chart.labels=s.getLabels(e.sortBy(s.samplesList[t],"timestamp")),s.chart.series.push(t),s.chart.data.push(s.getData(e.sortBy(s.samplesList[t],"timestamp"))),s.chartMeters.push(s.samplesList[t][0]),e.remove(s.sampleLabels,{id:t})},this.removeFromChart=function(t){s.chart.data.splice(s.chart.series.indexOf(t.resource_id),1),s.chart.series.splice(s.chart.series.indexOf(t.resource_id),1),s.chartMeters.splice(e.findIndex(s.chartMeters,{resource_id:t.resource_id}),1),s.sampleLabels.push({id:t.resource_id,name:t.resource_name||t.resource_id})},this.formatSamplesLabels=function(t){return e.uniq(t,"resource_id").reduce(function(e,t){return e.push({id:t.resource_id,name:t.resource_name||t.resource_id}),e},[])},this.formatPieChartData=function(t){s.chart.labels=t[0].metadata["lag-members"].replace(/\[|\]|'| /g,"").split(","),s.chart.options={legend:{display:!0}},t=e.groupBy(t,function(e){return e.metadata["dst-lag-member"]}),Chart.defaults.global.tooltipTemplate="<%if (label){%><%=label%>: <%}%><%= value %>%";var n=e.reduce(s.chart.labels,function(e,n){var r=t[n]?t[n].length:0;return e.push(r),e},[]),r=e.reduce(n,function(e,t){return e+t}),a=e.map(n,function(e){return Math.round(e/r*100)});console.log(r),s.chart.data=a},this.loader=!0,this.showSamples=function(){var t=void 0;t=i?r.getSamples(s.name,30):r.getSamples(s.name),t.then(function(t){return t.map(function(e){return e.resource_name=e.resource_name.replace("mysite_onos_vbng","ONOS_FABRIC"),e.resource_name=e.resource_name.replace("mysite_onos_volt","ONOS_CORD"),e.resource_name=e.resource_name.replace("mysite_vbng","mysite_vRouter"),e}),i?void s.formatPieChartData(t):(s.samplesList=e.groupBy(t,"resource_id"),s.sampleLabels=s.formatSamplesLabels(t),void s.addMeterToChart(s.tenant))})["catch"](function(e){s.error=e.data.detail})["finally"](function(){s.loader=!1})},n(function(){s.showSamples()},c),this.showSamples()}]}}])}(),function(){angular.module("xos.ceilometerDashboard").service("Ceilometer",["$http","$q",function(e,t){this.getMappings=function(){var n=t.defer();return e.get("/api/tenant/monitoring/dashboard/xos-slice-service-mapping/").then(function(e){n.resolve(e.data)})["catch"](function(e){n.reject(e)}),n.promise},this.getMeters=function(n){var r=t.defer();return e.get("/api/tenant/monitoring/dashboard/meters/",{cache:!0,params:n}).then(function(e){r.resolve(e.data)})["catch"](function(e){r.reject(e)}),r.promise},this.getSamples=function(n){var r=arguments.length<=1||void 0===arguments[1]?10:arguments[1],s=t.defer();return e.get("/api/tenant/monitoring/dashboard/metersamples/",{params:{meter:n,limit:r}}).then(function(e){s.resolve(e.data)})["catch"](function(e){s.reject(e)}),s.promise},this.getStats=function(n){var r=t.defer();return e.get("/api/tenant/monitoring/dashboard/meterstatistics/",{cache:!0,params:n}).then(function(e){r.resolve(e.data)})["catch"](function(e){r.reject(e)}),r.promise},this.selectedService=null,this.selectedSlice=null,this.selectedResource=null}])}(),function(){angular.module("xos.ceilometerDashboard").directive("ceilometerDashboard",["_",function(e){return{restrict:"E",scope:{},bindToController:!0,controllerAs:"vm",templateUrl:"templates/ceilometer-dashboard.tpl.html",controller:["Ceilometer",function(t){var n=this;this.showStats=!1,this.accordion={open:{}},this.openPanels=function(){t.selectedService&&(n.accordion.open[t.selectedService]=!0,t.selectedSlice&&(n.loadSliceMeter(t.selectedSlice,t.selectedService),n.selectedSlice=t.selectedSlice,t.selectedResource&&(n.selectedResource=t.selectedResource)))},this.loadMappings=function(){n.loader=!0,t.getMappings().then(function(e){e.map(function(e){return"service_ONOS_vBNG"===e.service&&(e.service="ONOS_FABRIC"),"service_ONOS_vOLT"===e.service&&(e.service="ONOS_CORD"),e.slices.map(function(e){"mysite_onos_volt"===e.slice&&(e.slice="ONOS_CORD"),"mysite_onos_vbng"===e.slice&&(e.slice="ONOS_FABRIC"),"mysite_vbng"===e.slice&&(e.slice="mysite_vRouter")}),e}),n.services=e,n.openPanels()})["catch"](function(e){n.error=e.data&&e.data.detail?e.data.detail:"An Error occurred. Please try again later."})["finally"](function(){n.loader=!1})},this.loadMappings(),this.loadSliceMeter=function(r,s){t.selectedSlice=null,t.selectedService=null,t.selectedResources=null,n.loader=!0,n.error=null,n.ceilometerError=null,t.getMeters({tenant:r.project_id}).then(function(a){n.selectedSlice=r.slice,n.selectedTenant=r.project_id,t.selectedSlice=r,t.selectedService=s,a.map(function(e){return e.resource_name=e.resource_name.replace("mysite_onos_vbng","ONOS_FABRIC"),e.resource_name=e.resource_name.replace("mysite_onos_volt","ONOS_CORD"),e.resource_name=e.resource_name.replace("mysite_vbng","mysite_vRouter"),e}),n.selectedResources=e.groupBy(a,"resource_name"),t.selectedResource&&(n.selectedMeters=n.selectedResources[t.selectedResource])})["catch"](function(e){return 503===e.status?n.ceilometerError=e.data.detail.specific_error:void(n.ceilometerError=e.data&&e.data.detail&&e.data.detail.specific_error?e.data.detail.specific_error:"An Error occurred. Please try again later.")})["finally"](function(){n.loader=!1})},this.selectedMeters=null,this.selectMeters=function(e,r){n.selectedMeters=e,t.selectedResource=r,n.selectedResource=r}}]}}])}(),angular.module("xos.ceilometerDashboard").run(["$location",function(e){e.path("/")}]);
\ No newline at end of file
diff --git a/xos/core/xoslib/static/vendor/xosCeilometerDashboardVendor.js b/xos/core/xoslib/static/vendor/xosCeilometerDashboardVendor.js
index 943474d..6754139 100644
--- a/xos/core/xoslib/static/vendor/xosCeilometerDashboardVendor.js
+++ b/xos/core/xoslib/static/vendor/xosCeilometerDashboardVendor.js
@@ -1,4338 +1 @@
-/**
- * @license AngularJS v1.4.7
- * (c) 2010-2015 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {'use strict';
-
-/* jshint ignore:start */
-var noop        = angular.noop;
-var extend      = angular.extend;
-var jqLite      = angular.element;
-var forEach     = angular.forEach;
-var isArray     = angular.isArray;
-var isString    = angular.isString;
-var isObject    = angular.isObject;
-var isUndefined = angular.isUndefined;
-var isDefined   = angular.isDefined;
-var isFunction  = angular.isFunction;
-var isElement   = angular.isElement;
-
-var ELEMENT_NODE = 1;
-var COMMENT_NODE = 8;
-
-var ADD_CLASS_SUFFIX = '-add';
-var REMOVE_CLASS_SUFFIX = '-remove';
-var EVENT_CLASS_PREFIX = 'ng-';
-var ACTIVE_CLASS_SUFFIX = '-active';
-
-var NG_ANIMATE_CLASSNAME = 'ng-animate';
-var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';
-
-// Detect proper transitionend/animationend event names.
-var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
-
-// If unprefixed events are not supported but webkit-prefixed are, use the latter.
-// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.
-// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`
-// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.
-// Register both events in case `window.onanimationend` is not supported because of that,
-// do the same for `transitionend` as Safari is likely to exhibit similar behavior.
-// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
-// therefore there is no reason to test anymore for other vendor prefixes:
-// http://caniuse.com/#search=transition
-if (isUndefined(window.ontransitionend) && isDefined(window.onwebkittransitionend)) {
-  CSS_PREFIX = '-webkit-';
-  TRANSITION_PROP = 'WebkitTransition';
-  TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
-} else {
-  TRANSITION_PROP = 'transition';
-  TRANSITIONEND_EVENT = 'transitionend';
-}
-
-if (isUndefined(window.onanimationend) && isDefined(window.onwebkitanimationend)) {
-  CSS_PREFIX = '-webkit-';
-  ANIMATION_PROP = 'WebkitAnimation';
-  ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
-} else {
-  ANIMATION_PROP = 'animation';
-  ANIMATIONEND_EVENT = 'animationend';
-}
-
-var DURATION_KEY = 'Duration';
-var PROPERTY_KEY = 'Property';
-var DELAY_KEY = 'Delay';
-var TIMING_KEY = 'TimingFunction';
-var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
-var ANIMATION_PLAYSTATE_KEY = 'PlayState';
-var SAFE_FAST_FORWARD_DURATION_VALUE = 9999;
-
-var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;
-var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
-var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
-var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
-
-var isPromiseLike = function(p) {
-  return p && p.then ? true : false;
-};
-
-function assertArg(arg, name, reason) {
-  if (!arg) {
-    throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
-  }
-  return arg;
-}
-
-function mergeClasses(a,b) {
-  if (!a && !b) return '';
-  if (!a) return b;
-  if (!b) return a;
-  if (isArray(a)) a = a.join(' ');
-  if (isArray(b)) b = b.join(' ');
-  return a + ' ' + b;
-}
-
-function packageStyles(options) {
-  var styles = {};
-  if (options && (options.to || options.from)) {
-    styles.to = options.to;
-    styles.from = options.from;
-  }
-  return styles;
-}
-
-function pendClasses(classes, fix, isPrefix) {
-  var className = '';
-  classes = isArray(classes)
-      ? classes
-      : classes && isString(classes) && classes.length
-          ? classes.split(/\s+/)
-          : [];
-  forEach(classes, function(klass, i) {
-    if (klass && klass.length > 0) {
-      className += (i > 0) ? ' ' : '';
-      className += isPrefix ? fix + klass
-                            : klass + fix;
-    }
-  });
-  return className;
-}
-
-function removeFromArray(arr, val) {
-  var index = arr.indexOf(val);
-  if (val >= 0) {
-    arr.splice(index, 1);
-  }
-}
-
-function stripCommentsFromElement(element) {
-  if (element instanceof jqLite) {
-    switch (element.length) {
-      case 0:
-        return [];
-        break;
-
-      case 1:
-        // there is no point of stripping anything if the element
-        // is the only element within the jqLite wrapper.
-        // (it's important that we retain the element instance.)
-        if (element[0].nodeType === ELEMENT_NODE) {
-          return element;
-        }
-        break;
-
-      default:
-        return jqLite(extractElementNode(element));
-        break;
-    }
-  }
-
-  if (element.nodeType === ELEMENT_NODE) {
-    return jqLite(element);
-  }
-}
-
-function extractElementNode(element) {
-  if (!element[0]) return element;
-  for (var i = 0; i < element.length; i++) {
-    var elm = element[i];
-    if (elm.nodeType == ELEMENT_NODE) {
-      return elm;
-    }
-  }
-}
-
-function $$addClass($$jqLite, element, className) {
-  forEach(element, function(elm) {
-    $$jqLite.addClass(elm, className);
-  });
-}
-
-function $$removeClass($$jqLite, element, className) {
-  forEach(element, function(elm) {
-    $$jqLite.removeClass(elm, className);
-  });
-}
-
-function applyAnimationClassesFactory($$jqLite) {
-  return function(element, options) {
-    if (options.addClass) {
-      $$addClass($$jqLite, element, options.addClass);
-      options.addClass = null;
-    }
-    if (options.removeClass) {
-      $$removeClass($$jqLite, element, options.removeClass);
-      options.removeClass = null;
-    }
-  }
-}
-
-function prepareAnimationOptions(options) {
-  options = options || {};
-  if (!options.$$prepared) {
-    var domOperation = options.domOperation || noop;
-    options.domOperation = function() {
-      options.$$domOperationFired = true;
-      domOperation();
-      domOperation = noop;
-    };
-    options.$$prepared = true;
-  }
-  return options;
-}
-
-function applyAnimationStyles(element, options) {
-  applyAnimationFromStyles(element, options);
-  applyAnimationToStyles(element, options);
-}
-
-function applyAnimationFromStyles(element, options) {
-  if (options.from) {
-    element.css(options.from);
-    options.from = null;
-  }
-}
-
-function applyAnimationToStyles(element, options) {
-  if (options.to) {
-    element.css(options.to);
-    options.to = null;
-  }
-}
-
-function mergeAnimationOptions(element, target, newOptions) {
-  var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || '');
-  var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');
-  var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);
-
-  if (newOptions.preparationClasses) {
-    target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses);
-    delete newOptions.preparationClasses;
-  }
-
-  // noop is basically when there is no callback; otherwise something has been set
-  var realDomOperation = target.domOperation !== noop ? target.domOperation : null;
-
-  extend(target, newOptions);
-
-  // 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.
-  if (realDomOperation) {
-    target.domOperation = realDomOperation;
-  }
-
-  if (classes.addClass) {
-    target.addClass = classes.addClass;
-  } else {
-    target.addClass = null;
-  }
-
-  if (classes.removeClass) {
-    target.removeClass = classes.removeClass;
-  } else {
-    target.removeClass = null;
-  }
-
-  return target;
-}
-
-function resolveElementClasses(existing, toAdd, toRemove) {
-  var ADD_CLASS = 1;
-  var REMOVE_CLASS = -1;
-
-  var flags = {};
-  existing = splitClassesToLookup(existing);
-
-  toAdd = splitClassesToLookup(toAdd);
-  forEach(toAdd, function(value, key) {
-    flags[key] = ADD_CLASS;
-  });
-
-  toRemove = splitClassesToLookup(toRemove);
-  forEach(toRemove, function(value, key) {
-    flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS;
-  });
-
-  var classes = {
-    addClass: '',
-    removeClass: ''
-  };
-
-  forEach(flags, function(val, klass) {
-    var prop, allow;
-    if (val === ADD_CLASS) {
-      prop = 'addClass';
-      allow = !existing[klass];
-    } else if (val === REMOVE_CLASS) {
-      prop = 'removeClass';
-      allow = existing[klass];
-    }
-    if (allow) {
-      if (classes[prop].length) {
-        classes[prop] += ' ';
-      }
-      classes[prop] += klass;
-    }
-  });
-
-  function splitClassesToLookup(classes) {
-    if (isString(classes)) {
-      classes = classes.split(' ');
-    }
-
-    var obj = {};
-    forEach(classes, function(klass) {
-      // sometimes the split leaves empty string values
-      // incase extra spaces were applied to the options
-      if (klass.length) {
-        obj[klass] = true;
-      }
-    });
-    return obj;
-  }
-
-  return classes;
-}
-
-function getDomNode(element) {
-  return (element instanceof angular.element) ? element[0] : element;
-}
-
-function applyGeneratedPreparationClasses(element, event, options) {
-  var classes = '';
-  if (event) {
-    classes = pendClasses(event, EVENT_CLASS_PREFIX, true);
-  }
-  if (options.addClass) {
-    classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX));
-  }
-  if (options.removeClass) {
-    classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX));
-  }
-  if (classes.length) {
-    options.preparationClasses = classes;
-    element.addClass(classes);
-  }
-}
-
-function clearGeneratedClasses(element, options) {
-  if (options.preparationClasses) {
-    element.removeClass(options.preparationClasses);
-    options.preparationClasses = null;
-  }
-  if (options.activeClasses) {
-    element.removeClass(options.activeClasses);
-    options.activeClasses = null;
-  }
-}
-
-function blockTransitions(node, duration) {
-  // we use a negative delay value since it performs blocking
-  // yet it doesn't kill any existing transitions running on the
-  // same element which makes this safe for class-based animations
-  var value = duration ? '-' + duration + 's' : '';
-  applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
-  return [TRANSITION_DELAY_PROP, value];
-}
-
-function blockKeyframeAnimations(node, applyBlock) {
-  var value = applyBlock ? 'paused' : '';
-  var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
-  applyInlineStyle(node, [key, value]);
-  return [key, value];
-}
-
-function applyInlineStyle(node, styleTuple) {
-  var prop = styleTuple[0];
-  var value = styleTuple[1];
-  node.style[prop] = value;
-}
-
-function concatWithSpace(a,b) {
-  if (!a) return b;
-  if (!b) return a;
-  return a + ' ' + b;
-}
-
-var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
-  var queue, cancelFn;
-
-  function scheduler(tasks) {
-    // we make a copy since RAFScheduler mutates the state
-    // of the passed in array variable and this would be difficult
-    // to track down on the outside code
-    queue = queue.concat(tasks);
-    nextTick();
-  }
-
-  queue = scheduler.queue = [];
-
-  /* waitUntilQuiet does two things:
-   * 1. It will run the FINAL `fn` value only when an uncancelled RAF has passed through
-   * 2. It will delay the next wave of tasks from running until the quiet `fn` has run.
-   *
-   * The motivation here is that animation code can request more time from the scheduler
-   * before the next wave runs. This allows for certain DOM properties such as classes to
-   * be resolved in time for the next animation to run.
-   */
-  scheduler.waitUntilQuiet = function(fn) {
-    if (cancelFn) cancelFn();
-
-    cancelFn = $$rAF(function() {
-      cancelFn = null;
-      fn();
-      nextTick();
-    });
-  };
-
-  return scheduler;
-
-  function nextTick() {
-    if (!queue.length) return;
-
-    var items = queue.shift();
-    for (var i = 0; i < items.length; i++) {
-      items[i]();
-    }
-
-    if (!cancelFn) {
-      $$rAF(function() {
-        if (!cancelFn) nextTick();
-      });
-    }
-  }
-}];
-
-var $$AnimateChildrenDirective = [function() {
-  return function(scope, element, attrs) {
-    var val = attrs.ngAnimateChildren;
-    if (angular.isString(val) && val.length === 0) { //empty attribute
-      element.data(NG_ANIMATE_CHILDREN_DATA, true);
-    } else {
-      attrs.$observe('ngAnimateChildren', function(value) {
-        value = value === 'on' || value === 'true';
-        element.data(NG_ANIMATE_CHILDREN_DATA, value);
-      });
-    }
-  };
-}];
-
-var ANIMATE_TIMER_KEY = '$$animateCss';
-
-/**
- * @ngdoc service
- * @name $animateCss
- * @kind object
- *
- * @description
- * The `$animateCss` service is a useful utility to trigger customized CSS-based transitions/keyframes
- * from a JavaScript-based animation or directly from a directive. The purpose of `$animateCss` is NOT
- * to side-step how `$animate` and ngAnimate work, but the goal is to allow pre-existing animations or
- * directives to create more complex animations that can be purely driven using CSS code.
- *
- * Note that only browsers that support CSS transitions and/or keyframe animations are capable of
- * rendering animations triggered via `$animateCss` (bad news for IE9 and lower).
- *
- * ## Usage
- * Once again, `$animateCss` is designed to be used inside of a registered JavaScript animation that
- * is powered by ngAnimate. It is possible to use `$animateCss` directly inside of a directive, however,
- * any automatic control over cancelling animations and/or preventing animations from being run on
- * child elements will not be handled by Angular. For this to work as expected, please use `$animate` to
- * trigger the animation and then setup a JavaScript animation that injects `$animateCss` to trigger
- * the CSS animation.
- *
- * The example below shows how we can create a folding animation on an element using `ng-if`:
- *
- * ```html
- * <!-- notice the `fold-animation` CSS class -->
- * <div ng-if="onOff" class="fold-animation">
- *   This element will go BOOM
- * </div>
- * <button ng-click="onOff=true">Fold In</button>
- * ```
- *
- * Now we create the **JavaScript animation** that will trigger the CSS transition:
- *
- * ```js
- * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) {
- *   return {
- *     enter: function(element, doneFn) {
- *       var height = element[0].offsetHeight;
- *       return $animateCss(element, {
- *         from: { height:'0px' },
- *         to: { height:height + 'px' },
- *         duration: 1 // one second
- *       });
- *     }
- *   }
- * }]);
- * ```
- *
- * ## More Advanced Uses
- *
- * `$animateCss` is the underlying code that ngAnimate uses to power **CSS-based animations** behind the scenes. Therefore CSS hooks
- * like `.ng-EVENT`, `.ng-EVENT-active`, `.ng-EVENT-stagger` are all features that can be triggered using `$animateCss` via JavaScript code.
- *
- * This also means that just about any combination of adding classes, removing classes, setting styles, dynamically setting a keyframe animation,
- * applying a hardcoded duration or delay value, changing the animation easing or applying a stagger animation are all options that work with
- * `$animateCss`. The service itself is smart enough to figure out the combination of options and examine the element styling properties in order
- * to provide a working animation that will run in CSS.
- *
- * The example below showcases a more advanced version of the `.fold-animation` from the example above:
- *
- * ```js
- * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) {
- *   return {
- *     enter: function(element, doneFn) {
- *       var height = element[0].offsetHeight;
- *       return $animateCss(element, {
- *         addClass: 'red large-text pulse-twice',
- *         easing: 'ease-out',
- *         from: { height:'0px' },
- *         to: { height:height + 'px' },
- *         duration: 1 // one second
- *       });
- *     }
- *   }
- * }]);
- * ```
- *
- * Since we're adding/removing CSS classes then the CSS transition will also pick those up:
- *
- * ```css
- * /&#42; since a hardcoded duration value of 1 was provided in the JavaScript animation code,
- * the CSS classes below will be transitioned despite them being defined as regular CSS classes &#42;/
- * .red { background:red; }
- * .large-text { font-size:20px; }
- *
- * /&#42; we can also use a keyframe animation and $animateCss will make it work alongside the transition &#42;/
- * .pulse-twice {
- *   animation: 0.5s pulse linear 2;
- *   -webkit-animation: 0.5s pulse linear 2;
- * }
- *
- * @keyframes pulse {
- *   from { transform: scale(0.5); }
- *   to { transform: scale(1.5); }
- * }
- *
- * @-webkit-keyframes pulse {
- *   from { -webkit-transform: scale(0.5); }
- *   to { -webkit-transform: scale(1.5); }
- * }
- * ```
- *
- * Given this complex combination of CSS classes, styles and options, `$animateCss` will figure everything out and make the animation happen.
- *
- * ## How the Options are handled
- *
- * `$animateCss` is very versatile and intelligent when it comes to figuring out what configurations to apply to the element to ensure the animation
- * 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
- * styles using the `from` and `to` properties.
- *
- * ```js
- * var animator = $animateCss(element, {
- *   from: { background:'red' },
- *   to: { background:'blue' }
- * });
- * animator.start();
- * ```
- *
- * ```css
- * .rotating-animation {
- *   animation:0.5s rotate linear;
- *   -webkit-animation:0.5s rotate linear;
- * }
- *
- * @keyframes rotate {
- *   from { transform: rotate(0deg); }
- *   to { transform: rotate(360deg); }
- * }
- *
- * @-webkit-keyframes rotate {
- *   from { -webkit-transform: rotate(0deg); }
- *   to { -webkit-transform: rotate(360deg); }
- * }
- * ```
- *
- * 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
- * going to be detected from what the keyframe styles on the CSS class are. In this event, `$animateCss` will automatically create an inline transition
- * 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
- * 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
- * and spread across the transition and keyframe animation.
- *
- * ## What is returned
- *
- * `$animateCss` works in two stages: a preparation phase and an animation phase. Therefore when `$animateCss` is first called it will NOT actually
- * 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
- * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties:
- *
- * ```js
- * var animator = $animateCss(element, { ... });
- * ```
- *
- * Now what do the contents of our `animator` variable look like:
- *
- * ```js
- * {
- *   // starts the animation
- *   start: Function,
- *
- *   // ends (aborts) the animation
- *   end: Function
- * }
- * ```
- *
- * 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.
- * 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 stlyes may have been
- * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties
- * and that changing them will not reconfigure the parameters of the animation.
- *
- * ### runner.done() vs runner.then()
- * 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
- * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**.
- * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()`
- * unless you really need a digest to kick off afterwards.
- *
- * 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
- * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code).
- * Check the {@link ngAnimate.$animateCss#usage animation code above} to see how this works.
- *
- * @param {DOMElement} element the element that will be animated
- * @param {object} options the animation-related options that will be applied during the animation
- *
- * * `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
- * 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.)
- * * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both).
- * * `transitionStyle` - The raw CSS transition style that will be used (e.g. `1s linear all`).
- * * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).
- * * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation.
- * * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition.
- * * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation.
- * * `removeClass` - A space separated list of CSS classes that will be removed from the element and spread across the animation.
- * * `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`
- * is provided then the animation will be skipped entirely.
- * * `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
- * 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
- * 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
- * CSS delay value.
- * * `stagger` - A numeric time value representing the delay between successively animated elements
- * ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.})
- * * `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
- * * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`)
- * * `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 occuring on the classes being added and removed.)
- * * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once
- *    the animation is closed. This is useful for when the styles are used purely for the sake of
- *    the animation and do not have a lasting visual effect on the element (e.g. a colapse and open animation).
- *    By default this value is set to `false`.
- *
- * @return {object} an object with start and end methods and details about the animation.
- *
- * * `start` - The method to start the animation. This will return a `Promise` when called.
- * * `end` - This method will cancel the animation and remove all applied CSS classes and styles.
- */
-var ONE_SECOND = 1000;
-var BASE_TEN = 10;
-
-var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
-var CLOSING_TIME_BUFFER = 1.5;
-
-var DETECT_CSS_PROPERTIES = {
-  transitionDuration:      TRANSITION_DURATION_PROP,
-  transitionDelay:         TRANSITION_DELAY_PROP,
-  transitionProperty:      TRANSITION_PROP + PROPERTY_KEY,
-  animationDuration:       ANIMATION_DURATION_PROP,
-  animationDelay:          ANIMATION_DELAY_PROP,
-  animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY
-};
-
-var DETECT_STAGGER_CSS_PROPERTIES = {
-  transitionDuration:      TRANSITION_DURATION_PROP,
-  transitionDelay:         TRANSITION_DELAY_PROP,
-  animationDuration:       ANIMATION_DURATION_PROP,
-  animationDelay:          ANIMATION_DELAY_PROP
-};
-
-function getCssKeyframeDurationStyle(duration) {
-  return [ANIMATION_DURATION_PROP, duration + 's'];
-}
-
-function getCssDelayStyle(delay, isKeyframeAnimation) {
-  var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;
-  return [prop, delay + 's'];
-}
-
-function computeCssStyles($window, element, properties) {
-  var styles = Object.create(null);
-  var detectedStyles = $window.getComputedStyle(element) || {};
-  forEach(properties, function(formalStyleName, actualStyleName) {
-    var val = detectedStyles[formalStyleName];
-    if (val) {
-      var c = val.charAt(0);
-
-      // only numerical-based values have a negative sign or digit as the first value
-      if (c === '-' || c === '+' || c >= 0) {
-        val = parseMaxTime(val);
-      }
-
-      // by setting this to null in the event that the delay is not set or is set directly as 0
-      // then we can still allow for zegative values to be used later on and not mistake this
-      // value for being greater than any other negative value.
-      if (val === 0) {
-        val = null;
-      }
-      styles[actualStyleName] = val;
-    }
-  });
-
-  return styles;
-}
-
-function parseMaxTime(str) {
-  var maxValue = 0;
-  var values = str.split(/\s*,\s*/);
-  forEach(values, function(value) {
-    // it's always safe to consider only second values and omit `ms` values since
-    // getComputedStyle will always handle the conversion for us
-    if (value.charAt(value.length - 1) == 's') {
-      value = value.substring(0, value.length - 1);
-    }
-    value = parseFloat(value) || 0;
-    maxValue = maxValue ? Math.max(value, maxValue) : value;
-  });
-  return maxValue;
-}
-
-function truthyTimingValue(val) {
-  return val === 0 || val != null;
-}
-
-function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
-  var style = TRANSITION_PROP;
-  var value = duration + 's';
-  if (applyOnlyDuration) {
-    style += DURATION_KEY;
-  } else {
-    value += ' linear all';
-  }
-  return [style, value];
-}
-
-function createLocalCacheLookup() {
-  var cache = Object.create(null);
-  return {
-    flush: function() {
-      cache = Object.create(null);
-    },
-
-    count: function(key) {
-      var entry = cache[key];
-      return entry ? entry.total : 0;
-    },
-
-    get: function(key) {
-      var entry = cache[key];
-      return entry && entry.value;
-    },
-
-    put: function(key, value) {
-      if (!cache[key]) {
-        cache[key] = { total: 1, value: value };
-      } else {
-        cache[key].total++;
-      }
-    }
-  };
-}
-
-// we do not reassign an already present style value since
-// if we detect the style property value again we may be
-// detecting styles that were added via the `from` styles.
-// We make use of `isDefined` here since an empty string
-// or null value (which is what getPropertyValue will return
-// for a non-existing style) will still be marked as a valid
-// value for the style (a falsy value implies that the style
-// is to be removed at the end of the animation). If we had a simple
-// "OR" statement then it would not be enough to catch that.
-function registerRestorableStyles(backup, node, properties) {
-  forEach(properties, function(prop) {
-    backup[prop] = isDefined(backup[prop])
-        ? backup[prop]
-        : node.style.getPropertyValue(prop);
-  });
-}
-
-var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
-  var gcsLookup = createLocalCacheLookup();
-  var gcsStaggerLookup = createLocalCacheLookup();
-
-  this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout',
-               '$$forceReflow', '$sniffer', '$$rAFScheduler', '$animate',
-       function($window,   $$jqLite,   $$AnimateRunner,   $timeout,
-                $$forceReflow,   $sniffer,   $$rAFScheduler, $animate) {
-
-    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
-
-    var parentCounter = 0;
-    function gcsHashFn(node, extraClasses) {
-      var KEY = "$$ngAnimateParentKey";
-      var parentNode = node.parentNode;
-      var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter);
-      return parentID + '-' + node.getAttribute('class') + '-' + extraClasses;
-    }
-
-    function computeCachedCssStyles(node, className, cacheKey, properties) {
-      var timings = gcsLookup.get(cacheKey);
-
-      if (!timings) {
-        timings = computeCssStyles($window, node, properties);
-        if (timings.animationIterationCount === 'infinite') {
-          timings.animationIterationCount = 1;
-        }
-      }
-
-      // we keep putting this in multiple times even though the value and the cacheKey are the same
-      // because we're keeping an interal tally of how many duplicate animations are detected.
-      gcsLookup.put(cacheKey, timings);
-      return timings;
-    }
-
-    function computeCachedCssStaggerStyles(node, className, cacheKey, properties) {
-      var stagger;
-
-      // if we have one or more existing matches of matching elements
-      // containing the same parent + CSS styles (which is how cacheKey works)
-      // then staggering is possible
-      if (gcsLookup.count(cacheKey) > 0) {
-        stagger = gcsStaggerLookup.get(cacheKey);
-
-        if (!stagger) {
-          var staggerClassName = pendClasses(className, '-stagger');
-
-          $$jqLite.addClass(node, staggerClassName);
-
-          stagger = computeCssStyles($window, node, properties);
-
-          // force the conversion of a null value to zero incase not set
-          stagger.animationDuration = Math.max(stagger.animationDuration, 0);
-          stagger.transitionDuration = Math.max(stagger.transitionDuration, 0);
-
-          $$jqLite.removeClass(node, staggerClassName);
-
-          gcsStaggerLookup.put(cacheKey, stagger);
-        }
-      }
-
-      return stagger || {};
-    }
-
-    var cancelLastRAFRequest;
-    var rafWaitQueue = [];
-    function waitUntilQuiet(callback) {
-      rafWaitQueue.push(callback);
-      $$rAFScheduler.waitUntilQuiet(function() {
-        gcsLookup.flush();
-        gcsStaggerLookup.flush();
-
-        // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
-        // PLEASE EXAMINE THE `$$forceReflow` service to understand why.
-        var pageWidth = $$forceReflow();
-
-        // we use a for loop to ensure that if the queue is changed
-        // during this looping then it will consider new requests
-        for (var i = 0; i < rafWaitQueue.length; i++) {
-          rafWaitQueue[i](pageWidth);
-        }
-        rafWaitQueue.length = 0;
-      });
-    }
-
-    function computeTimings(node, className, cacheKey) {
-      var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES);
-      var aD = timings.animationDelay;
-      var tD = timings.transitionDelay;
-      timings.maxDelay = aD && tD
-          ? Math.max(aD, tD)
-          : (aD || tD);
-      timings.maxDuration = Math.max(
-          timings.animationDuration * timings.animationIterationCount,
-          timings.transitionDuration);
-
-      return timings;
-    }
-
-    return function init(element, options) {
-      var restoreStyles = {};
-      var node = getDomNode(element);
-      if (!node
-          || !node.parentNode
-          || !$animate.enabled()) {
-        return closeAndReturnNoopAnimator();
-      }
-
-      options = prepareAnimationOptions(options);
-
-      var temporaryStyles = [];
-      var classes = element.attr('class');
-      var styles = packageStyles(options);
-      var animationClosed;
-      var animationPaused;
-      var animationCompleted;
-      var runner;
-      var runnerHost;
-      var maxDelay;
-      var maxDelayTime;
-      var maxDuration;
-      var maxDurationTime;
-
-      if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) {
-        return closeAndReturnNoopAnimator();
-      }
-
-      var method = options.event && isArray(options.event)
-            ? options.event.join(' ')
-            : options.event;
-
-      var isStructural = method && options.structural;
-      var structuralClassName = '';
-      var addRemoveClassName = '';
-
-      if (isStructural) {
-        structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true);
-      } else if (method) {
-        structuralClassName = method;
-      }
-
-      if (options.addClass) {
-        addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX);
-      }
-
-      if (options.removeClass) {
-        if (addRemoveClassName.length) {
-          addRemoveClassName += ' ';
-        }
-        addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX);
-      }
-
-      // there may be a situation where a structural animation is combined together
-      // with CSS classes that need to resolve before the animation is computed.
-      // However this means that there is no explicit CSS code to block the animation
-      // from happening (by setting 0s none in the class name). If this is the case
-      // we need to apply the classes before the first rAF so we know to continue if
-      // there actually is a detected transition or keyframe animation
-      if (options.applyClassesEarly && addRemoveClassName.length) {
-        applyAnimationClasses(element, options);
-      }
-
-      var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim();
-      var fullClassName = classes + ' ' + preparationClasses;
-      var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);
-      var hasToStyles = styles.to && Object.keys(styles.to).length > 0;
-      var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;
-
-      // there is no way we can trigger an animation if no styles and
-      // no classes are being applied which would then trigger a transition,
-      // unless there a is raw keyframe value that is applied to the element.
-      if (!containsKeyframeAnimation
-           && !hasToStyles
-           && !preparationClasses) {
-        return closeAndReturnNoopAnimator();
-      }
-
-      var cacheKey, stagger;
-      if (options.stagger > 0) {
-        var staggerVal = parseFloat(options.stagger);
-        stagger = {
-          transitionDelay: staggerVal,
-          animationDelay: staggerVal,
-          transitionDuration: 0,
-          animationDuration: 0
-        };
-      } else {
-        cacheKey = gcsHashFn(node, fullClassName);
-        stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);
-      }
-
-      if (!options.$$skipPreparationClasses) {
-        $$jqLite.addClass(element, preparationClasses);
-      }
-
-      var applyOnlyDuration;
-
-      if (options.transitionStyle) {
-        var transitionStyle = [TRANSITION_PROP, options.transitionStyle];
-        applyInlineStyle(node, transitionStyle);
-        temporaryStyles.push(transitionStyle);
-      }
-
-      if (options.duration >= 0) {
-        applyOnlyDuration = node.style[TRANSITION_PROP].length > 0;
-        var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration);
-
-        // we set the duration so that it will be picked up by getComputedStyle later
-        applyInlineStyle(node, durationStyle);
-        temporaryStyles.push(durationStyle);
-      }
-
-      if (options.keyframeStyle) {
-        var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle];
-        applyInlineStyle(node, keyframeStyle);
-        temporaryStyles.push(keyframeStyle);
-      }
-
-      var itemIndex = stagger
-          ? options.staggerIndex >= 0
-              ? options.staggerIndex
-              : gcsLookup.count(cacheKey)
-          : 0;
-
-      var isFirst = itemIndex === 0;
-
-      // this is a pre-emptive way of forcing the setup classes to be added and applied INSTANTLY
-      // without causing any combination of transitions to kick in. By adding a negative delay value
-      // it forces the setup class' transition to end immediately. We later then remove the negative
-      // transition delay to allow for the transition to naturally do it's thing. The beauty here is
-      // that if there is no transition defined then nothing will happen and this will also allow
-      // other transitions to be stacked on top of each other without any chopping them out.
-      if (isFirst && !options.skipBlocking) {
-        blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
-      }
-
-      var timings = computeTimings(node, fullClassName, cacheKey);
-      var relativeDelay = timings.maxDelay;
-      maxDelay = Math.max(relativeDelay, 0);
-      maxDuration = timings.maxDuration;
-
-      var flags = {};
-      flags.hasTransitions          = timings.transitionDuration > 0;
-      flags.hasAnimations           = timings.animationDuration > 0;
-      flags.hasTransitionAll        = flags.hasTransitions && timings.transitionProperty == 'all';
-      flags.applyTransitionDuration = hasToStyles && (
-                                        (flags.hasTransitions && !flags.hasTransitionAll)
-                                         || (flags.hasAnimations && !flags.hasTransitions));
-      flags.applyAnimationDuration  = options.duration && flags.hasAnimations;
-      flags.applyTransitionDelay    = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions);
-      flags.applyAnimationDelay     = truthyTimingValue(options.delay) && flags.hasAnimations;
-      flags.recalculateTimingStyles = addRemoveClassName.length > 0;
-
-      if (flags.applyTransitionDuration || flags.applyAnimationDuration) {
-        maxDuration = options.duration ? parseFloat(options.duration) : maxDuration;
-
-        if (flags.applyTransitionDuration) {
-          flags.hasTransitions = true;
-          timings.transitionDuration = maxDuration;
-          applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0;
-          temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration));
-        }
-
-        if (flags.applyAnimationDuration) {
-          flags.hasAnimations = true;
-          timings.animationDuration = maxDuration;
-          temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration));
-        }
-      }
-
-      if (maxDuration === 0 && !flags.recalculateTimingStyles) {
-        return closeAndReturnNoopAnimator();
-      }
-
-      if (options.delay != null) {
-        var delayStyle = parseFloat(options.delay);
-
-        if (flags.applyTransitionDelay) {
-          temporaryStyles.push(getCssDelayStyle(delayStyle));
-        }
-
-        if (flags.applyAnimationDelay) {
-          temporaryStyles.push(getCssDelayStyle(delayStyle, true));
-        }
-      }
-
-      // we need to recalculate the delay value since we used a pre-emptive negative
-      // delay value and the delay value is required for the final event checking. This
-      // property will ensure that this will happen after the RAF phase has passed.
-      if (options.duration == null && timings.transitionDuration > 0) {
-        flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst;
-      }
-
-      maxDelayTime = maxDelay * ONE_SECOND;
-      maxDurationTime = maxDuration * ONE_SECOND;
-      if (!options.skipBlocking) {
-        flags.blockTransition = timings.transitionDuration > 0;
-        flags.blockKeyframeAnimation = timings.animationDuration > 0 &&
-                                       stagger.animationDelay > 0 &&
-                                       stagger.animationDuration === 0;
-      }
-
-      if (options.from) {
-        if (options.cleanupStyles) {
-          registerRestorableStyles(restoreStyles, node, Object.keys(options.from));
-        }
-        applyAnimationFromStyles(element, options);
-      }
-
-      if (flags.blockTransition || flags.blockKeyframeAnimation) {
-        applyBlocking(maxDuration);
-      } else if (!options.skipBlocking) {
-        blockTransitions(node, false);
-      }
-
-      // TODO(matsko): for 1.5 change this code to have an animator object for better debugging
-      return {
-        $$willAnimate: true,
-        end: endFn,
-        start: function() {
-          if (animationClosed) return;
-
-          runnerHost = {
-            end: endFn,
-            cancel: cancelFn,
-            resume: null, //this will be set during the start() phase
-            pause: null
-          };
-
-          runner = new $$AnimateRunner(runnerHost);
-
-          waitUntilQuiet(start);
-
-          // we don't have access to pause/resume the animation
-          // since it hasn't run yet. AnimateRunner will therefore
-          // set noop functions for resume and pause and they will
-          // later be overridden once the animation is triggered
-          return runner;
-        }
-      };
-
-      function endFn() {
-        close();
-      }
-
-      function cancelFn() {
-        close(true);
-      }
-
-      function close(rejected) { // jshint ignore:line
-        // if the promise has been called already then we shouldn't close
-        // the animation again
-        if (animationClosed || (animationCompleted && animationPaused)) return;
-        animationClosed = true;
-        animationPaused = false;
-
-        if (!options.$$skipPreparationClasses) {
-          $$jqLite.removeClass(element, preparationClasses);
-        }
-        $$jqLite.removeClass(element, activeClasses);
-
-        blockKeyframeAnimations(node, false);
-        blockTransitions(node, false);
-
-        forEach(temporaryStyles, function(entry) {
-          // There is only one way to remove inline style properties entirely from elements.
-          // By using `removeProperty` this works, but we need to convert camel-cased CSS
-          // styles down to hyphenated values.
-          node.style[entry[0]] = '';
-        });
-
-        applyAnimationClasses(element, options);
-        applyAnimationStyles(element, options);
-
-        if (Object.keys(restoreStyles).length) {
-          forEach(restoreStyles, function(value, prop) {
-            value ? node.style.setProperty(prop, value)
-                  : node.style.removeProperty(prop);
-          });
-        }
-
-        // the reason why we have this option is to allow a synchronous closing callback
-        // that is fired as SOON as the animation ends (when the CSS is removed) or if
-        // the animation never takes off at all. A good example is a leave animation since
-        // the element must be removed just after the animation is over or else the element
-        // will appear on screen for one animation frame causing an overbearing flicker.
-        if (options.onDone) {
-          options.onDone();
-        }
-
-        // if the preparation function fails then the promise is not setup
-        if (runner) {
-          runner.complete(!rejected);
-        }
-      }
-
-      function applyBlocking(duration) {
-        if (flags.blockTransition) {
-          blockTransitions(node, duration);
-        }
-
-        if (flags.blockKeyframeAnimation) {
-          blockKeyframeAnimations(node, !!duration);
-        }
-      }
-
-      function closeAndReturnNoopAnimator() {
-        runner = new $$AnimateRunner({
-          end: endFn,
-          cancel: cancelFn
-        });
-
-        // should flush the cache animation
-        waitUntilQuiet(noop);
-        close();
-
-        return {
-          $$willAnimate: false,
-          start: function() {
-            return runner;
-          },
-          end: endFn
-        };
-      }
-
-      function start() {
-        if (animationClosed) return;
-        if (!node.parentNode) {
-          close();
-          return;
-        }
-
-        var startTime, events = [];
-
-        // even though we only pause keyframe animations here the pause flag
-        // will still happen when transitions are used. Only the transition will
-        // not be paused since that is not possible. If the animation ends when
-        // paused then it will not complete until unpaused or cancelled.
-        var playPause = function(playAnimation) {
-          if (!animationCompleted) {
-            animationPaused = !playAnimation;
-            if (timings.animationDuration) {
-              var value = blockKeyframeAnimations(node, animationPaused);
-              animationPaused
-                  ? temporaryStyles.push(value)
-                  : removeFromArray(temporaryStyles, value);
-            }
-          } else if (animationPaused && playAnimation) {
-            animationPaused = false;
-            close();
-          }
-        };
-
-        // checking the stagger duration prevents an accidently cascade of the CSS delay style
-        // being inherited from the parent. If the transition duration is zero then we can safely
-        // rely that the delay value is an intential stagger delay style.
-        var maxStagger = itemIndex > 0
-                         && ((timings.transitionDuration && stagger.transitionDuration === 0) ||
-                            (timings.animationDuration && stagger.animationDuration === 0))
-                         && Math.max(stagger.animationDelay, stagger.transitionDelay);
-        if (maxStagger) {
-          $timeout(triggerAnimationStart,
-                   Math.floor(maxStagger * itemIndex * ONE_SECOND),
-                   false);
-        } else {
-          triggerAnimationStart();
-        }
-
-        // this will decorate the existing promise runner with pause/resume methods
-        runnerHost.resume = function() {
-          playPause(true);
-        };
-
-        runnerHost.pause = function() {
-          playPause(false);
-        };
-
-        function triggerAnimationStart() {
-          // just incase a stagger animation kicks in when the animation
-          // itself was cancelled entirely
-          if (animationClosed) return;
-
-          applyBlocking(false);
-
-          forEach(temporaryStyles, function(entry) {
-            var key = entry[0];
-            var value = entry[1];
-            node.style[key] = value;
-          });
-
-          applyAnimationClasses(element, options);
-          $$jqLite.addClass(element, activeClasses);
-
-          if (flags.recalculateTimingStyles) {
-            fullClassName = node.className + ' ' + preparationClasses;
-            cacheKey = gcsHashFn(node, fullClassName);
-
-            timings = computeTimings(node, fullClassName, cacheKey);
-            relativeDelay = timings.maxDelay;
-            maxDelay = Math.max(relativeDelay, 0);
-            maxDuration = timings.maxDuration;
-
-            if (maxDuration === 0) {
-              close();
-              return;
-            }
-
-            flags.hasTransitions = timings.transitionDuration > 0;
-            flags.hasAnimations = timings.animationDuration > 0;
-          }
-
-          if (flags.applyAnimationDelay) {
-            relativeDelay = typeof options.delay !== "boolean" && truthyTimingValue(options.delay)
-                  ? parseFloat(options.delay)
-                  : relativeDelay;
-
-            maxDelay = Math.max(relativeDelay, 0);
-            timings.animationDelay = relativeDelay;
-            delayStyle = getCssDelayStyle(relativeDelay, true);
-            temporaryStyles.push(delayStyle);
-            node.style[delayStyle[0]] = delayStyle[1];
-          }
-
-          maxDelayTime = maxDelay * ONE_SECOND;
-          maxDurationTime = maxDuration * ONE_SECOND;
-
-          if (options.easing) {
-            var easeProp, easeVal = options.easing;
-            if (flags.hasTransitions) {
-              easeProp = TRANSITION_PROP + TIMING_KEY;
-              temporaryStyles.push([easeProp, easeVal]);
-              node.style[easeProp] = easeVal;
-            }
-            if (flags.hasAnimations) {
-              easeProp = ANIMATION_PROP + TIMING_KEY;
-              temporaryStyles.push([easeProp, easeVal]);
-              node.style[easeProp] = easeVal;
-            }
-          }
-
-          if (timings.transitionDuration) {
-            events.push(TRANSITIONEND_EVENT);
-          }
-
-          if (timings.animationDuration) {
-            events.push(ANIMATIONEND_EVENT);
-          }
-
-          startTime = Date.now();
-          var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime;
-          var endTime = startTime + timerTime;
-
-          var animationsData = element.data(ANIMATE_TIMER_KEY) || [];
-          var setupFallbackTimer = true;
-          if (animationsData.length) {
-            var currentTimerData = animationsData[0];
-            setupFallbackTimer = endTime > currentTimerData.expectedEndTime;
-            if (setupFallbackTimer) {
-              $timeout.cancel(currentTimerData.timer);
-            } else {
-              animationsData.push(close);
-            }
-          }
-
-          if (setupFallbackTimer) {
-            var timer = $timeout(onAnimationExpired, timerTime, false);
-            animationsData[0] = {
-              timer: timer,
-              expectedEndTime: endTime
-            };
-            animationsData.push(close);
-            element.data(ANIMATE_TIMER_KEY, animationsData);
-          }
-
-          element.on(events.join(' '), onAnimationProgress);
-          if (options.to) {
-            if (options.cleanupStyles) {
-              registerRestorableStyles(restoreStyles, node, Object.keys(options.to));
-            }
-            applyAnimationToStyles(element, options);
-          }
-        }
-
-        function onAnimationExpired() {
-          var animationsData = element.data(ANIMATE_TIMER_KEY);
-
-          // this will be false in the event that the element was
-          // removed from the DOM (via a leave animation or something
-          // similar)
-          if (animationsData) {
-            for (var i = 1; i < animationsData.length; i++) {
-              animationsData[i]();
-            }
-            element.removeData(ANIMATE_TIMER_KEY);
-          }
-        }
-
-        function onAnimationProgress(event) {
-          event.stopPropagation();
-          var ev = event.originalEvent || event;
-          var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now();
-
-          /* Firefox (or possibly just Gecko) likes to not round values up
-           * when a ms measurement is used for the animation */
-          var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));
-
-          /* $manualTimeStamp is a mocked timeStamp value which is set
-           * within browserTrigger(). This is only here so that tests can
-           * mock animations properly. Real events fallback to event.timeStamp,
-           * or, if they don't, then a timeStamp is automatically created for them.
-           * We're checking to see if the timeStamp surpasses the expected delay,
-           * but we're using elapsedTime instead of the timeStamp on the 2nd
-           * pre-condition since animations sometimes close off early */
-          if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
-            // we set this flag to ensure that if the transition is paused then, when resumed,
-            // the animation will automatically close itself since transitions cannot be paused.
-            animationCompleted = true;
-            close();
-          }
-        }
-      }
-    };
-  }];
-}];
-
-var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationProvider) {
-  $$animationProvider.drivers.push('$$animateCssDriver');
-
-  var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim';
-  var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor';
-
-  var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out';
-  var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in';
-
-  function isDocumentFragment(node) {
-    return node.parentNode && node.parentNode.nodeType === 11;
-  }
-
-  this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document',
-       function($animateCss,   $rootScope,   $$AnimateRunner,   $rootElement,   $sniffer,   $$jqLite,   $document) {
-
-    // only browsers that support these properties can render animations
-    if (!$sniffer.animations && !$sniffer.transitions) return noop;
-
-    var bodyNode = $document[0].body;
-    var rootNode = getDomNode($rootElement);
-
-    var rootBodyElement = jqLite(
-      // this is to avoid using something that exists outside of the body
-      // we also special case the doc fragement case because our unit test code
-      // appends the $rootElement to the body after the app has been bootstrapped
-      isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode
-    );
-
-    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
-
-    return function initDriverFn(animationDetails) {
-      return animationDetails.from && animationDetails.to
-          ? prepareFromToAnchorAnimation(animationDetails.from,
-                                         animationDetails.to,
-                                         animationDetails.classes,
-                                         animationDetails.anchors)
-          : prepareRegularAnimation(animationDetails);
-    };
-
-    function filterCssClasses(classes) {
-      //remove all the `ng-` stuff
-      return classes.replace(/\bng-\S+\b/g, '');
-    }
-
-    function getUniqueValues(a, b) {
-      if (isString(a)) a = a.split(' ');
-      if (isString(b)) b = b.split(' ');
-      return a.filter(function(val) {
-        return b.indexOf(val) === -1;
-      }).join(' ');
-    }
-
-    function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {
-      var clone = jqLite(getDomNode(outAnchor).cloneNode(true));
-      var startingClasses = filterCssClasses(getClassVal(clone));
-
-      outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
-      inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
-
-      clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME);
-
-      rootBodyElement.append(clone);
-
-      var animatorIn, animatorOut = prepareOutAnimation();
-
-      // the user may not end up using the `out` animation and
-      // only making use of the `in` animation or vice-versa.
-      // In either case we should allow this and not assume the
-      // animation is over unless both animations are not used.
-      if (!animatorOut) {
-        animatorIn = prepareInAnimation();
-        if (!animatorIn) {
-          return end();
-        }
-      }
-
-      var startingAnimator = animatorOut || animatorIn;
-
-      return {
-        start: function() {
-          var runner;
-
-          var currentAnimation = startingAnimator.start();
-          currentAnimation.done(function() {
-            currentAnimation = null;
-            if (!animatorIn) {
-              animatorIn = prepareInAnimation();
-              if (animatorIn) {
-                currentAnimation = animatorIn.start();
-                currentAnimation.done(function() {
-                  currentAnimation = null;
-                  end();
-                  runner.complete();
-                });
-                return currentAnimation;
-              }
-            }
-            // in the event that there is no `in` animation
-            end();
-            runner.complete();
-          });
-
-          runner = new $$AnimateRunner({
-            end: endFn,
-            cancel: endFn
-          });
-
-          return runner;
-
-          function endFn() {
-            if (currentAnimation) {
-              currentAnimation.end();
-            }
-          }
-        }
-      };
-
-      function calculateAnchorStyles(anchor) {
-        var styles = {};
-
-        var coords = getDomNode(anchor).getBoundingClientRect();
-
-        // we iterate directly since safari messes up and doesn't return
-        // all the keys for the coods object when iterated
-        forEach(['width','height','top','left'], function(key) {
-          var value = coords[key];
-          switch (key) {
-            case 'top':
-              value += bodyNode.scrollTop;
-              break;
-            case 'left':
-              value += bodyNode.scrollLeft;
-              break;
-          }
-          styles[key] = Math.floor(value) + 'px';
-        });
-        return styles;
-      }
-
-      function prepareOutAnimation() {
-        var animator = $animateCss(clone, {
-          addClass: NG_OUT_ANCHOR_CLASS_NAME,
-          delay: true,
-          from: calculateAnchorStyles(outAnchor)
-        });
-
-        // read the comment within `prepareRegularAnimation` to understand
-        // why this check is necessary
-        return animator.$$willAnimate ? animator : null;
-      }
-
-      function getClassVal(element) {
-        return element.attr('class') || '';
-      }
-
-      function prepareInAnimation() {
-        var endingClasses = filterCssClasses(getClassVal(inAnchor));
-        var toAdd = getUniqueValues(endingClasses, startingClasses);
-        var toRemove = getUniqueValues(startingClasses, endingClasses);
-
-        var animator = $animateCss(clone, {
-          to: calculateAnchorStyles(inAnchor),
-          addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd,
-          removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove,
-          delay: true
-        });
-
-        // read the comment within `prepareRegularAnimation` to understand
-        // why this check is necessary
-        return animator.$$willAnimate ? animator : null;
-      }
-
-      function end() {
-        clone.remove();
-        outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);
-        inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);
-      }
-    }
-
-    function prepareFromToAnchorAnimation(from, to, classes, anchors) {
-      var fromAnimation = prepareRegularAnimation(from, noop);
-      var toAnimation = prepareRegularAnimation(to, noop);
-
-      var anchorAnimations = [];
-      forEach(anchors, function(anchor) {
-        var outElement = anchor['out'];
-        var inElement = anchor['in'];
-        var animator = prepareAnchoredAnimation(classes, outElement, inElement);
-        if (animator) {
-          anchorAnimations.push(animator);
-        }
-      });
-
-      // no point in doing anything when there are no elements to animate
-      if (!fromAnimation && !toAnimation && anchorAnimations.length === 0) return;
-
-      return {
-        start: function() {
-          var animationRunners = [];
-
-          if (fromAnimation) {
-            animationRunners.push(fromAnimation.start());
-          }
-
-          if (toAnimation) {
-            animationRunners.push(toAnimation.start());
-          }
-
-          forEach(anchorAnimations, function(animation) {
-            animationRunners.push(animation.start());
-          });
-
-          var runner = new $$AnimateRunner({
-            end: endFn,
-            cancel: endFn // CSS-driven animations cannot be cancelled, only ended
-          });
-
-          $$AnimateRunner.all(animationRunners, function(status) {
-            runner.complete(status);
-          });
-
-          return runner;
-
-          function endFn() {
-            forEach(animationRunners, function(runner) {
-              runner.end();
-            });
-          }
-        }
-      };
-    }
-
-    function prepareRegularAnimation(animationDetails) {
-      var element = animationDetails.element;
-      var options = animationDetails.options || {};
-
-      if (animationDetails.structural) {
-        options.event = animationDetails.event;
-        options.structural = true;
-        options.applyClassesEarly = true;
-
-        // we special case the leave animation since we want to ensure that
-        // the element is removed as soon as the animation is over. Otherwise
-        // a flicker might appear or the element may not be removed at all
-        if (animationDetails.event === 'leave') {
-          options.onDone = options.domOperation;
-        }
-      }
-
-      // We assign the preparationClasses as the actual animation event since
-      // the internals of $animateCss will just suffix the event token values
-      // with `-active` to trigger the animation.
-      if (options.preparationClasses) {
-        options.event = concatWithSpace(options.event, options.preparationClasses);
-      }
-
-      var animator = $animateCss(element, options);
-
-      // the driver lookup code inside of $$animation attempts to spawn a
-      // driver one by one until a driver returns a.$$willAnimate animator object.
-      // $animateCss will always return an object, however, it will pass in
-      // a flag as a hint as to whether an animation was detected or not
-      return animator.$$willAnimate ? animator : null;
-    }
-  }];
-}];
-
-// TODO(matsko): use caching here to speed things up for detection
-// TODO(matsko): add documentation
-//  by the time...
-
-var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
-  this.$get = ['$injector', '$$AnimateRunner', '$$jqLite',
-       function($injector,   $$AnimateRunner,   $$jqLite) {
-
-    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
-         // $animateJs(element, 'enter');
-    return function(element, event, classes, options) {
-      // the `classes` argument is optional and if it is not used
-      // then the classes will be resolved from the element's className
-      // property as well as options.addClass/options.removeClass.
-      if (arguments.length === 3 && isObject(classes)) {
-        options = classes;
-        classes = null;
-      }
-
-      options = prepareAnimationOptions(options);
-      if (!classes) {
-        classes = element.attr('class') || '';
-        if (options.addClass) {
-          classes += ' ' + options.addClass;
-        }
-        if (options.removeClass) {
-          classes += ' ' + options.removeClass;
-        }
-      }
-
-      var classesToAdd = options.addClass;
-      var classesToRemove = options.removeClass;
-
-      // the lookupAnimations function returns a series of animation objects that are
-      // matched up with one or more of the CSS classes. These animation objects are
-      // defined via the module.animation factory function. If nothing is detected then
-      // we don't return anything which then makes $animation query the next driver.
-      var animations = lookupAnimations(classes);
-      var before, after;
-      if (animations.length) {
-        var afterFn, beforeFn;
-        if (event == 'leave') {
-          beforeFn = 'leave';
-          afterFn = 'afterLeave'; // TODO(matsko): get rid of this
-        } else {
-          beforeFn = 'before' + event.charAt(0).toUpperCase() + event.substr(1);
-          afterFn = event;
-        }
-
-        if (event !== 'enter' && event !== 'move') {
-          before = packageAnimations(element, event, options, animations, beforeFn);
-        }
-        after  = packageAnimations(element, event, options, animations, afterFn);
-      }
-
-      // no matching animations
-      if (!before && !after) return;
-
-      function applyOptions() {
-        options.domOperation();
-        applyAnimationClasses(element, options);
-      }
-
-      return {
-        start: function() {
-          var closeActiveAnimations;
-          var chain = [];
-
-          if (before) {
-            chain.push(function(fn) {
-              closeActiveAnimations = before(fn);
-            });
-          }
-
-          if (chain.length) {
-            chain.push(function(fn) {
-              applyOptions();
-              fn(true);
-            });
-          } else {
-            applyOptions();
-          }
-
-          if (after) {
-            chain.push(function(fn) {
-              closeActiveAnimations = after(fn);
-            });
-          }
-
-          var animationClosed = false;
-          var runner = new $$AnimateRunner({
-            end: function() {
-              endAnimations();
-            },
-            cancel: function() {
-              endAnimations(true);
-            }
-          });
-
-          $$AnimateRunner.chain(chain, onComplete);
-          return runner;
-
-          function onComplete(success) {
-            animationClosed = true;
-            applyOptions();
-            applyAnimationStyles(element, options);
-            runner.complete(success);
-          }
-
-          function endAnimations(cancelled) {
-            if (!animationClosed) {
-              (closeActiveAnimations || noop)(cancelled);
-              onComplete(cancelled);
-            }
-          }
-        }
-      };
-
-      function executeAnimationFn(fn, element, event, options, onDone) {
-        var args;
-        switch (event) {
-          case 'animate':
-            args = [element, options.from, options.to, onDone];
-            break;
-
-          case 'setClass':
-            args = [element, classesToAdd, classesToRemove, onDone];
-            break;
-
-          case 'addClass':
-            args = [element, classesToAdd, onDone];
-            break;
-
-          case 'removeClass':
-            args = [element, classesToRemove, onDone];
-            break;
-
-          default:
-            args = [element, onDone];
-            break;
-        }
-
-        args.push(options);
-
-        var value = fn.apply(fn, args);
-        if (value) {
-          if (isFunction(value.start)) {
-            value = value.start();
-          }
-
-          if (value instanceof $$AnimateRunner) {
-            value.done(onDone);
-          } else if (isFunction(value)) {
-            // optional onEnd / onCancel callback
-            return value;
-          }
-        }
-
-        return noop;
-      }
-
-      function groupEventedAnimations(element, event, options, animations, fnName) {
-        var operations = [];
-        forEach(animations, function(ani) {
-          var animation = ani[fnName];
-          if (!animation) return;
-
-          // note that all of these animations will run in parallel
-          operations.push(function() {
-            var runner;
-            var endProgressCb;
-
-            var resolved = false;
-            var onAnimationComplete = function(rejected) {
-              if (!resolved) {
-                resolved = true;
-                (endProgressCb || noop)(rejected);
-                runner.complete(!rejected);
-              }
-            };
-
-            runner = new $$AnimateRunner({
-              end: function() {
-                onAnimationComplete();
-              },
-              cancel: function() {
-                onAnimationComplete(true);
-              }
-            });
-
-            endProgressCb = executeAnimationFn(animation, element, event, options, function(result) {
-              var cancelled = result === false;
-              onAnimationComplete(cancelled);
-            });
-
-            return runner;
-          });
-        });
-
-        return operations;
-      }
-
-      function packageAnimations(element, event, options, animations, fnName) {
-        var operations = groupEventedAnimations(element, event, options, animations, fnName);
-        if (operations.length === 0) {
-          var a,b;
-          if (fnName === 'beforeSetClass') {
-            a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass');
-            b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass');
-          } else if (fnName === 'setClass') {
-            a = groupEventedAnimations(element, 'removeClass', options, animations, 'removeClass');
-            b = groupEventedAnimations(element, 'addClass', options, animations, 'addClass');
-          }
-
-          if (a) {
-            operations = operations.concat(a);
-          }
-          if (b) {
-            operations = operations.concat(b);
-          }
-        }
-
-        if (operations.length === 0) return;
-
-        // TODO(matsko): add documentation
-        return function startAnimation(callback) {
-          var runners = [];
-          if (operations.length) {
-            forEach(operations, function(animateFn) {
-              runners.push(animateFn());
-            });
-          }
-
-          runners.length ? $$AnimateRunner.all(runners, callback) : callback();
-
-          return function endFn(reject) {
-            forEach(runners, function(runner) {
-              reject ? runner.cancel() : runner.end();
-            });
-          };
-        };
-      }
-    };
-
-    function lookupAnimations(classes) {
-      classes = isArray(classes) ? classes : classes.split(' ');
-      var matches = [], flagMap = {};
-      for (var i=0; i < classes.length; i++) {
-        var klass = classes[i],
-            animationFactory = $animateProvider.$$registeredAnimations[klass];
-        if (animationFactory && !flagMap[klass]) {
-          matches.push($injector.get(animationFactory));
-          flagMap[klass] = true;
-        }
-      }
-      return matches;
-    }
-  }];
-}];
-
-var $$AnimateJsDriverProvider = ['$$animationProvider', function($$animationProvider) {
-  $$animationProvider.drivers.push('$$animateJsDriver');
-  this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) {
-    return function initDriverFn(animationDetails) {
-      if (animationDetails.from && animationDetails.to) {
-        var fromAnimation = prepareAnimation(animationDetails.from);
-        var toAnimation = prepareAnimation(animationDetails.to);
-        if (!fromAnimation && !toAnimation) return;
-
-        return {
-          start: function() {
-            var animationRunners = [];
-
-            if (fromAnimation) {
-              animationRunners.push(fromAnimation.start());
-            }
-
-            if (toAnimation) {
-              animationRunners.push(toAnimation.start());
-            }
-
-            $$AnimateRunner.all(animationRunners, done);
-
-            var runner = new $$AnimateRunner({
-              end: endFnFactory(),
-              cancel: endFnFactory()
-            });
-
-            return runner;
-
-            function endFnFactory() {
-              return function() {
-                forEach(animationRunners, function(runner) {
-                  // at this point we cannot cancel animations for groups just yet. 1.5+
-                  runner.end();
-                });
-              };
-            }
-
-            function done(status) {
-              runner.complete(status);
-            }
-          }
-        };
-      } else {
-        return prepareAnimation(animationDetails);
-      }
-    };
-
-    function prepareAnimation(animationDetails) {
-      // TODO(matsko): make sure to check for grouped animations and delegate down to normal animations
-      var element = animationDetails.element;
-      var event = animationDetails.event;
-      var options = animationDetails.options;
-      var classes = animationDetails.classes;
-      return $$animateJs(element, event, classes, options);
-    }
-  }];
-}];
-
-var NG_ANIMATE_ATTR_NAME = 'data-ng-animate';
-var NG_ANIMATE_PIN_DATA = '$ngAnimatePin';
-var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
-  var PRE_DIGEST_STATE = 1;
-  var RUNNING_STATE = 2;
-
-  var rules = this.rules = {
-    skip: [],
-    cancel: [],
-    join: []
-  };
-
-  function isAllowed(ruleType, element, currentAnimation, previousAnimation) {
-    return rules[ruleType].some(function(fn) {
-      return fn(element, currentAnimation, previousAnimation);
-    });
-  }
-
-  function hasAnimationClasses(options, and) {
-    options = options || {};
-    var a = (options.addClass || '').length > 0;
-    var b = (options.removeClass || '').length > 0;
-    return and ? a && b : a || b;
-  }
-
-  rules.join.push(function(element, newAnimation, currentAnimation) {
-    // if the new animation is class-based then we can just tack that on
-    return !newAnimation.structural && hasAnimationClasses(newAnimation.options);
-  });
-
-  rules.skip.push(function(element, newAnimation, currentAnimation) {
-    // there is no need to animate anything if no classes are being added and
-    // there is no structural animation that will be triggered
-    return !newAnimation.structural && !hasAnimationClasses(newAnimation.options);
-  });
-
-  rules.skip.push(function(element, newAnimation, currentAnimation) {
-    // why should we trigger a new structural animation if the element will
-    // be removed from the DOM anyway?
-    return currentAnimation.event == 'leave' && newAnimation.structural;
-  });
-
-  rules.skip.push(function(element, newAnimation, currentAnimation) {
-    // if there is an ongoing current animation then don't even bother running the class-based animation
-    return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural;
-  });
-
-  rules.cancel.push(function(element, newAnimation, currentAnimation) {
-    // there can never be two structural animations running at the same time
-    return currentAnimation.structural && newAnimation.structural;
-  });
-
-  rules.cancel.push(function(element, newAnimation, currentAnimation) {
-    // if the previous animation is already running, but the new animation will
-    // be triggered, but the new animation is structural
-    return currentAnimation.state === RUNNING_STATE && newAnimation.structural;
-  });
-
-  rules.cancel.push(function(element, newAnimation, currentAnimation) {
-    var nO = newAnimation.options;
-    var cO = currentAnimation.options;
-
-    // if the exact same CSS class is added/removed then it's safe to cancel it
-    return (nO.addClass && nO.addClass === cO.removeClass) || (nO.removeClass && nO.removeClass === cO.addClass);
-  });
-
-  this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
-               '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow',
-       function($$rAF,   $rootScope,   $rootElement,   $document,   $$HashMap,
-                $$animation,   $$AnimateRunner,   $templateRequest,   $$jqLite,   $$forceReflow) {
-
-    var activeAnimationsLookup = new $$HashMap();
-    var disabledElementsLookup = new $$HashMap();
-    var animationsEnabled = null;
-
-    function postDigestTaskFactory() {
-      var postDigestCalled = false;
-      return function(fn) {
-        // we only issue a call to postDigest before
-        // it has first passed. This prevents any callbacks
-        // from not firing once the animation has completed
-        // since it will be out of the digest cycle.
-        if (postDigestCalled) {
-          fn();
-        } else {
-          $rootScope.$$postDigest(function() {
-            postDigestCalled = true;
-            fn();
-          });
-        }
-      };
-    }
-
-    // Wait until all directive and route-related templates are downloaded and
-    // compiled. The $templateRequest.totalPendingRequests variable keeps track of
-    // all of the remote templates being currently downloaded. If there are no
-    // templates currently downloading then the watcher will still fire anyway.
-    var deregisterWatch = $rootScope.$watch(
-      function() { return $templateRequest.totalPendingRequests === 0; },
-      function(isEmpty) {
-        if (!isEmpty) return;
-        deregisterWatch();
-
-        // Now that all templates have been downloaded, $animate will wait until
-        // the post digest queue is empty before enabling animations. By having two
-        // calls to $postDigest calls we can ensure that the flag is enabled at the
-        // very end of the post digest queue. Since all of the animations in $animate
-        // use $postDigest, it's important that the code below executes at the end.
-        // This basically means that the page is fully downloaded and compiled before
-        // any animations are triggered.
-        $rootScope.$$postDigest(function() {
-          $rootScope.$$postDigest(function() {
-            // we check for null directly in the event that the application already called
-            // .enabled() with whatever arguments that it provided it with
-            if (animationsEnabled === null) {
-              animationsEnabled = true;
-            }
-          });
-        });
-      }
-    );
-
-    var callbackRegistry = {};
-
-    // remember that the classNameFilter is set during the provider/config
-    // stage therefore we can optimize here and setup a helper function
-    var classNameFilter = $animateProvider.classNameFilter();
-    var isAnimatableClassName = !classNameFilter
-              ? function() { return true; }
-              : function(className) {
-                return classNameFilter.test(className);
-              };
-
-    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
-
-    function normalizeAnimationOptions(element, options) {
-      return mergeAnimationOptions(element, options, {});
-    }
-
-    function findCallbacks(element, event) {
-      var targetNode = getDomNode(element);
-
-      var matches = [];
-      var entries = callbackRegistry[event];
-      if (entries) {
-        forEach(entries, function(entry) {
-          if (entry.node.contains(targetNode)) {
-            matches.push(entry.callback);
-          }
-        });
-      }
-
-      return matches;
-    }
-
-    return {
-      on: function(event, container, callback) {
-        var node = extractElementNode(container);
-        callbackRegistry[event] = callbackRegistry[event] || [];
-        callbackRegistry[event].push({
-          node: node,
-          callback: callback
-        });
-      },
-
-      off: function(event, container, callback) {
-        var entries = callbackRegistry[event];
-        if (!entries) return;
-
-        callbackRegistry[event] = arguments.length === 1
-            ? null
-            : filterFromRegistry(entries, container, callback);
-
-        function filterFromRegistry(list, matchContainer, matchCallback) {
-          var containerNode = extractElementNode(matchContainer);
-          return list.filter(function(entry) {
-            var isMatch = entry.node === containerNode &&
-                            (!matchCallback || entry.callback === matchCallback);
-            return !isMatch;
-          });
-        }
-      },
-
-      pin: function(element, parentElement) {
-        assertArg(isElement(element), 'element', 'not an element');
-        assertArg(isElement(parentElement), 'parentElement', 'not an element');
-        element.data(NG_ANIMATE_PIN_DATA, parentElement);
-      },
-
-      push: function(element, event, options, domOperation) {
-        options = options || {};
-        options.domOperation = domOperation;
-        return queueAnimation(element, event, options);
-      },
-
-      // this method has four signatures:
-      //  () - global getter
-      //  (bool) - global setter
-      //  (element) - element getter
-      //  (element, bool) - element setter<F37>
-      enabled: function(element, bool) {
-        var argCount = arguments.length;
-
-        if (argCount === 0) {
-          // () - Global getter
-          bool = !!animationsEnabled;
-        } else {
-          var hasElement = isElement(element);
-
-          if (!hasElement) {
-            // (bool) - Global setter
-            bool = animationsEnabled = !!element;
-          } else {
-            var node = getDomNode(element);
-            var recordExists = disabledElementsLookup.get(node);
-
-            if (argCount === 1) {
-              // (element) - Element getter
-              bool = !recordExists;
-            } else {
-              // (element, bool) - Element setter
-              bool = !!bool;
-              if (!bool) {
-                disabledElementsLookup.put(node, true);
-              } else if (recordExists) {
-                disabledElementsLookup.remove(node);
-              }
-            }
-          }
-        }
-
-        return bool;
-      }
-    };
-
-    function queueAnimation(element, event, options) {
-      var node, parent;
-      element = stripCommentsFromElement(element);
-      if (element) {
-        node = getDomNode(element);
-        parent = element.parent();
-      }
-
-      options = prepareAnimationOptions(options);
-
-      // we create a fake runner with a working promise.
-      // These methods will become available after the digest has passed
-      var runner = new $$AnimateRunner();
-
-      // this is used to trigger callbacks in postDigest mode
-      var runInNextPostDigestOrNow = postDigestTaskFactory();
-
-      if (isArray(options.addClass)) {
-        options.addClass = options.addClass.join(' ');
-      }
-
-      if (options.addClass && !isString(options.addClass)) {
-        options.addClass = null;
-      }
-
-      if (isArray(options.removeClass)) {
-        options.removeClass = options.removeClass.join(' ');
-      }
-
-      if (options.removeClass && !isString(options.removeClass)) {
-        options.removeClass = null;
-      }
-
-      if (options.from && !isObject(options.from)) {
-        options.from = null;
-      }
-
-      if (options.to && !isObject(options.to)) {
-        options.to = null;
-      }
-
-      // there are situations where a directive issues an animation for
-      // a jqLite wrapper that contains only comment nodes... If this
-      // happens then there is no way we can perform an animation
-      if (!node) {
-        close();
-        return runner;
-      }
-
-      var className = [node.className, options.addClass, options.removeClass].join(' ');
-      if (!isAnimatableClassName(className)) {
-        close();
-        return runner;
-      }
-
-      var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
-
-      // this is a hard disable of all animations for the application or on
-      // the element itself, therefore  there is no need to continue further
-      // past this point if not enabled
-      var skipAnimations = !animationsEnabled || disabledElementsLookup.get(node);
-      var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
-      var hasExistingAnimation = !!existingAnimation.state;
-
-      // there is no point in traversing the same collection of parent ancestors if a followup
-      // animation will be run on the same element that already did all that checking work
-      if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state != PRE_DIGEST_STATE)) {
-        skipAnimations = !areAnimationsAllowed(element, parent, event);
-      }
-
-      if (skipAnimations) {
-        close();
-        return runner;
-      }
-
-      if (isStructural) {
-        closeChildAnimations(element);
-      }
-
-      var newAnimation = {
-        structural: isStructural,
-        element: element,
-        event: event,
-        close: close,
-        options: options,
-        runner: runner
-      };
-
-      if (hasExistingAnimation) {
-        var skipAnimationFlag = isAllowed('skip', element, newAnimation, existingAnimation);
-        if (skipAnimationFlag) {
-          if (existingAnimation.state === RUNNING_STATE) {
-            close();
-            return runner;
-          } else {
-            mergeAnimationOptions(element, existingAnimation.options, options);
-            return existingAnimation.runner;
-          }
-        }
-
-        var cancelAnimationFlag = isAllowed('cancel', element, newAnimation, existingAnimation);
-        if (cancelAnimationFlag) {
-          if (existingAnimation.state === RUNNING_STATE) {
-            // this will end the animation right away and it is safe
-            // to do so since the animation is already running and the
-            // runner callback code will run in async
-            existingAnimation.runner.end();
-          } else if (existingAnimation.structural) {
-            // this means that the animation is queued into a digest, but
-            // hasn't started yet. Therefore it is safe to run the close
-            // method which will call the runner methods in async.
-            existingAnimation.close();
-          } else {
-            // this will merge the new animation options into existing animation options
-            mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
-            return existingAnimation.runner;
-          }
-        } else {
-          // a joined animation means that this animation will take over the existing one
-          // so an example would involve a leave animation taking over an enter. Then when
-          // the postDigest kicks in the enter will be ignored.
-          var joinAnimationFlag = isAllowed('join', element, newAnimation, existingAnimation);
-          if (joinAnimationFlag) {
-            if (existingAnimation.state === RUNNING_STATE) {
-              normalizeAnimationOptions(element, options);
-            } else {
-              applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
-
-              event = newAnimation.event = existingAnimation.event;
-              options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
-
-              //we return the same runner since only the option values of this animation will
-              //be fed into the `existingAnimation`.
-              return existingAnimation.runner;
-            }
-          }
-        }
-      } else {
-        // normalization in this case means that it removes redundant CSS classes that
-        // already exist (addClass) or do not exist (removeClass) on the element
-        normalizeAnimationOptions(element, options);
-      }
-
-      // when the options are merged and cleaned up we may end up not having to do
-      // an animation at all, therefore we should check this before issuing a post
-      // digest callback. Structural animations will always run no matter what.
-      var isValidAnimation = newAnimation.structural;
-      if (!isValidAnimation) {
-        // animate (from/to) can be quickly checked first, otherwise we check if any classes are present
-        isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0)
-                            || hasAnimationClasses(newAnimation.options);
-      }
-
-      if (!isValidAnimation) {
-        close();
-        clearElementAnimationState(element);
-        return runner;
-      }
-
-      // the counter keeps track of cancelled animations
-      var counter = (existingAnimation.counter || 0) + 1;
-      newAnimation.counter = counter;
-
-      markElementAnimationState(element, PRE_DIGEST_STATE, newAnimation);
-
-      $rootScope.$$postDigest(function() {
-        var animationDetails = activeAnimationsLookup.get(node);
-        var animationCancelled = !animationDetails;
-        animationDetails = animationDetails || {};
-
-        // if addClass/removeClass is called before something like enter then the
-        // registered parent element may not be present. The code below will ensure
-        // that a final value for parent element is obtained
-        var parentElement = element.parent() || [];
-
-        // animate/structural/class-based animations all have requirements. Otherwise there
-        // is no point in performing an animation. The parent node must also be set.
-        var isValidAnimation = parentElement.length > 0
-                                && (animationDetails.event === 'animate'
-                                    || animationDetails.structural
-                                    || hasAnimationClasses(animationDetails.options));
-
-        // this means that the previous animation was cancelled
-        // even if the follow-up animation is the same event
-        if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) {
-          // if another animation did not take over then we need
-          // to make sure that the domOperation and options are
-          // handled accordingly
-          if (animationCancelled) {
-            applyAnimationClasses(element, options);
-            applyAnimationStyles(element, options);
-          }
-
-          // if the event changed from something like enter to leave then we do
-          // it, otherwise if it's the same then the end result will be the same too
-          if (animationCancelled || (isStructural && animationDetails.event !== event)) {
-            options.domOperation();
-            runner.end();
-          }
-
-          // in the event that the element animation was not cancelled or a follow-up animation
-          // isn't allowed to animate from here then we need to clear the state of the element
-          // so that any future animations won't read the expired animation data.
-          if (!isValidAnimation) {
-            clearElementAnimationState(element);
-          }
-
-          return;
-        }
-
-        // this combined multiple class to addClass / removeClass into a setClass event
-        // so long as a structural event did not take over the animation
-        event = !animationDetails.structural && hasAnimationClasses(animationDetails.options, true)
-            ? 'setClass'
-            : animationDetails.event;
-
-        markElementAnimationState(element, RUNNING_STATE);
-        var realRunner = $$animation(element, event, animationDetails.options);
-
-        realRunner.done(function(status) {
-          close(!status);
-          var animationDetails = activeAnimationsLookup.get(node);
-          if (animationDetails && animationDetails.counter === counter) {
-            clearElementAnimationState(getDomNode(element));
-          }
-          notifyProgress(runner, event, 'close', {});
-        });
-
-        // this will update the runner's flow-control events based on
-        // the `realRunner` object.
-        runner.setHost(realRunner);
-        notifyProgress(runner, event, 'start', {});
-      });
-
-      return runner;
-
-      function notifyProgress(runner, event, phase, data) {
-        runInNextPostDigestOrNow(function() {
-          var callbacks = findCallbacks(element, event);
-          if (callbacks.length) {
-            // do not optimize this call here to RAF because
-            // we don't know how heavy the callback code here will
-            // be and if this code is buffered then this can
-            // lead to a performance regression.
-            $$rAF(function() {
-              forEach(callbacks, function(callback) {
-                callback(element, phase, data);
-              });
-            });
-          }
-        });
-        runner.progress(event, phase, data);
-      }
-
-      function close(reject) { // jshint ignore:line
-        clearGeneratedClasses(element, options);
-        applyAnimationClasses(element, options);
-        applyAnimationStyles(element, options);
-        options.domOperation();
-        runner.complete(!reject);
-      }
-    }
-
-    function closeChildAnimations(element) {
-      var node = getDomNode(element);
-      var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']');
-      forEach(children, function(child) {
-        var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME));
-        var animationDetails = activeAnimationsLookup.get(child);
-        switch (state) {
-          case RUNNING_STATE:
-            animationDetails.runner.end();
-            /* falls through */
-          case PRE_DIGEST_STATE:
-            if (animationDetails) {
-              activeAnimationsLookup.remove(child);
-            }
-            break;
-        }
-      });
-    }
-
-    function clearElementAnimationState(element) {
-      var node = getDomNode(element);
-      node.removeAttribute(NG_ANIMATE_ATTR_NAME);
-      activeAnimationsLookup.remove(node);
-    }
-
-    function isMatchingElement(nodeOrElmA, nodeOrElmB) {
-      return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
-    }
-
-    function areAnimationsAllowed(element, parentElement, event) {
-      var bodyElement = jqLite($document[0].body);
-      var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML';
-      var rootElementDetected = isMatchingElement(element, $rootElement);
-      var parentAnimationDetected = false;
-      var animateChildren;
-
-      var parentHost = element.data(NG_ANIMATE_PIN_DATA);
-      if (parentHost) {
-        parentElement = parentHost;
-      }
-
-      while (parentElement && parentElement.length) {
-        if (!rootElementDetected) {
-          // angular doesn't want to attempt to animate elements outside of the application
-          // therefore we need to ensure that the rootElement is an ancestor of the current element
-          rootElementDetected = isMatchingElement(parentElement, $rootElement);
-        }
-
-        var parentNode = parentElement[0];
-        if (parentNode.nodeType !== ELEMENT_NODE) {
-          // no point in inspecting the #document element
-          break;
-        }
-
-        var details = activeAnimationsLookup.get(parentNode) || {};
-        // either an enter, leave or move animation will commence
-        // therefore we can't allow any animations to take place
-        // but if a parent animation is class-based then that's ok
-        if (!parentAnimationDetected) {
-          parentAnimationDetected = details.structural || disabledElementsLookup.get(parentNode);
-        }
-
-        if (isUndefined(animateChildren) || animateChildren === true) {
-          var value = parentElement.data(NG_ANIMATE_CHILDREN_DATA);
-          if (isDefined(value)) {
-            animateChildren = value;
-          }
-        }
-
-        // there is no need to continue traversing at this point
-        if (parentAnimationDetected && animateChildren === false) break;
-
-        if (!rootElementDetected) {
-          // angular doesn't want to attempt to animate elements outside of the application
-          // therefore we need to ensure that the rootElement is an ancestor of the current element
-          rootElementDetected = isMatchingElement(parentElement, $rootElement);
-          if (!rootElementDetected) {
-            parentHost = parentElement.data(NG_ANIMATE_PIN_DATA);
-            if (parentHost) {
-              parentElement = parentHost;
-            }
-          }
-        }
-
-        if (!bodyElementDetected) {
-          // we also need to ensure that the element is or will be apart of the body element
-          // otherwise it is pointless to even issue an animation to be rendered
-          bodyElementDetected = isMatchingElement(parentElement, bodyElement);
-        }
-
-        parentElement = parentElement.parent();
-      }
-
-      var allowAnimation = !parentAnimationDetected || animateChildren;
-      return allowAnimation && rootElementDetected && bodyElementDetected;
-    }
-
-    function markElementAnimationState(element, state, details) {
-      details = details || {};
-      details.state = state;
-
-      var node = getDomNode(element);
-      node.setAttribute(NG_ANIMATE_ATTR_NAME, state);
-
-      var oldValue = activeAnimationsLookup.get(node);
-      var newValue = oldValue
-          ? extend(oldValue, details)
-          : details;
-      activeAnimationsLookup.put(node, newValue);
-    }
-  }];
-}];
-
-var $$AnimateAsyncRunFactory = ['$$rAF', function($$rAF) {
-  var waitQueue = [];
-
-  function waitForTick(fn) {
-    waitQueue.push(fn);
-    if (waitQueue.length > 1) return;
-    $$rAF(function() {
-      for (var i = 0; i < waitQueue.length; i++) {
-        waitQueue[i]();
-      }
-      waitQueue = [];
-    });
-  }
-
-  return function() {
-    var passed = false;
-    waitForTick(function() {
-      passed = true;
-    });
-    return function(callback) {
-      passed ? callback() : waitForTick(callback);
-    };
-  };
-}];
-
-var $$AnimateRunnerFactory = ['$q', '$sniffer', '$$animateAsyncRun',
-                      function($q,   $sniffer,   $$animateAsyncRun) {
-
-  var INITIAL_STATE = 0;
-  var DONE_PENDING_STATE = 1;
-  var DONE_COMPLETE_STATE = 2;
-
-  AnimateRunner.chain = function(chain, callback) {
-    var index = 0;
-
-    next();
-    function next() {
-      if (index === chain.length) {
-        callback(true);
-        return;
-      }
-
-      chain[index](function(response) {
-        if (response === false) {
-          callback(false);
-          return;
-        }
-        index++;
-        next();
-      });
-    }
-  };
-
-  AnimateRunner.all = function(runners, callback) {
-    var count = 0;
-    var status = true;
-    forEach(runners, function(runner) {
-      runner.done(onProgress);
-    });
-
-    function onProgress(response) {
-      status = status && response;
-      if (++count === runners.length) {
-        callback(status);
-      }
-    }
-  };
-
-  function AnimateRunner(host) {
-    this.setHost(host);
-
-    this._doneCallbacks = [];
-    this._runInAnimationFrame = $$animateAsyncRun();
-    this._state = 0;
-  }
-
-  AnimateRunner.prototype = {
-    setHost: function(host) {
-      this.host = host || {};
-    },
-
-    done: function(fn) {
-      if (this._state === DONE_COMPLETE_STATE) {
-        fn();
-      } else {
-        this._doneCallbacks.push(fn);
-      }
-    },
-
-    progress: noop,
-
-    getPromise: function() {
-      if (!this.promise) {
-        var self = this;
-        this.promise = $q(function(resolve, reject) {
-          self.done(function(status) {
-            status === false ? reject() : resolve();
-          });
-        });
-      }
-      return this.promise;
-    },
-
-    then: function(resolveHandler, rejectHandler) {
-      return this.getPromise().then(resolveHandler, rejectHandler);
-    },
-
-    'catch': function(handler) {
-      return this.getPromise()['catch'](handler);
-    },
-
-    'finally': function(handler) {
-      return this.getPromise()['finally'](handler);
-    },
-
-    pause: function() {
-      if (this.host.pause) {
-        this.host.pause();
-      }
-    },
-
-    resume: function() {
-      if (this.host.resume) {
-        this.host.resume();
-      }
-    },
-
-    end: function() {
-      if (this.host.end) {
-        this.host.end();
-      }
-      this._resolve(true);
-    },
-
-    cancel: function() {
-      if (this.host.cancel) {
-        this.host.cancel();
-      }
-      this._resolve(false);
-    },
-
-    complete: function(response) {
-      var self = this;
-      if (self._state === INITIAL_STATE) {
-        self._state = DONE_PENDING_STATE;
-        self._runInAnimationFrame(function() {
-          self._resolve(response);
-        });
-      }
-    },
-
-    _resolve: function(response) {
-      if (this._state !== DONE_COMPLETE_STATE) {
-        forEach(this._doneCallbacks, function(fn) {
-          fn(response);
-        });
-        this._doneCallbacks.length = 0;
-        this._state = DONE_COMPLETE_STATE;
-      }
-    }
-  };
-
-  return AnimateRunner;
-}];
-
-var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
-  var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';
-
-  var drivers = this.drivers = [];
-
-  var RUNNER_STORAGE_KEY = '$$animationRunner';
-
-  function setRunner(element, runner) {
-    element.data(RUNNER_STORAGE_KEY, runner);
-  }
-
-  function removeRunner(element) {
-    element.removeData(RUNNER_STORAGE_KEY);
-  }
-
-  function getRunner(element) {
-    return element.data(RUNNER_STORAGE_KEY);
-  }
-
-  this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$HashMap', '$$rAFScheduler',
-       function($$jqLite,   $rootScope,   $injector,   $$AnimateRunner,   $$HashMap,   $$rAFScheduler) {
-
-    var animationQueue = [];
-    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
-
-    function sortAnimations(animations) {
-      var tree = { children: [] };
-      var i, lookup = new $$HashMap();
-
-      // this is done first beforehand so that the hashmap
-      // is filled with a list of the elements that will be animated
-      for (i = 0; i < animations.length; i++) {
-        var animation = animations[i];
-        lookup.put(animation.domNode, animations[i] = {
-          domNode: animation.domNode,
-          fn: animation.fn,
-          children: []
-        });
-      }
-
-      for (i = 0; i < animations.length; i++) {
-        processNode(animations[i]);
-      }
-
-      return flatten(tree);
-
-      function processNode(entry) {
-        if (entry.processed) return entry;
-        entry.processed = true;
-
-        var elementNode = entry.domNode;
-        var parentNode = elementNode.parentNode;
-        lookup.put(elementNode, entry);
-
-        var parentEntry;
-        while (parentNode) {
-          parentEntry = lookup.get(parentNode);
-          if (parentEntry) {
-            if (!parentEntry.processed) {
-              parentEntry = processNode(parentEntry);
-            }
-            break;
-          }
-          parentNode = parentNode.parentNode;
-        }
-
-        (parentEntry || tree).children.push(entry);
-        return entry;
-      }
-
-      function flatten(tree) {
-        var result = [];
-        var queue = [];
-        var i;
-
-        for (i = 0; i < tree.children.length; i++) {
-          queue.push(tree.children[i]);
-        }
-
-        var remainingLevelEntries = queue.length;
-        var nextLevelEntries = 0;
-        var row = [];
-
-        for (i = 0; i < queue.length; i++) {
-          var entry = queue[i];
-          if (remainingLevelEntries <= 0) {
-            remainingLevelEntries = nextLevelEntries;
-            nextLevelEntries = 0;
-            result.push(row);
-            row = [];
-          }
-          row.push(entry.fn);
-          entry.children.forEach(function(childEntry) {
-            nextLevelEntries++;
-            queue.push(childEntry);
-          });
-          remainingLevelEntries--;
-        }
-
-        if (row.length) {
-          result.push(row);
-        }
-
-        return result;
-      }
-    }
-
-    // TODO(matsko): document the signature in a better way
-    return function(element, event, options) {
-      options = prepareAnimationOptions(options);
-      var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
-
-      // there is no animation at the current moment, however
-      // these runner methods will get later updated with the
-      // methods leading into the driver's end/cancel methods
-      // for now they just stop the animation from starting
-      var runner = new $$AnimateRunner({
-        end: function() { close(); },
-        cancel: function() { close(true); }
-      });
-
-      if (!drivers.length) {
-        close();
-        return runner;
-      }
-
-      setRunner(element, runner);
-
-      var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass));
-      var tempClasses = options.tempClasses;
-      if (tempClasses) {
-        classes += ' ' + tempClasses;
-        options.tempClasses = null;
-      }
-
-      animationQueue.push({
-        // this data is used by the postDigest code and passed into
-        // the driver step function
-        element: element,
-        classes: classes,
-        event: event,
-        structural: isStructural,
-        options: options,
-        beforeStart: beforeStart,
-        close: close
-      });
-
-      element.on('$destroy', handleDestroyedElement);
-
-      // we only want there to be one function called within the post digest
-      // block. This way we can group animations for all the animations that
-      // were apart of the same postDigest flush call.
-      if (animationQueue.length > 1) return runner;
-
-      $rootScope.$$postDigest(function() {
-        var animations = [];
-        forEach(animationQueue, function(entry) {
-          // the element was destroyed early on which removed the runner
-          // form its storage. This means we can't animate this element
-          // at all and it already has been closed due to destruction.
-          if (getRunner(entry.element)) {
-            animations.push(entry);
-          } else {
-            entry.close();
-          }
-        });
-
-        // now any future animations will be in another postDigest
-        animationQueue.length = 0;
-
-        var groupedAnimations = groupAnimations(animations);
-        var toBeSortedAnimations = [];
-
-        forEach(groupedAnimations, function(animationEntry) {
-          toBeSortedAnimations.push({
-            domNode: getDomNode(animationEntry.from ? animationEntry.from.element : animationEntry.element),
-            fn: function triggerAnimationStart() {
-              // it's important that we apply the `ng-animate` CSS class and the
-              // temporary classes before we do any driver invoking since these
-              // CSS classes may be required for proper CSS detection.
-              animationEntry.beforeStart();
-
-              var startAnimationFn, closeFn = animationEntry.close;
-
-              // in the event that the element was removed before the digest runs or
-              // during the RAF sequencing then we should not trigger the animation.
-              var targetElement = animationEntry.anchors
-                  ? (animationEntry.from.element || animationEntry.to.element)
-                  : animationEntry.element;
-
-              if (getRunner(targetElement)) {
-                var operation = invokeFirstDriver(animationEntry);
-                if (operation) {
-                  startAnimationFn = operation.start;
-                }
-              }
-
-              if (!startAnimationFn) {
-                closeFn();
-              } else {
-                var animationRunner = startAnimationFn();
-                animationRunner.done(function(status) {
-                  closeFn(!status);
-                });
-                updateAnimationRunners(animationEntry, animationRunner);
-              }
-            }
-          });
-        });
-
-        // we need to sort each of the animations in order of parent to child
-        // relationships. This ensures that the child classes are applied at the
-        // right time.
-        $$rAFScheduler(sortAnimations(toBeSortedAnimations));
-      });
-
-      return runner;
-
-      // TODO(matsko): change to reference nodes
-      function getAnchorNodes(node) {
-        var SELECTOR = '[' + NG_ANIMATE_REF_ATTR + ']';
-        var items = node.hasAttribute(NG_ANIMATE_REF_ATTR)
-              ? [node]
-              : node.querySelectorAll(SELECTOR);
-        var anchors = [];
-        forEach(items, function(node) {
-          var attr = node.getAttribute(NG_ANIMATE_REF_ATTR);
-          if (attr && attr.length) {
-            anchors.push(node);
-          }
-        });
-        return anchors;
-      }
-
-      function groupAnimations(animations) {
-        var preparedAnimations = [];
-        var refLookup = {};
-        forEach(animations, function(animation, index) {
-          var element = animation.element;
-          var node = getDomNode(element);
-          var event = animation.event;
-          var enterOrMove = ['enter', 'move'].indexOf(event) >= 0;
-          var anchorNodes = animation.structural ? getAnchorNodes(node) : [];
-
-          if (anchorNodes.length) {
-            var direction = enterOrMove ? 'to' : 'from';
-
-            forEach(anchorNodes, function(anchor) {
-              var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR);
-              refLookup[key] = refLookup[key] || {};
-              refLookup[key][direction] = {
-                animationID: index,
-                element: jqLite(anchor)
-              };
-            });
-          } else {
-            preparedAnimations.push(animation);
-          }
-        });
-
-        var usedIndicesLookup = {};
-        var anchorGroups = {};
-        forEach(refLookup, function(operations, key) {
-          var from = operations.from;
-          var to = operations.to;
-
-          if (!from || !to) {
-            // only one of these is set therefore we can't have an
-            // anchor animation since all three pieces are required
-            var index = from ? from.animationID : to.animationID;
-            var indexKey = index.toString();
-            if (!usedIndicesLookup[indexKey]) {
-              usedIndicesLookup[indexKey] = true;
-              preparedAnimations.push(animations[index]);
-            }
-            return;
-          }
-
-          var fromAnimation = animations[from.animationID];
-          var toAnimation = animations[to.animationID];
-          var lookupKey = from.animationID.toString();
-          if (!anchorGroups[lookupKey]) {
-            var group = anchorGroups[lookupKey] = {
-              structural: true,
-              beforeStart: function() {
-                fromAnimation.beforeStart();
-                toAnimation.beforeStart();
-              },
-              close: function() {
-                fromAnimation.close();
-                toAnimation.close();
-              },
-              classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes),
-              from: fromAnimation,
-              to: toAnimation,
-              anchors: [] // TODO(matsko): change to reference nodes
-            };
-
-            // the anchor animations require that the from and to elements both have at least
-            // one shared CSS class which effictively marries the two elements together to use
-            // the same animation driver and to properly sequence the anchor animation.
-            if (group.classes.length) {
-              preparedAnimations.push(group);
-            } else {
-              preparedAnimations.push(fromAnimation);
-              preparedAnimations.push(toAnimation);
-            }
-          }
-
-          anchorGroups[lookupKey].anchors.push({
-            'out': from.element, 'in': to.element
-          });
-        });
-
-        return preparedAnimations;
-      }
-
-      function cssClassesIntersection(a,b) {
-        a = a.split(' ');
-        b = b.split(' ');
-        var matches = [];
-
-        for (var i = 0; i < a.length; i++) {
-          var aa = a[i];
-          if (aa.substring(0,3) === 'ng-') continue;
-
-          for (var j = 0; j < b.length; j++) {
-            if (aa === b[j]) {
-              matches.push(aa);
-              break;
-            }
-          }
-        }
-
-        return matches.join(' ');
-      }
-
-      function invokeFirstDriver(animationDetails) {
-        // we loop in reverse order since the more general drivers (like CSS and JS)
-        // may attempt more elements, but custom drivers are more particular
-        for (var i = drivers.length - 1; i >= 0; i--) {
-          var driverName = drivers[i];
-          if (!$injector.has(driverName)) continue; // TODO(matsko): remove this check
-
-          var factory = $injector.get(driverName);
-          var driver = factory(animationDetails);
-          if (driver) {
-            return driver;
-          }
-        }
-      }
-
-      function beforeStart() {
-        element.addClass(NG_ANIMATE_CLASSNAME);
-        if (tempClasses) {
-          $$jqLite.addClass(element, tempClasses);
-        }
-      }
-
-      function updateAnimationRunners(animation, newRunner) {
-        if (animation.from && animation.to) {
-          update(animation.from.element);
-          update(animation.to.element);
-        } else {
-          update(animation.element);
-        }
-
-        function update(element) {
-          getRunner(element).setHost(newRunner);
-        }
-      }
-
-      function handleDestroyedElement() {
-        var runner = getRunner(element);
-        if (runner && (event !== 'leave' || !options.$$domOperationFired)) {
-          runner.end();
-        }
-      }
-
-      function close(rejected) { // jshint ignore:line
-        element.off('$destroy', handleDestroyedElement);
-        removeRunner(element);
-
-        applyAnimationClasses(element, options);
-        applyAnimationStyles(element, options);
-        options.domOperation();
-
-        if (tempClasses) {
-          $$jqLite.removeClass(element, tempClasses);
-        }
-
-        element.removeClass(NG_ANIMATE_CLASSNAME);
-        runner.complete(!rejected);
-      }
-    };
-  }];
-}];
-
-/* global angularAnimateModule: true,
-
-   $$AnimateAsyncRunFactory,
-   $$rAFSchedulerFactory,
-   $$AnimateChildrenDirective,
-   $$AnimateRunnerFactory,
-   $$AnimateQueueProvider,
-   $$AnimationProvider,
-   $AnimateCssProvider,
-   $$AnimateCssDriverProvider,
-   $$AnimateJsProvider,
-   $$AnimateJsDriverProvider,
-*/
-
-/**
- * @ngdoc module
- * @name ngAnimate
- * @description
- *
- * The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via
- * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an Angular app.
- *
- * <div doc-module-components="ngAnimate"></div>
- *
- * # Usage
- * 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
- * using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via `module.animation()`. For
- * both CSS and JS animations the sole requirement is to have a matching `CSS class` that exists both in the registered animation and within
- * the HTML element that the animation will be triggered on.
- *
- * ## Directive Support
- * The following directives are "animation aware":
- *
- * | Directive                                                                                                | Supported Animations                                                     |
- * |----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
- * | {@link ng.directive:ngRepeat#animations ngRepeat}                                                        | enter, leave and move                                                    |
- * | {@link ngRoute.directive:ngView#animations ngView}                                                       | enter and leave                                                          |
- * | {@link ng.directive:ngInclude#animations ngInclude}                                                      | enter and leave                                                          |
- * | {@link ng.directive:ngSwitch#animations ngSwitch}                                                        | enter and leave                                                          |
- * | {@link ng.directive:ngIf#animations ngIf}                                                                | enter and leave                                                          |
- * | {@link ng.directive:ngClass#animations ngClass}                                                          | add and remove (the CSS class(es) present)                               |
- * | {@link ng.directive:ngShow#animations ngShow} & {@link ng.directive:ngHide#animations ngHide}            | add and remove (the ng-hide class value)                                 |
- * | {@link ng.directive:form#animation-hooks form} & {@link ng.directive:ngModel#animation-hooks ngModel}    | add and remove (dirty, pristine, valid, invalid & all other validations) |
- * | {@link module:ngMessages#animations ngMessages}                                                          | add and remove (ng-active & ng-inactive)                                 |
- * | {@link module:ngMessages#animations ngMessage}                                                           | enter and leave                                                          |
- *
- * (More information can be found by visiting each the documentation associated with each directive.)
- *
- * ## CSS-based Animations
- *
- * 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
- * and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation.
- *
- * The example below shows how an `enter` animation can be made possible on an element using `ng-if`:
- *
- * ```html
- * <div ng-if="bool" class="fade">
- *    Fade me in out
- * </div>
- * <button ng-click="bool=true">Fade In!</button>
- * <button ng-click="bool=false">Fade Out!</button>
- * ```
- *
- * Notice the CSS class **fade**? We can now create the CSS transition code that references this class:
- *
- * ```css
- * /&#42; The starting CSS styles for the enter animation &#42;/
- * .fade.ng-enter {
- *   transition:0.5s linear all;
- *   opacity:0;
- * }
- *
- * /&#42; The finishing CSS styles for the enter animation &#42;/
- * .fade.ng-enter.ng-enter-active {
- *   opacity:1;
- * }
- * ```
- *
- * 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
- * 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
- * code **must** be defined within the starting CSS class (in this case `.ng-enter`). The destination class is what the transition will animate towards.
- *
- * 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:
- *
- * ```css
- * /&#42; now the element will fade out before it is removed from the DOM &#42;/
- * .fade.ng-leave {
- *   transition:0.5s linear all;
- *   opacity:1;
- * }
- * .fade.ng-leave.ng-leave-active {
- *   opacity:0;
- * }
- * ```
- *
- * We can also make use of **CSS Keyframes** by referencing the keyframe animation within the starting CSS class:
- *
- * ```css
- * /&#42; there is no need to define anything inside of the destination
- * CSS class since the keyframe will take charge of the animation &#42;/
- * .fade.ng-leave {
- *   animation: my_fade_animation 0.5s linear;
- *   -webkit-animation: my_fade_animation 0.5s linear;
- * }
- *
- * @keyframes my_fade_animation {
- *   from { opacity:1; }
- *   to { opacity:0; }
- * }
- *
- * @-webkit-keyframes my_fade_animation {
- *   from { opacity:1; }
- *   to { opacity:0; }
- * }
- * ```
- *
- * Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element.
- *
- * ### CSS Class-based Animations
- *
- * Class-based animations (animations that are triggered via `ngClass`, `ngShow`, `ngHide` and some other directives) have a slightly different
- * naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added
- * and removed.
- *
- * For example if we wanted to do a CSS animation for `ngHide` then we place an animation on the `.ng-hide` CSS class:
- *
- * ```html
- * <div ng-show="bool" class="fade">
- *   Show and hide me
- * </div>
- * <button ng-click="bool=true">Toggle</button>
- *
- * <style>
- * .fade.ng-hide {
- *   transition:0.5s linear all;
- *   opacity:0;
- * }
- * </style>
- * ```
- *
- * 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
- * ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest.
- *
- * 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
- * with CSS styles.
- *
- * ```html
- * <div ng-class="{on:onOff}" class="highlight">
- *   Highlight this box
- * </div>
- * <button ng-click="onOff=!onOff">Toggle</button>
- *
- * <style>
- * .highlight {
- *   transition:0.5s linear all;
- * }
- * .highlight.on-add {
- *   background:white;
- * }
- * .highlight.on {
- *   background:yellow;
- * }
- * .highlight.on-remove {
- *   background:black;
- * }
- * </style>
- * ```
- *
- * We can also make use of CSS keyframes by placing them within the CSS classes.
- *
- *
- * ### CSS Staggering Animations
- * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a
- * curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be
- * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for
- * the animation. The style property expected within the stagger class can either be a **transition-delay** or an
- * **animation-delay** property (or both if your animation contains both transitions and keyframe animations).
- *
- * ```css
- * .my-animation.ng-enter {
- *   /&#42; standard transition code &#42;/
- *   transition: 1s linear all;
- *   opacity:0;
- * }
- * .my-animation.ng-enter-stagger {
- *   /&#42; this will have a 100ms delay between each successive leave animation &#42;/
- *   transition-delay: 0.1s;
- *
- *   /&#42; As of 1.4.4, this must always be set: it signals ngAnimate
- *     to not accidentally inherit a delay property from another CSS class &#42;/
- *   transition-duration: 0s;
- * }
- * .my-animation.ng-enter.ng-enter-active {
- *   /&#42; standard transition styles &#42;/
- *   opacity:1;
- * }
- * ```
- *
- * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations
- * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this
- * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation
- * will also be reset if one or more animation frames have passed since the multiple calls to `$animate` were fired.
- *
- * The following code will issue the **ng-leave-stagger** event on the element provided:
- *
- * ```js
- * var kids = parent.children();
- *
- * $animate.leave(kids[0]); //stagger index=0
- * $animate.leave(kids[1]); //stagger index=1
- * $animate.leave(kids[2]); //stagger index=2
- * $animate.leave(kids[3]); //stagger index=3
- * $animate.leave(kids[4]); //stagger index=4
- *
- * window.requestAnimationFrame(function() {
- *   //stagger has reset itself
- *   $animate.leave(kids[5]); //stagger index=0
- *   $animate.leave(kids[6]); //stagger index=1
- *
- *   $scope.$digest();
- * });
- * ```
- *
- * Stagger animations are currently only supported within CSS-defined animations.
- *
- * ### The `ng-animate` CSS class
- *
- * When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation.
- * This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations).
- *
- * Therefore, animations can be applied to an element using this temporary class directly via CSS.
- *
- * ```css
- * .zipper.ng-animate {
- *   transition:0.5s linear all;
- * }
- * .zipper.ng-enter {
- *   opacity:0;
- * }
- * .zipper.ng-enter.ng-enter-active {
- *   opacity:1;
- * }
- * .zipper.ng-leave {
- *   opacity:1;
- * }
- * .zipper.ng-leave.ng-leave-active {
- *   opacity:0;
- * }
- * ```
- *
- * (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove
- * the CSS class once an animation has completed.)
- *
- *
- * ## JavaScript-based Animations
- *
- * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared
- * 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
- * `module.animation()` module function we can register the ainmation.
- *
- * Let's see an example of a enter/leave animation using `ngRepeat`:
- *
- * ```html
- * <div ng-repeat="item in items" class="slide">
- *   {{ item }}
- * </div>
- * ```
- *
- * 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`:
- *
- * ```js
- * myModule.animation('.slide', [function() {
- *   return {
- *     // make note that other events (like addClass/removeClass)
- *     // have different function input parameters
- *     enter: function(element, doneFn) {
- *       jQuery(element).fadeIn(1000, doneFn);
- *
- *       // remember to call doneFn so that angular
- *       // knows that the animation has concluded
- *     },
- *
- *     move: function(element, doneFn) {
- *       jQuery(element).fadeIn(1000, doneFn);
- *     },
- *
- *     leave: function(element, doneFn) {
- *       jQuery(element).fadeOut(1000, doneFn);
- *     }
- *   }
- * }]
- * ```
- *
- * The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as
- * greensock.js and velocity.js.
- *
- * If our animation code class-based (meaning that something like `ngClass`, `ngHide` and `ngShow` triggers it) then we can still define
- * our animations inside of the same registered animation, however, the function input arguments are a bit different:
- *
- * ```html
- * <div ng-class="color" class="colorful">
- *   this box is moody
- * </div>
- * <button ng-click="color='red'">Change to red</button>
- * <button ng-click="color='blue'">Change to blue</button>
- * <button ng-click="color='green'">Change to green</button>
- * ```
- *
- * ```js
- * myModule.animation('.colorful', [function() {
- *   return {
- *     addClass: function(element, className, doneFn) {
- *       // do some cool animation and call the doneFn
- *     },
- *     removeClass: function(element, className, doneFn) {
- *       // do some cool animation and call the doneFn
- *     },
- *     setClass: function(element, addedClass, removedClass, doneFn) {
- *       // do some cool animation and call the doneFn
- *     }
- *   }
- * }]
- * ```
- *
- * ## CSS + JS Animations Together
- *
- * AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of Angular,
- * 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
- * charge of the animation**:
- *
- * ```html
- * <div ng-if="bool" class="slide">
- *   Slide in and out
- * </div>
- * ```
- *
- * ```js
- * myModule.animation('.slide', [function() {
- *   return {
- *     enter: function(element, doneFn) {
- *       jQuery(element).slideIn(1000, doneFn);
- *     }
- *   }
- * }]
- * ```
- *
- * ```css
- * .slide.ng-enter {
- *   transition:0.5s linear all;
- *   transform:translateY(-100px);
- * }
- * .slide.ng-enter.ng-enter-active {
- *   transform:translateY(0);
- * }
- * ```
- *
- * 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
- * lack of CSS animations by using the `$animateCss` service to trigger our own tweaked-out, CSS-based animations directly from
- * our own JS-based animation code:
- *
- * ```js
- * myModule.animation('.slide', ['$animateCss', function($animateCss) {
- *   return {
- *     enter: function(element, doneFn) {
-*        // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.
- *       var runner = $animateCss(element, {
- *         event: 'enter',
- *         structural: true
- *       }).start();
-*        runner.done(doneFn);
- *     }
- *   }
- * }]
- * ```
- *
- * 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.
- *
- * 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
- * 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
- * data into `$animateCss` directly:
- *
- * ```js
- * myModule.animation('.slide', ['$animateCss', function($animateCss) {
- *   return {
- *     enter: function(element, doneFn) {
- *       var runner = $animateCss(element, {
- *         event: 'enter',
- *         structural: true,
- *         addClass: 'maroon-setting',
- *         from: { height:0 },
- *         to: { height: 200 }
- *       }).start();
- *
- *       runner.done(doneFn);
- *     }
- *   }
- * }]
- * ```
- *
- * Now we can fill in the rest via our transition CSS code:
- *
- * ```css
- * /&#42; the transition tells ngAnimate to make the animation happen &#42;/
- * .slide.ng-enter { transition:0.5s linear all; }
- *
- * /&#42; this extra CSS class will be absorbed into the transition
- * since the $animateCss code is adding the class &#42;/
- * .maroon-setting { background:red; }
- * ```
- *
- * 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.
- *
- * To learn more about what's possible be sure to visit the {@link ngAnimate.$animateCss $animateCss service}.
- *
- * ## Animation Anchoring (via `ng-animate-ref`)
- *
- * ngAnimate in AngularJS 1.4 comes packed with the ability to cross-animate elements between
- * structural areas of an application (like views) by pairing up elements using an attribute
- * called `ng-animate-ref`.
- *
- * Let's say for example we have two views that are managed by `ng-view` and we want to show
- * that there is a relationship between two components situated in within these views. By using the
- * `ng-animate-ref` attribute we can identify that the two components are paired together and we
- * can then attach an animation, which is triggered when the view changes.
- *
- * Say for example we have the following template code:
- *
- * ```html
- * <!-- index.html -->
- * <div ng-view class="view-animation">
- * </div>
- *
- * <!-- home.html -->
- * <a href="#/banner-page">
- *   <img src="./banner.jpg" class="banner" ng-animate-ref="banner">
- * </a>
- *
- * <!-- banner-page.html -->
- * <img src="./banner.jpg" class="banner" ng-animate-ref="banner">
- * ```
- *
- * Now, when the view changes (once the link is clicked), ngAnimate will examine the
- * HTML contents to see if there is a match reference between any components in the view
- * that is leaving and the view that is entering. It will scan both the view which is being
- * removed (leave) and inserted (enter) to see if there are any paired DOM elements that
- * contain a matching ref value.
- *
- * The two images match since they share the same ref value. ngAnimate will now create a
- * transport element (which is a clone of the first image element) and it will then attempt
- * to animate to the position of the second image element in the next view. For the animation to
- * work a special CSS class called `ng-anchor` will be added to the transported element.
- *
- * We can now attach a transition onto the `.banner.ng-anchor` CSS class and then
- * ngAnimate will handle the entire transition for us as well as the addition and removal of
- * any changes of CSS classes between the elements:
- *
- * ```css
- * .banner.ng-anchor {
- *   /&#42; this animation will last for 1 second since there are
- *          two phases to the animation (an `in` and an `out` phase) &#42;/
- *   transition:0.5s linear all;
- * }
- * ```
- *
- * We also **must** include animations for the views that are being entered and removed
- * (otherwise anchoring wouldn't be possible since the new view would be inserted right away).
- *
- * ```css
- * .view-animation.ng-enter, .view-animation.ng-leave {
- *   transition:0.5s linear all;
- *   position:fixed;
- *   left:0;
- *   top:0;
- *   width:100%;
- * }
- * .view-animation.ng-enter {
- *   transform:translateX(100%);
- * }
- * .view-animation.ng-leave,
- * .view-animation.ng-enter.ng-enter-active {
- *   transform:translateX(0%);
- * }
- * .view-animation.ng-leave.ng-leave-active {
- *   transform:translateX(-100%);
- * }
- * ```
- *
- * Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur:
- * an `out` and an `in` stage. The `out` stage happens first and that is when the element is animated away
- * from its origin. Once that animation is over then the `in` stage occurs which animates the
- * element to its destination. The reason why there are two animations is to give enough time
- * for the enter animation on the new element to be ready.
- *
- * The example above sets up a transition for both the in and out phases, but we can also target the out or
- * in phases directly via `ng-anchor-out` and `ng-anchor-in`.
- *
- * ```css
- * .banner.ng-anchor-out {
- *   transition: 0.5s linear all;
- *
- *   /&#42; the scale will be applied during the out animation,
- *          but will be animated away when the in animation runs &#42;/
- *   transform: scale(1.2);
- * }
- *
- * .banner.ng-anchor-in {
- *   transition: 1s linear all;
- * }
- * ```
- *
- *
- *
- *
- * ### Anchoring Demo
- *
-  <example module="anchoringExample"
-           name="anchoringExample"
-           id="anchoringExample"
-           deps="angular-animate.js;angular-route.js"
-           animations="true">
-    <file name="index.html">
-      <a href="#/">Home</a>
-      <hr />
-      <div class="view-container">
-        <div ng-view class="view"></div>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('anchoringExample', ['ngAnimate', 'ngRoute'])
-        .config(['$routeProvider', function($routeProvider) {
-          $routeProvider.when('/', {
-            templateUrl: 'home.html',
-            controller: 'HomeController as home'
-          });
-          $routeProvider.when('/profile/:id', {
-            templateUrl: 'profile.html',
-            controller: 'ProfileController as profile'
-          });
-        }])
-        .run(['$rootScope', function($rootScope) {
-          $rootScope.records = [
-            { id:1, title: "Miss Beulah Roob" },
-            { id:2, title: "Trent Morissette" },
-            { id:3, title: "Miss Ava Pouros" },
-            { id:4, title: "Rod Pouros" },
-            { id:5, title: "Abdul Rice" },
-            { id:6, title: "Laurie Rutherford Sr." },
-            { id:7, title: "Nakia McLaughlin" },
-            { id:8, title: "Jordon Blanda DVM" },
-            { id:9, title: "Rhoda Hand" },
-            { id:10, title: "Alexandrea Sauer" }
-          ];
-        }])
-        .controller('HomeController', [function() {
-          //empty
-        }])
-        .controller('ProfileController', ['$rootScope', '$routeParams', function($rootScope, $routeParams) {
-          var index = parseInt($routeParams.id, 10);
-          var record = $rootScope.records[index - 1];
-
-          this.title = record.title;
-          this.id = record.id;
-        }]);
-    </file>
-    <file name="home.html">
-      <h2>Welcome to the home page</h1>
-      <p>Please click on an element</p>
-      <a class="record"
-         ng-href="#/profile/{{ record.id }}"
-         ng-animate-ref="{{ record.id }}"
-         ng-repeat="record in records">
-        {{ record.title }}
-      </a>
-    </file>
-    <file name="profile.html">
-      <div class="profile record" ng-animate-ref="{{ profile.id }}">
-        {{ profile.title }}
-      </div>
-    </file>
-    <file name="animations.css">
-      .record {
-        display:block;
-        font-size:20px;
-      }
-      .profile {
-        background:black;
-        color:white;
-        font-size:100px;
-      }
-      .view-container {
-        position:relative;
-      }
-      .view-container > .view.ng-animate {
-        position:absolute;
-        top:0;
-        left:0;
-        width:100%;
-        min-height:500px;
-      }
-      .view.ng-enter, .view.ng-leave,
-      .record.ng-anchor {
-        transition:0.5s linear all;
-      }
-      .view.ng-enter {
-        transform:translateX(100%);
-      }
-      .view.ng-enter.ng-enter-active, .view.ng-leave {
-        transform:translateX(0%);
-      }
-      .view.ng-leave.ng-leave-active {
-        transform:translateX(-100%);
-      }
-      .record.ng-anchor-out {
-        background:red;
-      }
-    </file>
-  </example>
- *
- * ### How is the element transported?
- *
- * When an anchor animation occurs, ngAnimate will clone the starting element and position it exactly where the starting
- * element is located on screen via absolute positioning. The cloned element will be placed inside of the root element
- * of the application (where ng-app was defined) and all of the CSS classes of the starting element will be applied. The
- * element will then animate into the `out` and `in` animations and will eventually reach the coordinates and match
- * the dimensions of the destination element. During the entire animation a CSS class of `.ng-animate-shim` will be applied
- * to both the starting and destination elements in order to hide them from being visible (the CSS styling for the class
- * is: `visibility:hidden`). Once the anchor reaches its destination then it will be removed and the destination element
- * will become visible since the shim class will be removed.
- *
- * ### How is the morphing handled?
- *
- * CSS Anchoring relies on transitions and keyframes and the internal code is intelligent enough to figure out
- * what CSS classes differ between the starting element and the destination element. These different CSS classes
- * will be added/removed on the anchor element and a transition will be applied (the transition that is provided
- * in the anchor class). Long story short, ngAnimate will figure out what classes to add and remove which will
- * make the transition of the element as smooth and automatic as possible. Be sure to use simple CSS classes that
- * do not rely on DOM nesting structure so that the anchor element appears the same as the starting element (since
- * the cloned element is placed inside of root element which is likely close to the body element).
- *
- * Note that if the root element is on the `<html>` element then the cloned node will be placed inside of body.
- *
- *
- * ## Using $animate in your directive code
- *
- * So far we've explored how to feed in animations into an Angular application, but how do we trigger animations within our own directives in our application?
- * 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
- * imagine we have a greeting box that shows and hides itself when the data changes
- *
- * ```html
- * <greeting-box active="onOrOff">Hi there</greeting-box>
- * ```
- *
- * ```js
- * ngModule.directive('greetingBox', ['$animate', function($animate) {
- *   return function(scope, element, attrs) {
- *     attrs.$observe('active', function(value) {
- *       value ? $animate.addClass(element, 'on') : $animate.removeClass(element, 'on');
- *     });
- *   });
- * }]);
- * ```
- *
- * 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
- * in our HTML code then we can trigger a CSS or JS animation to happen.
- *
- * ```css
- * /&#42; normally we would create a CSS class to reference on the element &#42;/
- * greeting-box.on { transition:0.5s linear all; background:green; color:white; }
- * ```
- *
- * The `$animate` service contains a variety of other methods like `enter`, `leave`, `animate` and `setClass`. To learn more about what's
- * possible be sure to visit the {@link ng.$animate $animate service API page}.
- *
- *
- * ### Preventing Collisions With Third Party Libraries
- *
- * Some third-party frameworks place animation duration defaults across many element or className
- * selectors in order to make their code small and reuseable. This can lead to issues with ngAnimate, which
- * is expecting actual animations on these elements and has to wait for their completion.
- *
- * You can prevent this unwanted behavior by using a prefix on all your animation classes:
- *
- * ```css
- * /&#42; prefixed with animate- &#42;/
- * .animate-fade-add.animate-fade-add-active {
- *   transition:1s linear all;
- *   opacity:0;
- * }
- * ```
- *
- * You then configure `$animate` to enforce this prefix:
- *
- * ```js
- * $animateProvider.classNameFilter(/animate-/);
- * ```
- *
- * This also may provide your application with a speed boost since only specific elements containing CSS class prefix
- * will be evaluated for animation when any DOM changes occur in the application.
- *
- * ## Callbacks and Promises
- *
- * 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
- * an animation (within our directive code) then we can continue performing directive and scope related activities after the animation has
- * ended by chaining onto the returned promise that animation method returns.
- *
- * ```js
- * // somewhere within the depths of the directive
- * $animate.enter(element, parent).then(function() {
- *   //the animation has completed
- * });
- * ```
- *
- * (Note that earlier versions of Angular prior to v1.4 required the promise code to be wrapped using `$scope.$apply(...)`. This is not the case
- * anymore.)
- *
- * In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering
- * an event listener using the `$animate` service. Let's say for example that an animation was triggered on our view
- * routing controller to hook into that:
- *
- * ```js
- * ngModule.controller('HomePageController', ['$animate', function($animate) {
- *   $animate.on('enter', ngViewElement, function(element) {
- *     // the animation for this route has completed
- *   }]);
- * }])
- * ```
- *
- * (Note that you will need to trigger a digest within the callback to get angular to notice any scope-related changes.)
- */
-
-/**
- * @ngdoc service
- * @name $animate
- * @kind object
- *
- * @description
- * The ngAnimate `$animate` service documentation is the same for the core `$animate` service.
- *
- * Click here {@link ng.$animate to learn more about animations with `$animate`}.
- */
-angular.module('ngAnimate', [])
-  .directive('ngAnimateChildren', $$AnimateChildrenDirective)
-  .factory('$$rAFScheduler', $$rAFSchedulerFactory)
-
-  .factory('$$AnimateRunner', $$AnimateRunnerFactory)
-  .factory('$$animateAsyncRun', $$AnimateAsyncRunFactory)
-
-  .provider('$$animateQueue', $$AnimateQueueProvider)
-  .provider('$$animation', $$AnimationProvider)
-
-  .provider('$animateCss', $AnimateCssProvider)
-  .provider('$$animateCssDriver', $$AnimateCssDriverProvider)
-
-  .provider('$$animateJs', $$AnimateJsProvider)
-  .provider('$$animateJsDriver', $$AnimateJsDriverProvider);
-
-
-})(window, window.angular);
-
-angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
-
-.constant('uibAccordionConfig', {
-  closeOthers: true
-})
-
-.controller('UibAccordionController', ['$scope', '$attrs', 'uibAccordionConfig', function($scope, $attrs, accordionConfig) {
-  // This array keeps track of the accordion groups
-  this.groups = [];
-
-  // Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
-  this.closeOthers = function(openGroup) {
-    var closeOthers = angular.isDefined($attrs.closeOthers) ?
-      $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
-    if (closeOthers) {
-      angular.forEach(this.groups, function(group) {
-        if (group !== openGroup) {
-          group.isOpen = false;
-        }
-      });
-    }
-  };
-
-  // This is called from the accordion-group directive to add itself to the accordion
-  this.addGroup = function(groupScope) {
-    var that = this;
-    this.groups.push(groupScope);
-
-    groupScope.$on('$destroy', function(event) {
-      that.removeGroup(groupScope);
-    });
-  };
-
-  // This is called from the accordion-group directive when to remove itself
-  this.removeGroup = function(group) {
-    var index = this.groups.indexOf(group);
-    if (index !== -1) {
-      this.groups.splice(index, 1);
-    }
-  };
-
-}])
-
-// The accordion directive simply sets up the directive controller
-// and adds an accordion CSS class to itself element.
-.directive('uibAccordion', function() {
-  return {
-    controller: 'UibAccordionController',
-    controllerAs: 'accordion',
-    transclude: true,
-    templateUrl: function(element, attrs) {
-      return attrs.templateUrl || 'template/accordion/accordion.html';
-    }
-  };
-})
-
-// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
-.directive('uibAccordionGroup', function() {
-  return {
-    require: '^uibAccordion',         // We need this directive to be inside an accordion
-    transclude: true,              // It transcludes the contents of the directive into the template
-    replace: true,                // The element containing the directive will be replaced with the template
-    templateUrl: function(element, attrs) {
-      return attrs.templateUrl || 'template/accordion/accordion-group.html';
-    },
-    scope: {
-      heading: '@',               // Interpolate the heading attribute onto this scope
-      isOpen: '=?',
-      isDisabled: '=?'
-    },
-    controller: function() {
-      this.setHeading = function(element) {
-        this.heading = element;
-      };
-    },
-    link: function(scope, element, attrs, accordionCtrl) {
-      accordionCtrl.addGroup(scope);
-
-      scope.openClass = attrs.openClass || 'panel-open';
-      scope.panelClass = attrs.panelClass;
-      scope.$watch('isOpen', function(value) {
-        element.toggleClass(scope.openClass, !!value);
-        if (value) {
-          accordionCtrl.closeOthers(scope);
-        }
-      });
-
-      scope.toggleOpen = function($event) {
-        if (!scope.isDisabled) {
-          if (!$event || $event.which === 32) {
-            scope.isOpen = !scope.isOpen;
-          }
-        }
-      };
-    }
-  };
-})
-
-// Use accordion-heading below an accordion-group to provide a heading containing HTML
-.directive('uibAccordionHeading', function() {
-  return {
-    transclude: true,   // Grab the contents to be used as the heading
-    template: '',       // In effect remove this element!
-    replace: true,
-    require: '^uibAccordionGroup',
-    link: function(scope, element, attrs, accordionGroupCtrl, transclude) {
-      // Pass the heading to the accordion-group controller
-      // so that it can be transcluded into the right place in the template
-      // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
-      accordionGroupCtrl.setHeading(transclude(scope, angular.noop));
-    }
-  };
-})
-
-// Use in the accordion-group template to indicate where you want the heading to be transcluded
-// You must provide the property on the accordion-group controller that will hold the transcluded element
-.directive('uibAccordionTransclude', function() {
-  return {
-    require: ['?^uibAccordionGroup', '?^accordionGroup'],
-    link: function(scope, element, attrs, controller) {
-      controller = controller[0] ? controller[0] : controller[1]; // Delete after we remove deprecation
-      scope.$watch(function() { return controller[attrs.uibAccordionTransclude]; }, function(heading) {
-        if (heading) {
-          element.find('span').html('');
-          element.find('span').append(heading);
-        }
-      });
-    }
-  };
-});
-
-/* Deprecated accordion below */
-
-angular.module('ui.bootstrap.accordion')
-
-  .value('$accordionSuppressWarning', false)
-
-  .controller('AccordionController', ['$scope', '$attrs', '$controller', '$log', '$accordionSuppressWarning', function($scope, $attrs, $controller, $log, $accordionSuppressWarning) {
-    if (!$accordionSuppressWarning) {
-      $log.warn('AccordionController is now deprecated. Use UibAccordionController instead.');
-    }
-
-    angular.extend(this, $controller('UibAccordionController', {
-      $scope: $scope,
-      $attrs: $attrs
-    }));
-  }])
-
-  .directive('accordion', ['$log', '$accordionSuppressWarning', function($log, $accordionSuppressWarning) {
-    return {
-      restrict: 'EA',
-      controller: 'AccordionController',
-      controllerAs: 'accordion',
-      transclude: true,
-      replace: false,
-      templateUrl: function(element, attrs) {
-        return attrs.templateUrl || 'template/accordion/accordion.html';
-      },
-      link: function() {
-        if (!$accordionSuppressWarning) {
-          $log.warn('accordion is now deprecated. Use uib-accordion instead.');
-        }
-      }
-    };
-  }])
-
-  .directive('accordionGroup', ['$log', '$accordionSuppressWarning', function($log, $accordionSuppressWarning) {
-    return {
-      require: '^accordion',         // We need this directive to be inside an accordion
-      restrict: 'EA',
-      transclude: true,              // It transcludes the contents of the directive into the template
-      replace: true,                // The element containing the directive will be replaced with the template
-      templateUrl: function(element, attrs) {
-        return attrs.templateUrl || 'template/accordion/accordion-group.html';
-      },
-      scope: {
-        heading: '@',               // Interpolate the heading attribute onto this scope
-        isOpen: '=?',
-        isDisabled: '=?'
-      },
-      controller: function() {
-        this.setHeading = function(element) {
-          this.heading = element;
-        };
-      },
-      link: function(scope, element, attrs, accordionCtrl) {
-        if (!$accordionSuppressWarning) {
-          $log.warn('accordion-group is now deprecated. Use uib-accordion-group instead.');
-        }
-
-        accordionCtrl.addGroup(scope);
-
-        scope.openClass = attrs.openClass || 'panel-open';
-        scope.panelClass = attrs.panelClass;
-        scope.$watch('isOpen', function(value) {
-          element.toggleClass(scope.openClass, !!value);
-          if (value) {
-            accordionCtrl.closeOthers(scope);
-          }
-        });
-
-        scope.toggleOpen = function($event) {
-          if (!scope.isDisabled) {
-            if (!$event || $event.which === 32) {
-              scope.isOpen = !scope.isOpen;
-            }
-          }
-        };
-      }
-    };
-  }])
-
-  .directive('accordionHeading', ['$log', '$accordionSuppressWarning', function($log, $accordionSuppressWarning) {
-    return {
-      restrict: 'EA',
-      transclude: true,   // Grab the contents to be used as the heading
-      template: '',       // In effect remove this element!
-      replace: true,
-      require: '^accordionGroup',
-      link: function(scope, element, attr, accordionGroupCtrl, transclude) {
-        if (!$accordionSuppressWarning) {
-          $log.warn('accordion-heading is now deprecated. Use uib-accordion-heading instead.');
-        }
-        // Pass the heading to the accordion-group controller
-        // so that it can be transcluded into the right place in the template
-        // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
-        accordionGroupCtrl.setHeading(transclude(scope, angular.noop));
-      }
-    };
-  }])
-
-  .directive('accordionTransclude', ['$log', '$accordionSuppressWarning', function($log, $accordionSuppressWarning) {
-    return {
-      require: '^accordionGroup',
-      link: function(scope, element, attr, controller) {
-        if (!$accordionSuppressWarning) {
-          $log.warn('accordion-transclude is now deprecated. Use uib-accordion-transclude instead.');
-        }
-
-        scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
-          if (heading) {
-            element.find('span').html('');
-            element.find('span').append(heading);
-          }
-        });
-      }
-    };
-  }]);
-
-
-angular.module('ui.bootstrap.collapse', [])
-
-  .directive('uibCollapse', ['$animate', '$injector', function($animate, $injector) {
-    var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null;
-    return {
-      link: function(scope, element, attrs) {
-        function expand() {
-          element.removeClass('collapse')
-            .addClass('collapsing')
-            .attr('aria-expanded', true)
-            .attr('aria-hidden', false);
-
-          if ($animateCss) {
-            $animateCss(element, {
-              addClass: 'in',
-              easing: 'ease',
-              to: { height: element[0].scrollHeight + 'px' }
-            }).start().finally(expandDone);
-          } else {
-            $animate.addClass(element, 'in', {
-              to: { height: element[0].scrollHeight + 'px' }
-            }).then(expandDone);
-          }
-        }
-
-        function expandDone() {
-          element.removeClass('collapsing')
-            .addClass('collapse')
-            .css({height: 'auto'});
-        }
-
-        function collapse() {
-          if (!element.hasClass('collapse') && !element.hasClass('in')) {
-            return collapseDone();
-          }
-
-          element
-            // IMPORTANT: The height must be set before adding "collapsing" class.
-            // Otherwise, the browser attempts to animate from height 0 (in
-            // collapsing class) to the given height here.
-            .css({height: element[0].scrollHeight + 'px'})
-            // initially all panel collapse have the collapse class, this removal
-            // prevents the animation from jumping to collapsed state
-            .removeClass('collapse')
-            .addClass('collapsing')
-            .attr('aria-expanded', false)
-            .attr('aria-hidden', true);
-
-          if ($animateCss) {
-            $animateCss(element, {
-              removeClass: 'in',
-              to: {height: '0'}
-            }).start().finally(collapseDone);
-          } else {
-            $animate.removeClass(element, 'in', {
-              to: {height: '0'}
-            }).then(collapseDone);
-          }
-        }
-
-        function collapseDone() {
-          element.css({height: '0'}); // Required so that collapse works when animation is disabled
-          element.removeClass('collapsing')
-            .addClass('collapse');
-        }
-
-        scope.$watch(attrs.uibCollapse, function(shouldCollapse) {
-          if (shouldCollapse) {
-            collapse();
-          } else {
-            expand();
-          }
-        });
-      }
-    };
-  }]);
-
-/* Deprecated collapse below */
-
-angular.module('ui.bootstrap.collapse')
-
-  .value('$collapseSuppressWarning', false)
-
-  .directive('collapse', ['$animate', '$injector', '$log', '$collapseSuppressWarning', function($animate, $injector, $log, $collapseSuppressWarning) {
-    var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null;
-    return {
-      link: function(scope, element, attrs) {
-        if (!$collapseSuppressWarning) {
-          $log.warn('collapse is now deprecated. Use uib-collapse instead.');
-        }
-
-        function expand() {
-          element.removeClass('collapse')
-            .addClass('collapsing')
-            .attr('aria-expanded', true)
-            .attr('aria-hidden', false);
-
-          if ($animateCss) {
-            $animateCss(element, {
-              easing: 'ease',
-              to: { height: element[0].scrollHeight + 'px' }
-            }).start().done(expandDone);
-          } else {
-            $animate.animate(element, {}, {
-              height: element[0].scrollHeight + 'px'
-            }).then(expandDone);
-          }
-        }
-
-        function expandDone() {
-          element.removeClass('collapsing')
-            .addClass('collapse in')
-            .css({height: 'auto'});
-        }
-
-        function collapse() {
-          if (!element.hasClass('collapse') && !element.hasClass('in')) {
-            return collapseDone();
-          }
-
-          element
-            // IMPORTANT: The height must be set before adding "collapsing" class.
-            // Otherwise, the browser attempts to animate from height 0 (in
-            // collapsing class) to the given height here.
-            .css({height: element[0].scrollHeight + 'px'})
-            // initially all panel collapse have the collapse class, this removal
-            // prevents the animation from jumping to collapsed state
-            .removeClass('collapse in')
-            .addClass('collapsing')
-            .attr('aria-expanded', false)
-            .attr('aria-hidden', true);
-
-          if ($animateCss) {
-            $animateCss(element, {
-              to: {height: '0'}
-            }).start().done(collapseDone);
-          } else {
-            $animate.animate(element, {}, {
-              height: '0'
-            }).then(collapseDone);
-          }
-        }
-
-        function collapseDone() {
-          element.css({height: '0'}); // Required so that collapse works when animation is disabled
-          element.removeClass('collapsing')
-            .addClass('collapse');
-        }
-
-        scope.$watch(attrs.collapse, function(shouldCollapse) {
-          if (shouldCollapse) {
-            collapse();
-          } else {
-            expand();
-          }
-        });
-      }
-    };
-  }]);
+angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("uibAccordionConfig",{closeOthers:!0}).controller("UibAccordionController",["$scope","$attrs","uibAccordionConfig",function(n,e,o){this.groups=[],this.closeOthers=function(i){var a=angular.isDefined(e.closeOthers)?n.$eval(e.closeOthers):o.closeOthers;a&&angular.forEach(this.groups,function(n){n!==i&&(n.isOpen=!1)})},this.addGroup=function(n){var e=this;this.groups.push(n),n.$on("$destroy",function(o){e.removeGroup(n)})},this.removeGroup=function(n){var e=this.groups.indexOf(n);-1!==e&&this.groups.splice(e,1)}}]).directive("uibAccordion",function(){return{controller:"UibAccordionController",controllerAs:"accordion",transclude:!0,templateUrl:function(n,e){return e.templateUrl||"template/accordion/accordion.html"}}}).directive("uibAccordionGroup",function(){return{require:"^uibAccordion",transclude:!0,replace:!0,templateUrl:function(n,e){return e.templateUrl||"template/accordion/accordion-group.html"},scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(n){this.heading=n}},link:function(n,e,o,i){i.addGroup(n),n.openClass=o.openClass||"panel-open",n.panelClass=o.panelClass,n.$watch("isOpen",function(o){e.toggleClass(n.openClass,!!o),o&&i.closeOthers(n)}),n.toggleOpen=function(e){n.isDisabled||e&&32!==e.which||(n.isOpen=!n.isOpen)}}}}).directive("uibAccordionHeading",function(){return{transclude:!0,template:"",replace:!0,require:"^uibAccordionGroup",link:function(n,e,o,i,a){i.setHeading(a(n,angular.noop))}}}).directive("uibAccordionTransclude",function(){return{require:["?^uibAccordionGroup","?^accordionGroup"],link:function(n,e,o,i){i=i[0]?i[0]:i[1],n.$watch(function(){return i[o.uibAccordionTransclude]},function(n){n&&(e.find("span").html(""),e.find("span").append(n))})}}}),angular.module("ui.bootstrap.accordion").value("$accordionSuppressWarning",!1).controller("AccordionController",["$scope","$attrs","$controller","$log","$accordionSuppressWarning",function(n,e,o,i,a){a||i.warn("AccordionController is now deprecated. Use UibAccordionController instead."),angular.extend(this,o("UibAccordionController",{$scope:n,$attrs:e}))}]).directive("accordion",["$log","$accordionSuppressWarning",function(n,e){return{restrict:"EA",controller:"AccordionController",controllerAs:"accordion",transclude:!0,replace:!1,templateUrl:function(n,e){return e.templateUrl||"template/accordion/accordion.html"},link:function(){e||n.warn("accordion is now deprecated. Use uib-accordion instead.")}}}]).directive("accordionGroup",["$log","$accordionSuppressWarning",function(n,e){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:function(n,e){return e.templateUrl||"template/accordion/accordion-group.html"},scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(n){this.heading=n}},link:function(o,i,a,r){e||n.warn("accordion-group is now deprecated. Use uib-accordion-group instead."),r.addGroup(o),o.openClass=a.openClass||"panel-open",o.panelClass=a.panelClass,o.$watch("isOpen",function(n){i.toggleClass(o.openClass,!!n),n&&r.closeOthers(o)}),o.toggleOpen=function(n){o.isDisabled||n&&32!==n.which||(o.isOpen=!o.isOpen)}}}}]).directive("accordionHeading",["$log","$accordionSuppressWarning",function(n,e){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",link:function(o,i,a,r,t){e||n.warn("accordion-heading is now deprecated. Use uib-accordion-heading instead."),r.setHeading(t(o,angular.noop))}}}]).directive("accordionTransclude",["$log","$accordionSuppressWarning",function(n,e){return{require:"^accordionGroup",link:function(o,i,a,r){e||n.warn("accordion-transclude is now deprecated. Use uib-accordion-transclude instead."),o.$watch(function(){return r[a.accordionTransclude]},function(n){n&&(i.find("span").html(""),i.find("span").append(n))})}}}]),angular.module("ui.bootstrap.collapse",[]).directive("uibCollapse",["$animate","$injector",function(n,e){var o=e.has("$animateCss")?e.get("$animateCss"):null;return{link:function(e,i,a){function r(){i.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),o?o(i,{addClass:"in",easing:"ease",to:{height:i[0].scrollHeight+"px"}}).start()["finally"](t):n.addClass(i,"in",{to:{height:i[0].scrollHeight+"px"}}).then(t)}function t(){i.removeClass("collapsing").addClass("collapse").css({height:"auto"})}function s(){return i.hasClass("collapse")||i.hasClass("in")?(i.css({height:i[0].scrollHeight+"px"}).removeClass("collapse").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),void(o?o(i,{removeClass:"in",to:{height:"0"}}).start()["finally"](c):n.removeClass(i,"in",{to:{height:"0"}}).then(c))):c()}function c(){i.css({height:"0"}),i.removeClass("collapsing").addClass("collapse")}e.$watch(a.uibCollapse,function(n){n?s():r()})}}}]),angular.module("ui.bootstrap.collapse").value("$collapseSuppressWarning",!1).directive("collapse",["$animate","$injector","$log","$collapseSuppressWarning",function(n,e,o,i){var a=e.has("$animateCss")?e.get("$animateCss"):null;return{link:function(e,r,t){function s(){r.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),a?a(r,{easing:"ease",to:{height:r[0].scrollHeight+"px"}}).start().done(c):n.animate(r,{},{height:r[0].scrollHeight+"px"}).then(c)}function c(){r.removeClass("collapsing").addClass("collapse in").css({height:"auto"})}function l(){return r.hasClass("collapse")||r.hasClass("in")?(r.css({height:r[0].scrollHeight+"px"}).removeClass("collapse in").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),void(a?a(r,{to:{height:"0"}}).start().done(d):n.animate(r,{},{height:"0"}).then(d))):d()}function d(){r.css({height:"0"}),r.removeClass("collapsing").addClass("collapse")}i||o.warn("collapse is now deprecated. Use uib-collapse instead."),e.$watch(t.collapse,function(n){n?l():s()})}}}]);
\ No newline at end of file
